Initial
This commit is contained in:
418
uudecode/DECODE64.HLD
Normal file
418
uudecode/DECODE64.HLD
Normal file
@@ -0,0 +1,418 @@
|
||||
;*************************************************************************************
|
||||
; MODULE: BASE64.ASM DATE: JANUARY 27,1997
|
||||
; AUTHOR: SEAN M. KESSLER
|
||||
; TARGET: 32 BIT FLAT MODEL
|
||||
; FUNCTION : BASE64 DECODER
|
||||
;*************************************************************************************
|
||||
.386
|
||||
.MODEL FLAT
|
||||
INCLUDE devioctl.inc
|
||||
|
||||
HANDLE STRUC
|
||||
PHANDLE TYPEDEF FAR PTR HANDLE
|
||||
HANDLE@@mHandle DD <0>
|
||||
HANDLE ENDS
|
||||
|
||||
INVALID_HANDLE equ 0FFFFFFFFh
|
||||
|
||||
STRSTR MACRO szStringOne,szStringTwo
|
||||
push offset szStringTwo ; save string one
|
||||
push offset szStringOne ; save string two
|
||||
call _strstr ; call standard library strstr
|
||||
add esp,08h ; reset stack frame
|
||||
ENDM
|
||||
|
||||
STRCHR MACRO szString,charByte
|
||||
push charByte ; save charByte
|
||||
push offset szString ; save string
|
||||
call _strchr ; call standard library strchr
|
||||
add esp,08h ; reset stack frame
|
||||
ENDM
|
||||
|
||||
STRLEN MACRO szData
|
||||
push edi ; save destination index register
|
||||
push ecx ; save ecx register
|
||||
mov edi,offset szData ; get string to destination index register
|
||||
mov ecx,0FFFFh ; move 65535 to ecx register
|
||||
xor eax,eax ; clear eax register
|
||||
repnz scasb ; scan string
|
||||
mov eax,0FFFFh ; move 65535 to eax
|
||||
sub eax,ecx ; subtract number of bytes scanned
|
||||
dec eax ; decrement result
|
||||
pop ecx ; restore ecx register
|
||||
pop edi ; restore destination index register
|
||||
ENDM
|
||||
|
||||
MEMCPY MACRO szDstData,szSrcData,lengthCopy
|
||||
push esi ; save source index register
|
||||
push edi ; save destination index register
|
||||
mov esi,offset szSrcData ; move source data to source index register
|
||||
mov edi,offset szDstData ; move destination data to destination index register
|
||||
mov ecx,lengthCopy ; move number of bytes to copy to ecx register
|
||||
rep movsb ; copy data
|
||||
pop edi ; restore destination index register
|
||||
pop esi ; restore source index register
|
||||
ENDM
|
||||
|
||||
STRCMP MACRO szStringOne,szStringTwo
|
||||
LOCAL @@STRCMPnotEqual,@@STRCMPequal,@@STRCMPexit
|
||||
push ecx ; save ecx register
|
||||
push edi ; save destination index register
|
||||
push esi ; save source index register
|
||||
mov edi,offset szStringOne ; move string one to destination index register
|
||||
mov esi,offset szStringTwo ; move string two to source index register
|
||||
STRLEN szStringOne ; get length of string one
|
||||
mov ecx,eax ; save length to ecx register
|
||||
STRLEN szStringTwo ; get length of string two
|
||||
cmp ecx,eax ; compare lengths
|
||||
jne @@STRCMPnotEqual ; if lengths differ, strings are not equal
|
||||
@@STRCMPloop: ; loop control
|
||||
mov al,byte ptr[esi] ; get byte from string two
|
||||
cmp al,byte ptr[edi] ; compare with byte from string one
|
||||
jne @@STRCMPnotEqual ; if bytes differ then we're done
|
||||
loop @@STRCMPloop ; iterate through string length
|
||||
@@STRCMPequal: ; equality control
|
||||
mov eax,0001h ; set return code
|
||||
jmp @@STRCMPexit ; we're done
|
||||
@@STRCMPnotEqual: ; inequality control
|
||||
xor eax,eax ; set return code
|
||||
@@STRCMPexit: ; exit sync address
|
||||
pop esi ; restore source index register
|
||||
pop edi ; restore destination index register
|
||||
pop ecx ; restore ecx register
|
||||
ENDM
|
||||
|
||||
STRNCMP MACRO szStringOne,szStringTwo
|
||||
LOCAL @@STRNCMPloop,@@STRNCMPequal,@@STRNCMPnotEqual,@@STRNCMPexit
|
||||
push ecx ; save ecx register
|
||||
push edi ; save edi register
|
||||
push esi ; save source index register
|
||||
mov edi,offset szStringOne ; move string one to destination index register
|
||||
mov esi,offset szStringTwo ; move string two to source index register
|
||||
STRLEN szStringOne ; get length of string one
|
||||
mov ecx,eax ; save length to ecx register
|
||||
STRLEN szStringTwo ; get length of string two
|
||||
cmp ecx,eax ; compare the lengths
|
||||
jle @@STRNCMPloop ; string one is less equal to string two
|
||||
mov ecx,eax ; string two is less, so use it's length
|
||||
@@STRNCMPloop: ; loop control
|
||||
mov al,byte ptr[esi] ; get byte from string one
|
||||
cmp al,byte ptr[edi] ; compare with byte from string two
|
||||
jne @@STRNCMPnotEqual ; if byte are unequal, strings are unequal
|
||||
inc edi ; increment along string two
|
||||
inc esi ; increment along string one
|
||||
loop @@STRNCMPloop ; keep going
|
||||
@@STRNCMPequal: ; string equal sync address
|
||||
mov eax,0001h ; set return code
|
||||
jmp @@STRNCMPexit ; we're done
|
||||
@@STRNCMPnotEqual: ; string unequal sync address
|
||||
xor eax,eax ; set return code
|
||||
@@STRNCMPexit: ; exit sync address
|
||||
pop esi ; restore source index register
|
||||
pop edi ; restore destination index register
|
||||
pop ecx ; restore ecx register
|
||||
ENDM
|
||||
|
||||
CREATEFILE MACRO pathFileName,access,share,open,attribute
|
||||
push 0000h ; save handle to template (null)
|
||||
push attribute ; save attributes
|
||||
push open ; save creation flags
|
||||
push 0000h ; save security attributes
|
||||
push share ; save share mode
|
||||
push access ; save acess mode
|
||||
push pathFileName ; save path file name
|
||||
call dword ptr __imp__CreateFileA@28 ; call create
|
||||
ENDM
|
||||
|
||||
READFILE MACRO hFileHandle,szBuffer,sizeBuffer
|
||||
sub esp,04h ; create bytesRead on stack
|
||||
mov eax,esp ; move bytesRead address to eax
|
||||
push 0000h ; save overlapped structure address
|
||||
push eax ; save pointer to bytesRead
|
||||
push sizeBuffer ; save length of buffer
|
||||
push offset szBuffer ; save address of read buffer
|
||||
push hFileHandle ; save file handle
|
||||
call dword ptr __imp__ReadFile@20 ; call read
|
||||
mov eax,[esp] ; move bytesRead value to eax
|
||||
add esp,04h ; remove bytesRead variable from stack
|
||||
ENDM
|
||||
|
||||
WRITEFILE MACRO hFileHandle,szBuffer,sizeBuffer
|
||||
sub esp,04h ; create bytesWritten variable on stack
|
||||
mov eax,esp ; move bytesWritten address to eax
|
||||
push 0000h ; save overlapped structure address
|
||||
push eax ; save bytesWritten address
|
||||
push sizeBuffer ; save write length
|
||||
push offset szBuffer ; save address of write buffer
|
||||
push hFileHandle ; save file handle
|
||||
call dword ptr __imp__WriteFile@20 ; call write
|
||||
mov eax,[esp] ; move number of bytes written to eax
|
||||
add esp,04h ; remove bytesWritten variable from stack
|
||||
ENDM
|
||||
|
||||
CLOSEHANDLE MACRO handle
|
||||
push handle ; save file handle
|
||||
call dword ptr __imp__CloseHandle@4 ; call close
|
||||
ENDM
|
||||
|
||||
FREAD MACRO sFileInfo,ptrByte
|
||||
LOCAL @@FREADreadError,@@FREADsimpleRead,@@FREADdone
|
||||
cmp sFileInfo.FileInfo@@mBufferIndex,00h ; is buffer index zero
|
||||
jne @@FREADsimpleRead ; if not then just grab next byte
|
||||
READFILE sFileInfo.FileInfo@@mhFileHandle,sFileInfo.FileInfo@@mszBuffer,MaxLength ; otherwise we fill the read buffer
|
||||
cmp eax,0000h ; did we read any data ?
|
||||
je @@FREADreadError ; if not then we're done
|
||||
mov sFileInfo.FileInfo@@mBufferIndex,eax ; move number of bytes read to buffer index
|
||||
mov eax,offset sFileInfo.FileInfo@@mszBuffer ; move address of buffer to eax
|
||||
mov sFileInfo.FileInfo@@mlpBufferPointer,eax ; move address of buffer to lpBufferPointer
|
||||
jmp @@FREADsimpleRead ; grab next byte
|
||||
@@FREADreadError: ; read error sync address
|
||||
xor eax,eax ; set return code
|
||||
jmp @@FREADdone ; we're done
|
||||
@@FREADsimpleRead: ; simple read sync address
|
||||
mov eax,sFileInfo.FileInfo@@mlpBufferPointer ; move address of buffer to eax
|
||||
mov al,byte ptr[eax] ; move byte value to al
|
||||
mov byte ptr[ptrByte],al ; move byte value to user buffer
|
||||
inc sFileInfo.FileInfo@@mlpBufferPointer ; increment along lpBufferPointer
|
||||
dec sFileInfo.FileInfo@@mBufferIndex ; decrement the buffer index
|
||||
mov eax,01h ; set the return code
|
||||
@@FREADdone: ; done reading sync
|
||||
ENDM
|
||||
|
||||
FWRITE MACRO sFileInfo,ptrByte
|
||||
LOCAL @@FWRITEsimpleWrite,@@FWRITEuseBuffer
|
||||
cmp sFileInfo.FileInfo@@mBufferIndex,MaxLength ; compare buffer index to MaxLength
|
||||
jl @@FWRITEsimpleWrite ; if it's less then insert char into buffer
|
||||
WRITEFILE sFileInfo.FileInfo@@mhFileHandle,sFileInfo.FileInfo@@mszBuffer,MaxLength ; other wise
|
||||
mov sFileInfo.FileInfo@@mBufferIndex,0000h ; set buffer index to zero
|
||||
mov eax,offset sFileInfo.FileInfo@@mszBuffer ; move address of buffer to eax
|
||||
mov sFileInfo.FileInfo@@mlpBufferPointer,eax ; move address of buffer to lpBufferPointer
|
||||
@@FWRITEsimpleWrite: ; simple write sync address
|
||||
cmp sFileInfo.FileInfo@@mlpBufferPointer,0000h ; is buffer pointer null?
|
||||
jne @@FWRITEuseBuffer ; if not then just use it
|
||||
mov eax,offset sFileInfo.FileInfo@@mszBuffer ; move address of buffer to eax
|
||||
mov sFileInfo.FileInfo@@mlpBufferPointer,eax ; move address of buffer to lpBufferPointer
|
||||
@@FWRITEuseBuffer: ; use buffer sync address
|
||||
mov cl,byte ptr[ptrByte] ; move byte to write to cl
|
||||
mov eax,sFileInfo.FileInfo@@mlpBufferPointer ; move address of buffer to eax
|
||||
mov byte ptr[eax],cl ; move byte into buffer
|
||||
inc sFileInfo.FileInfo@@mlpBufferPointer ; increment buffer pointer
|
||||
inc sFileInfo.FileInfo@@mBufferIndex ; increment buffer index
|
||||
mov eax,01h ; set return code
|
||||
ENDM
|
||||
|
||||
FFLUSH MACRO sFileInfo
|
||||
WRITEFILE sFileInfo.FileInfo@@mhFileHandle,sFileInfo.FileInfo@@mszBuffer,sFileInfo.FileInfo@@mBufferIndex ; write buffer to disk
|
||||
mov sFileInfo.FileInfo@@mBufferIndex,0000h ; set buffer index to zero
|
||||
mov eax,offset sFileInfo.FileInfo@@mszBuffer ; move address of buffer to eax
|
||||
mov sFileInfo.FileInfo@@mlpBufferPointer,eax ; move address of buffer to lpBufferPointer
|
||||
ENDM
|
||||
|
||||
FGETS MACRO sFileInfo,szBuffer
|
||||
LOCAL @@FGETScont,@@FGETexit,@@FGETsetError,@@FGETScrlf
|
||||
push esi ; save source index register
|
||||
mov esi,offset szBuffer ; move address of buffer into esi
|
||||
@@FGETScont: ; loop control
|
||||
FREAD sFileInfo,esi ; read a byte
|
||||
cmp eax,0000h ; was our read successful?
|
||||
je @@FGETexit ; if not we're done
|
||||
cmp byte ptr[esi],0Dh ; is the byte a carriage return?
|
||||
je @@FGETScrlf ; if yes then jump to handler
|
||||
inc esi ; increment along esi
|
||||
jmp @@FGETScont ; keep reading
|
||||
@@FGETScrlf: ; carriage return control
|
||||
mov byte ptr[esi],00h ; move null into line data
|
||||
sub esp,04h ; create temp var on stack
|
||||
mov esi,esp ; esi points to temp var
|
||||
FREAD sFileInfo,esi ; read line-feed into temp var
|
||||
add esp,04h ; restore stack
|
||||
@@FGETexit: ; exit sync address
|
||||
pop esi ; restore source index register
|
||||
ENDM
|
||||
|
||||
FileInfo STRUC
|
||||
MaxLength equ 800h
|
||||
FileInfo@@mhFileHandle HANDLE <0>
|
||||
FileInfo@@mszBuffer DB MaxLength DUP(0)
|
||||
FileInfo@@mBufferIndex DD (0)
|
||||
FileInfo@@mlpBufferPointer DD (0)
|
||||
FileInfo ENDS
|
||||
|
||||
.DATA
|
||||
inputFile FileInfo <<0>>
|
||||
outputFile FileInfo <<0>>
|
||||
lineData DB 400h DUP(0)
|
||||
szDefaultOutputPathFileName DB 'IMAGE.JPG',00h
|
||||
szOutputPathFileName DB 0FFh DUP(0)
|
||||
szFileNameLiteral DB 'filename=',00h
|
||||
szOutBytes DB 04h DUP(0)
|
||||
szInputPathFileName DD ?
|
||||
szBase64ID DB '/9j/',00h
|
||||
szBase64Vector DB 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',00h
|
||||
num DD ?
|
||||
lineLength DD ?
|
||||
itemIndex DD ?
|
||||
numIndex DD ?
|
||||
valueItem DD ?
|
||||
.CODE
|
||||
_decodeBase64 proc near ; WORD decodeBase64(const char *szPathFileName)
|
||||
push ebp ; save stack frame
|
||||
mov ebp,esp ; create new frame
|
||||
push esi ; save source index register
|
||||
push edi ; save destination index register
|
||||
push [ebp+8] ; save pathFileName
|
||||
pop szInputPathFileName ; restore into inputPathFileName
|
||||
cmp szInputPathFileName,0000h ; is the file na null
|
||||
je @@error ; if so then we've got an error
|
||||
CREATEFILE szInputPathFileName,GENERIC_READ,FILE_SHARE_READ,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL
|
||||
mov inputFile.FileInfo@@mhFileHandle,eax ; store the handle
|
||||
cmp inputFile.FileInfo@@mhFileHandle,INVALID_HANDLE ; do we have a valid handle ?
|
||||
je @@error ; if the handle is invalid then we've got an error
|
||||
STRLEN szDefaultOutputPathFileName ; get the length of the default file name
|
||||
MEMCPY szOutputPathFileName,szDefaultOutputPathFileName,eax ; set output file name to default
|
||||
@@search: ; search sync address
|
||||
FGETS inputFile,lineData ; get input line
|
||||
cmp eax,0000h ; did we read anything
|
||||
je @@end ; if not we're done
|
||||
STRSTR lineData,szFileNameLiteral ; look for "filename=" literal
|
||||
cmp eax,0000h ; did we find it
|
||||
jne @@nameFile ; if so then extract the filename
|
||||
STRNCMP szBase64ID,lineData ; compare line to base64 identifier
|
||||
cmp eax,0001h ; if we've got it then we start decoding
|
||||
je @@beginDecode ; jump to decode handler
|
||||
jmp @@search ; keep going
|
||||
@@nameFile: ; nameFile sync address
|
||||
push eax ; save address of filename literal
|
||||
push offset szOutputPathFileName ; save address of filename buffer
|
||||
call _nameFile ; extract the file name
|
||||
add esp,08h ; reset stack frame
|
||||
jmp @@search ; keep going
|
||||
@@beginDecode: ; begin decode sync address
|
||||
CREATEFILE offset szOutputPathFileName,GENERIC_WRITE,FILE_SHARE_READ,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL
|
||||
mov outputFile.FileInfo@@mhFileHandle,eax ; save handle
|
||||
@@continueDecode: ; continue decode sync address
|
||||
STRLEN lineData ; get length of lineData
|
||||
dec eax ; decrement line length
|
||||
mov lineLength,eax ; move line length into lineLength
|
||||
mov itemIndex,0000h ; set itemIndex to zero
|
||||
@@itemLoop: ; itemLoop sync address
|
||||
mov valueItem,0000h ; set valueItem to zero
|
||||
mov esi,offset lineData ; move ptr lineData to esi register
|
||||
add esi,itemIndex ; add itemIndex to address
|
||||
cmp byte ptr[esi+02h],'=' ; is pChar[2] equal to '='?
|
||||
je @@assignOne ; if so then num=1
|
||||
cmp byte ptr[esi+03h],'=' ; else if pChar[3]='='
|
||||
je @@assignTwo ; then num=2
|
||||
mov num,0003h ; otherwise num=3
|
||||
jmp @@assignContinue ; continue
|
||||
@@assignOne: ; assignment sync address
|
||||
mov num,0001h ; assign 1 to num
|
||||
jmp @@assignContinue ; continue
|
||||
@@assignTwo: ; assignment sync address
|
||||
mov num,0002h ; assign two to num
|
||||
jmp @@assignContinue ; continue
|
||||
@@assignContinue: ; end assignment sync address
|
||||
mov numIndex,0000h ; set numIndex to zero
|
||||
@@numLoop: ; numIndex loop sync address
|
||||
xor eax,eax ; clear out eax
|
||||
mov edi,numIndex ; move numIndex into destination index
|
||||
mov al,byte ptr[esi+edi] ; get the byte at pChar[numIndex]
|
||||
STRCHR szBase64Vector,eax ; ::strchar(szBase64Vector,pChar[numIndex])
|
||||
cmp eax,0000h ; did we find the token
|
||||
je @@end ; if not then we've got an error
|
||||
mov edi,eax ; move address of found token to edi (pTok)
|
||||
sub edi,offset szBase64Vector ; perform (pTok-szBase64Vector) result to edi
|
||||
mov eax,0003h ; move 3 into eax
|
||||
sub eax,numIndex ; perform (3-numIndex) result to eax
|
||||
mov edx,0006h ; move 6 into edx
|
||||
imul eax,edx ; perform (3-numIndex)*6 result to eax
|
||||
mov cl,al ; move shift value into cl register
|
||||
shl edi,cl ; perform (pTok-smszVec)<<((3-numIndex)*6) result to edi
|
||||
add valueItem,edi ; valueItem+=(pTok-smszVec)<<((3-numIndex)*6)
|
||||
inc numIndex ; increment numIndex
|
||||
mov eax,numIndex ; move numIndex into eax register
|
||||
cmp eax,num ; compare numIndex to num
|
||||
jle @@numLoop ; loop through <= operation
|
||||
mov numIndex,0002h ; set numIndex to 2
|
||||
@@nextNumLoop: ; next numLoop sync address
|
||||
mov esi,offset szOutBytes ; move szOutBytes address into esi
|
||||
mov edi,numIndex ; move numIndex into edi
|
||||
mov eax,valueItem ; move valueItem into eax register
|
||||
and eax,000000FFh ; apply bit mask
|
||||
mov byte ptr[esi+edi],al ; set byte in szOutBytes
|
||||
shr valueItem,08h ; shift valueItem right 8 bytes
|
||||
dec numIndex ; decrement numIndex
|
||||
cmp numIndex,0000h ; compare numIndex to zero
|
||||
jge @@nextNumLoop ; if >=0 keep going
|
||||
mov esi,offset szOutBytes ; move szOutBytes to esi
|
||||
xor edi,edi ; clear edi
|
||||
@@writeLoop: ; writeLoop sync address
|
||||
FWRITE outputFile,byte ptr[esi+edi] ; write out the byte
|
||||
inc edi ; increment edi
|
||||
cmp edi,num ; compare edi to num
|
||||
jl @@writeLoop ; if it's less then keep going
|
||||
add itemIndex,0004h ; increment itemIndex by four
|
||||
mov eax,itemIndex ; move itemIndex to eax
|
||||
cmp eax,lineLength ; compare itemIndex to lineLength
|
||||
jl @@itemLoop ; if it's less that keep going
|
||||
FGETS inputFile,lineData ; get another line
|
||||
cmp eax,0000h ; did we get a line?
|
||||
je @@end ; if not then we're done
|
||||
jmp @@continueDecode ; otherwise keep going
|
||||
@@end: ; end sync address
|
||||
FFLUSH outputFile ; flush the output file
|
||||
CLOSEHANDLE outputFile.FileInfo@@mhFileHandle ; close output file
|
||||
CLOSEHANDLE inputFile.FileInfo@@mhFileHandle ; close input file
|
||||
@@error: ; error sync address
|
||||
pop edi ; restore destination index register
|
||||
pop esi ; restore source index register
|
||||
pop ebp ; restore prior stack frame
|
||||
retn ; return near to caller
|
||||
_decodeBase64 endp
|
||||
_nameFile proc near
|
||||
push ebp ; save stack frame
|
||||
mov ebp,esp ; create new frame
|
||||
push esi ; save source index register
|
||||
push edi ; save destination index register
|
||||
mov edi,[ebp+8] ; move dest string to destination index register
|
||||
mov esi,[ebp+0Ch] ; move source string to source index register
|
||||
@@NAMEFILEquoteLoop: ; first quote loop control
|
||||
mov al,byte ptr[esi] ; move byte into al
|
||||
cmp al,00h ; is it null?
|
||||
je @@NAMEFILEerror ; if it's null then we've got an error
|
||||
cmp al,'"' ; is it the first quote ?
|
||||
je @@NAMEFILEreadFile ; if so then get the filename
|
||||
inc esi ; increment along esi
|
||||
jmp @@NAMEFILEquoteLoop ; keep going
|
||||
@@NAMEFILEreadFile: ; read file name sync address
|
||||
inc esi ; skip past the first quote
|
||||
mov al,byte ptr[esi] ; read from file name
|
||||
cmp al,'"' ; is the byte the closing quote?
|
||||
je @@NAMEFILEreadEnd ; if so then we're done
|
||||
cmp al,00h ; is the byte a null byte?
|
||||
je @@NAMEFILEreadEnd ; if so then we're done
|
||||
mov byte ptr[edi],al ; store the byte in destination
|
||||
inc edi ; increment along destination
|
||||
jmp @@NAMEFILEreadFile ; keep going
|
||||
@@NAMEFILEreadEnd: ; read end sync address
|
||||
mov byte ptr[edi],00h ; null terminate the string
|
||||
mov eax,0001h ; set return code
|
||||
jmp @@NAMEFILEend ; we're done
|
||||
@@NAMEFILEerror: ; error sync address
|
||||
xor eax,eax ; set error return
|
||||
@@NAMEFILEend: ; end proc sync address
|
||||
pop edi ; restore destination index register
|
||||
pop esi ; restore source index register
|
||||
pop ebp ; restore prior stack frame
|
||||
retn ; return near to caller
|
||||
_nameFile endp
|
||||
public _decodeBase64
|
||||
extrn __imp__WriteFile@20:near
|
||||
extrn __imp__CloseHandle@4:near
|
||||
extrn __imp__CreateFileA@28:near
|
||||
extrn __imp__GetLastError@0:near
|
||||
extrn __imp__ReadFile@20:near
|
||||
extrn __imp__WriteFile@20:near
|
||||
extrn _strstr:near
|
||||
extrn _strchr:near
|
||||
END
|
||||
Reference in New Issue
Block a user