Hi to all!

Is there in Windows APIs that can encode/decode MIME base64, UUE, XXE formats?

Thanks,
Mike
Posted on 2004-03-28 08:42:00 by Mike
Not that I know of, but base64 and UUE are old and well documented and easy to handle. And if XXE is what I think it is (something that was used for, for instance, binary files in SWAG), it's easy enough to handle, too. Google around, you should find plenty :)
Posted on 2004-03-28 08:56:29 by f0dder
You can try to see in the ATL library of VC++ .NET, file atlenc.h, support Base64, UUEncode...
Good luck
Posted on 2004-03-28 22:00:11 by TQN
Thank you, TQN!
I have no VC++, but I've found atl.dll (size=73K, date=2003.04.29). Below you can see all members of dll. Are you sure that there are some function that can encode base64 ?
Mike

*************
Atl contents:
AtlAdvise
AtlAxAttachControl
AtlAxCreateControl
AtlAxCreateControlEx
AtlAxCreateDialogA
AtlAxCreateDialogW
AtlAxDialogBoxA
AtlAxDialogBoxW
AtlAxGetControl
AtlAxGetHost
AtlAxWinInit
AtlComPtrAssign
AtlComQIPtrAssign
AtlCreateTargetDC
AtlDevModeW2A
AtlFreeMarshalStream
AtlGetObjectSourceInterface
AtlGetVersion
AtlHiMetricToPixel
AtlIPersistPropertyBag_Load
AtlIPersistPropertyBag_Save
AtlIPersistStreamInit_Load
AtlIPersistStreamInit_Save
AtlInternalQueryInterface
AtlMarshalPtrInProc
AtlModuleAddCreateWndData
AtlModuleAddTermFunc
AtlModuleExtractCreateWndData
AtlModuleGetClassObject
AtlModuleInit
AtlModuleLoadTypeLib
AtlModuleRegisterClassObjects
AtlModuleRegisterServer
AtlModuleRegisterTypeLib
AtlModuleRegisterWndClassInfoA
AtlModuleRegisterWndClassInfoW
AtlModuleRevokeClassObjects
AtlModuleTerm
AtlModuleUnRegisterTypeLib
AtlModuleUnregisterServer
AtlModuleUnregisterServerEx
AtlModuleUpdateRegistryFromResourceD
AtlPixelToHiMetric
AtlRegisterClassCategoriesHelper
AtlSetErrorInfo
AtlUnadvise
AtlUnmarshalPtr
AtlWaitWithMessageLoop
DllCanUnloadNow
DllGetClassObject
DllRegisterServer
DllUnregisterServer
Posted on 2004-03-29 00:33:20 by Mike
Here is the attached atlenc.h file. The ATL dll of VC++.NET 2002 is atl70.dll, VC++. NET 2003 is atl71.dll. You need install VS .NET 2003.
Good luck !
Posted on 2004-03-29 02:25:09 by TQN
Thank you, TQN!

That's real help! There are ready programs written in C! I dont't need any dll. It seems to me that I'll find a time and rewrite all those into assembler.

Mike
Posted on 2004-03-29 07:33:14 by Mike
Hi,

this has been done many times before in assembly. What about this
one for (Base64 coding) from somewhere here?



.data
alphabet db " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx
yz0123456789+/"

.code
base64encode PROC source:DWORD, destination:DWORD, sourcelen:DWORD
push edi
push esi
push ebx
mov esi, source
mov edi, destination
@@base64loop:
xor eax, eax
.IF sourcelen == 1
lodsb ;source ptr + 1
mov ecx, 2 ;bytes to output = 2
mov edx, 03D3Dh ;padding = 2 byte
dec sourcelen ;length - 1
.ELSEIF sourcelen == 2
lodsw ;source ptr + 2
mov ecx, 3 ;bytes to output = 3
mov edx, 03Dh ;padding = 1 byte
sub sourcelen, 2 ;length - 2
.ELSE
lodsd
mov ecx, 4 ;bytes to output = 4
xor edx, edx ;padding = 0 byte
dec esi ;source ptr + 3 (+4-1)
sub sourcelen, 3 ;length - 3
.ENDIF

xchg al,ah ; flip eax completely
rol eax, 16 ; can this be done faster
xchg al,ah ; ??

@@:
push eax
and eax, 0FC000000h ;get the last 6 high bits
rol eax, 6 ;rotate them into al
mov al, byte ptr [offset alphabet+eax] ;get encode character
stosb ;write to destination
pop eax
shl eax, 6 ;shift left 6 bits
dec ecx
jnz @B ;loop

