192 lines
9.2 KiB
NASM
192 lines
9.2 KiB
NASM
;*************************************************************************************
|
|
; MODULE: DECODE64.ASM DATE: JANUARY 27,1997
|
|
; AUTHOR: SEAN M. KESSLER
|
|
; TARGET: 32 BIT LAT MODEL
|
|
; FUNCTION : BASE64 DECODER
|
|
;*************************************************************************************
|
|
.386
|
|
.MODEL FLAT
|
|
INCLUDE devioctl.inc
|
|
INCLUDE string.inc
|
|
INCLUDE openfile.inc
|
|
LOCALS
|
|
|
|
DECODEBYTE MACRO index,offset
|
|
mov al,byte ptr [index+offset] ; get byte at index register + offset
|
|
sub al,' ' ; subtract space
|
|
and al,3Fh ; and with 3Fh
|
|
ENDM
|
|
|
|
.DATA
|
|
inputFile FileInfo <>
|
|
outputFile FileInfo <>
|
|
szBeginLine DB 'begin ',0000h
|
|
szEndLine DB 'end',0000h
|
|
szLineData DB 400h DUP(0)
|
|
numItem DB (0)
|
|
charByte DB (0)
|
|
status DD (0)
|
|
szOutputPathFileName DB 0FFh DUP(0)
|
|
szInputPathFileName DD ?
|
|
.CODE
|
|
_uudecode proc near ; void uudecode(char *szInputPathFileName)
|
|
push ebp ; save stack frame
|
|
mov ebp,esp ; create new frame
|
|
push esi ; save source index register
|
|
push edi ; save destination index register
|
|
push dword ptr[ebp+08h] ; save inputPathFileName
|
|
pop szInputPathFileName ; restore into szInputPathFileName
|
|
cmp szInputPathFileName,0000h ; is the file name null
|
|
je @@errorExit ; if so then we're done
|
|
FOPEN szInputPathFileName,inputFile,GENERIC_READ,FILE_SHARE_READ,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL
|
|
cmp eax,INVALID_HANDLE
|
|
je @@errorExit
|
|
@@munchLoop:
|
|
FGETS inputFile,szLineData ; read a line
|
|
cmp eax,0000h ; did the read succeed ?
|
|
je @@endRead ; if not then we're done
|
|
STRNCMP szBeginLine,szLineData ; compare line to signature
|
|
cmp eax,0001h ; did we find the signature
|
|
jne @@munchLoop ; if not then keep reading
|
|
call _getOutputFileName ; get output file name
|
|
mov esi,offset szOutputPathFileName
|
|
FOPEN esi,outputFile,GENERIC_WRITE,FILE_SHARE_READ,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL
|
|
cmp eax,INVALID_HANDLE ; was there a problem creating the output file
|
|
je @@endRead ; if so then we're done
|
|
@@readLoop: ; read loop sync address
|
|
mov esi,offset szLineData ; assign input line address to esi
|
|
FGETS inputFile,szLineData ; read an input line
|
|
cmp eax,0000h ; check for read error
|
|
je @@endDecode ; if there was an error, then we're done
|
|
xor eax,eax ; clear eax register
|
|
DECODEBYTE esi,00h ; decode the byte
|
|
mov numItem,al ; move the decoded item into numItem
|
|
cmp numItem,0000h ; compare numItem to zero
|
|
jle @@endDecode ; if it's less than or equal, we're done
|
|
inc esi ; increment line pointer
|
|
@@decodeLoop: ; decode loop sync address
|
|
cmp numItem,0000h ; compare numItem to zero
|
|
jle @@readLoop ; if it's less than or equal, get another line
|
|
cmp numItem,0003h ; compare numItem to 3
|
|
jge @@handleItemFGE3 ; handle (numItem>=3)
|
|
cmp numItem,0001h ; compare numItem to 1
|
|
jge @@handleItemGE1 ; handle (numItem>=1)
|
|
@@GE1Ret: ; return sync address
|
|
cmp numItem,0002h ; compare numItem to 2
|
|
jge @@handleItemGE2 ; handle (numItem>=2)
|
|
@@GE2Ret: ; return sync address
|
|
cmp numItem,0003h ; compare numItem to 3
|
|
jge @@handleItemGE3 ; handle (numItem>=3)
|
|
@@GE3Ret: ; return sync address
|
|
add esi,0004h ; increment line pointer
|
|
sub numItem,0003h ; subtract 3 from numItem
|
|
jmp @@decodeLoop ; keep going
|
|
@@handleItemFGE3: ; return sunc address
|
|
DECODEBYTE esi,00h ; decode the byte
|
|
mov cl,02h ; move shift value into cl register
|
|
shl ax,cl ; perform left shift
|
|
mov charByte,al ; save value into charByte
|
|
DECODEBYTE esi,01h ; decode the byte
|
|
mov cl,04h ; move shift value into cl register
|
|
shr al,cl ; perform right shift
|
|
or charByte,al ; or result with saved value
|
|
FWRITE outputFile,charByte ; write out the char
|
|
DECODEBYTE esi,01h ; decode byte
|
|
mov cl,04h ; move shift value into cl register
|
|
shl ax,cl ; perform left shift
|
|
mov charByte,al ; save value into charByte
|
|
DECODEBYTE esi,02h ; decode byte
|
|
mov cl,02h ; move shift value into cl register
|
|
shr al,cl ; perform right shift
|
|
or charByte,al ; or result with saved value
|
|
FWRITE outputFile,charByte ; write out the char
|
|
DECODEBYTE esi,02h ; decode byte
|
|
mov cl,06h ; move shift value into cl register
|
|
shl ax,cl ; perform left shift
|
|
mov charByte,al ; save value into charByte
|
|
DECODEBYTE esi,03h ; decode byte
|
|
or charByte,al ; or result with saved value
|
|
FWRITE outputFile,charByte ; write out the char
|
|
jmp @@GE3Ret ; jump back
|
|
@@handleItemGE1: ; (numItem>=1) sync address
|
|
DECODEBYTE esi,00h ; decode byte
|
|
mov cl,02h ; move shift value into cl register
|
|
shl ax,cl ; perform left shift
|
|
mov charByte,al ; save result into charByte
|
|
DECODEBYTE esi,01h ; decode byte
|
|
mov cl,04h ; mov shift value into cl register
|
|
shr ax,cl ; perform right shift
|
|
or charByte,al ; or the result into charByte
|
|
FWRITE outputFile,charByte ; write out the byte
|
|
jmp @@GE1Ret ; return
|
|
@@handleItemGE2: ; (numItem>=2) sync address
|
|
DECODEBYTE esi,01h ; decode byte
|
|
mov cl,04h ; move shift value into cl register
|
|
shl ax,cl ; perform left shift
|
|
mov charByte,al ; save result into charByte
|
|
DECODEBYTE esi,02h ; decode byte
|
|
mov cl,02h ; move shift value into cl register
|
|
shr ax,cl ; perform right shift
|
|
or charByte,al ; or result into charByte
|
|
FWRITE outputFile,charByte ; write out the byte
|
|
jmp @@GE2Ret ; return
|
|
@@handleItemGE3: ; (numItem>=3) sync address
|
|
DECODEBYTE esi,02h ; decode byte
|
|
mov cl,06h ; move shift value into cl register
|
|
shl ax,cl ; perform left shift
|
|
mov charByte,al ; save result into charByte
|
|
DECODEBYTE esi,03h ; decode byte
|
|
or charByte,al ; or result with charByte
|
|
FWRITE outputFile,charByte ; write out the byte
|
|
jmp @@GE3Ret ; return
|
|
@@endDecode: ; end decode sync address
|
|
FGETS inputFile,szLineData ; get final line from input file s/b 'end'
|
|
STRNCMP szLineData,szEndLine ; compare last line to endLine
|
|
cmp eax,0000h ; check return
|
|
je @@setError ; if it's not equal to 'end' we've got an error
|
|
mov status,0001h ; set success
|
|
jmp @@endRead ; skip over next instruction(s)
|
|
@@setError: ; setError sync address
|
|
mov status,0000h ; set failure
|
|
@@endRead: ; end read sync address
|
|
FCLOSE inputFile ; close input file
|
|
FFLUSH outputFile ; flush output file
|
|
FCLOSE outputFile ; close output file
|
|
@@errorExit: ; error exit sync address
|
|
mov eax,status ; set return code
|
|
pop edi ; restore destination index register
|
|
pop esi ; restore source index register
|
|
pop ebp ; restore previous stack frame
|
|
retn ; return near to caller
|
|
_uudecode endp
|
|
_getOutputFileName 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 esi,offset szLineData ; move input line address into source index
|
|
mov edi,offset szOutputPathFileName ; move output file name buffer into destination index
|
|
xor ecx,ecx ; clear ecx register for counting
|
|
@@munchLoop: ; munch loop sync address
|
|
mov al,byte ptr[esi] ; get byte from input line
|
|
inc esi ; increment esi along input line
|
|
cmp al,' ' ; did we read a space
|
|
jne @@munchLoop ; if not then keep reading
|
|
inc ecx ; increment space counter
|
|
cmp ecx,0002h ; is this the second space
|
|
jne @@munchLoop ; if not then keep reading
|
|
@@copyLoop: ; copy loop sync address
|
|
mov al,byte ptr[esi] ; get source byte into al register
|
|
mov byte ptr[edi],al ; copy byte into destination
|
|
inc esi ; increment along source line
|
|
inc edi ; increment along destination
|
|
cmp al,0000h ; compare input byte to zero
|
|
jne @@copyLoop ; if it's not null then keep going
|
|
pop edi ; restore destination index register
|
|
pop esi ; restore source index register
|
|
pop ebp ; restore stack frame
|
|
retn ; return near to caller
|
|
_getOutputFileName endp
|
|
public _uudecode
|
|
END
|