cmp sourcelen, 0
jnz @@base64loop ;main loop

mov eax, edx ;add padding and null terminate
stosd ; " " " " "

pop ebx
pop esi
pop edi
ret
base64encode ENDP



code:
.data
; ASCII-43 -> BASE64 mapping table
base64table db 62,0,0,0,63,52,53,54,55,56,57,58,59,60,61,0
db 0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13
db 14,15,16,17,18,19,20,21,22,23,24,25,0,0,0,0
db 0,0,26,27,28,29,30,31,32,33,34,35,36,37,38
db 39,40,41,42,43,44,45,46,47,48,49,50,51

.code
base64decode PROC source:DWORD, destination:DWORD
push ebx
push esi
push edi
mov esi, source
mov edi, destination
invoke lstrlen, source
shr eax, 2
mov ecx, eax
push ecx
@@outer_loop:
xor ebx, ebx
mov ecx, 4
lodsd
@@inner_loop:
push eax
and eax, 0FFh
sub al, 43
or bl, [offset base64table+eax]
shl ebx, 6
pop eax
shr eax, 8
dec ecx
jnz @@inner_loop
mov eax, ebx
rol ax, 8
rol eax, 16
rol ax, 8
stosd
dec edi
pop ecx
dec ecx
jnz @@outer_loop
pop edi
pop esi
pop ebx
ret
base64encode ENDP



Same as the one above but with error detection...

code:
; ASCII -> BASE64 mapping table
base64table db 43 dup (255)
db 62,255,255,255,63,52,53,54,55,56,57,58,59,60,61,25
5
db 255,255,0,255,255,255,0,1,2,3,4,5,6,7,8,9,10,11,12
,13
db 14,15,16,17,18,19,20,21,22,23,24,25,255,255,255,25
5
db 255,255,26,27,28,29,30,31,32,33,34,35,36,37,38
db 39,40,41,42,43,44,45,46,47,48,49,50,51
db 132 dup (255)

base64decode PROC source:DWORD, destination:DWORD, sourcelen:DWORD
push esi
push edi
push ebx

mov esi, source ; esi <- source
mov edi, destination ; edi <- destination
mov ecx, sourcelen
shr ecx, 2
cld

;-------------[decoding part]---------------

@@outer_loop:
push ecx
mov ecx, 4
xor ebx, ebx
lodsd
@@inner_loop:
push eax
and eax, 0ffh
mov al, byte ptr [offset base64table+eax]
cmp al, 255
je @@invalid_char
shl ebx, 6
or bl, al
pop eax
shr eax, 8
dec ecx
jnz @@inner_loop
mov eax, ebx
shl eax, 8
xchg ah, al
ror eax, 16
xchg ah, al
stosd
dec edi
pop ecx
dec ecx
jnz @@outer_loop
xor eax, eax
jmp @@decode_done

;-------------------------------------------

@@invalid_char:
mov eax, -1
@@decode_done:
pop ebx
pop edi
pop esi
ret
base64decode ENDP




As far as I remember zynaps was the author.

Bye Miracle
Posted on 2004-03-30 22:59:07 by miracle
Neat, Miracle - seems like there's room for improvement in the algo, might make some difference in decoding large mail attachments. Btw, other posts on this board (including the one where this base64 came from, I think):
http://www.asmcommunity.net/board/index.php?topic=4169&highlight=base64
http://www.asmcommunity.net/board/index.php?topic=10311&highlight=base64
Posted on 2004-03-30 23:41:17 by f0dder
Thanks, Miracle!

Encoder and 2nd decoder works properly, that's enough!
All have been tested, see attach.

Thanks,
Mike
Posted on 2004-03-31 05:34:16 by Mike
Hi!

I 've found one problem now. There are no problems when I decode text. In this case I can detect length of the decoded text with lstrlen function. Otherwise if inside is some binary (e.g. contents of the exe file) I don't know how much bytes I must write into the file.

Regards,
Mike
Posted on 2004-04-08 06:12:03 by Mike
Posted on 2004-04-08 11:09:00 by bitRAKE
Hi!

All has already looked. But are you sure that human words will work inplace assembler instructions? I've found there only

CMP AX,0A0Dh

Do you see any relation with the output length? I don't. Now I see only one method to count it:
InputLength*3/4
but I am not sure that it's good idea.

Mike
Posted on 2004-04-09 06:42:43 by Mike