; ###############################################################################;
; DESCRIPTION: Simple and not optimized code for Base 64 Encode/Decode algorithm.
; :
; -------------------------------------------------------------------------------;
; COMPILATION: ml /c /coff file.asm
; LINKING : link /SUBSYSTEM:CONSOLE file
; -------------------------------------------------------------------------------;
; AUTHOR : Marco 'RootkitNeo' C.
; -------------------------------------------------------------------------------;
; LANGUAGE : MASM32 (CUI Application)
; -------------------------------------------------------------------------------;
; VERSION : v. 1.0
; -------------------------------------------------------------------------------;
; LICENSE : GNU/GPL V.3
; ###############################################################################;
include c:\masm32\include\masm32rt.inc
; String length (byte format)
; #################################################################################-
strLen MACRO string
xor eax, eax
xor ecx, ecx
mywhile:
cmp [string+ecx], 0
je _exit
inc ecx
jmp mywhile
_exit:
mov eax, ecx
ENDM
; #################################################################################
; Get index of a char in CODES string
; #################################################################################
indexOf MACRO char
push ecx
xor ecx, ecx
.IF char != '='
.WHILE [codes+ecx] != char
inc cl
.ENDW
.ELSE
mov ecx, -1
.ENDIF
mov dl, cl
pop ecx
EXITM <dl> ; return value
ENDM
; #################################################################################
;
; Data Section
; ---------------------------------------------------------------------------------
.data
initMessage1 db 9,9,"#############################################",13,10,
9,9,"# #",13,10,
9,9,"# Base64 v.1.0 | MASM V. 6.14.8444 #",13,10,
9,9,"#-------------------------------------------#",13,10,
9,9,"# Developed by: #",13,10,0
initMessage2 db 9,9,"# Marco 'RootkitNeo' C. #",13,10,
9,9,"#-------------------------------------------#",13,10,
9,9,"# Description : #",13,10,
9,9,"# Base64 Encode/Decode #",13,10,
9,9,"#############################################",13,10,13,10,0
strInputTextM db "Type your text: ",0
strOutputTextME db "Base64 Encoded String: ",0
strOutputTextMD db "Base64 Decoded String: ",0
codes db "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
CRLF db 13,10,0
menu db "-------------------------------------------------------------------------------",13,10,
"Select an option:",13,10,
"1. Encode",13,10,
"2. Decode",13,10,
"3. Exit",13,10,13,10,
"> ",0
consoleTitle db "Base 64 Encode/Decode ",0
; ---------------------------------------------------------------------------------
;
; Stack section
; ---------------------------------------------------------------------------------
.data?
strBuffer db 100 dup (?) ; Plain text buffer
strEncodedBuffer db 300 dup (?) ; Encode text buffer
choice db ? ; Selected option (menu)
; ---------------------------------------------------------------------------------
;
; Constant section
; ---------------------------------------------------------------------------------
.const
max_input_buffer = 100
max_encoded_buffer = 300
; ---------------------------------------------------------------------------------
;
; Code segment
; ---------------------------------------------------------------------------------
.code
start:
; Title of the window
invoke SetConsoleTitle, addr consoleTitle
; Show the menu
.WHILE choice != '3'
call ClearScreenAndColor
; Print init message
push offset initMessage1
call StdOut
push offset initMessage2
call StdOut
; The menu
push offset menu
call StdOut
; Wait user input
push 4
push offset choice
call StdIn
; Encode
.IF choice == '1'
push offset strInputTextM
call StdOut
push [max_input_buffer]
push offset strBuffer
call StdIn
push offset CRLF
call StdOut
call encodeString
push offset strOutputTextME
call StdOut
push offset strEncodedBuffer
call StdOut
; Decode
.ELSEIF choice == '2'
push offset strInputTextM
call StdOut
push [max_encoded_buffer]
push offset strEncodedBuffer
call StdIn
push offset CRLF
call StdOut
call decodeString
push offset strOutputTextMD
call StdOut
push offset strBuffer
call StdOut
.ENDIF
; End if
push offset CRLF
call StdOut
push offset CRLF
call StdOut
; Clean buffers
invoke RtlZeroMemory, addr strBuffer,max_input_buffer
invoke RtlZeroMemory, addr strEncodedBuffer, max_encoded_buffer
inkey "[...Press any key to continue...]"
.ENDW
; Exit
invoke ExitProcess, 0
;
; Encode plain text
; ---------------------------------------------------------------------------------
encodeString proc
pushad
strLen [strBuffer] ; Length
xor ecx, ecx
mov ebx, eax
xor eax, eax
xor edx, edx
xor esi, esi
.while ecx < ebx
mov al, [strBuffer+ecx]
and al, 0FCh
shr al, 2
mov al, [codes+eax]
mov [strEncodedBuffer+esi+0], al
; First char
mov al, [strBuffer+ecx]
and al, 03h
shl al, 4
inc ecx
dec ebx
.IF ecx > ebx
dec ecx
inc ebx
; Second char
mov al, [codes+eax]
mov [strEncodedBuffer+esi+1], al
mov [strEncodedBuffer+esi+2], '='
mov [strEncodedBuffer+esi+3], '='
.ELSE
inc ebx
dec ecx
; Second char
mov dl, [strBuffer+ecx+1]
and dl, 0F0h
shr dl, 4
or al, dl
mov al, [codes+eax]
mov [strEncodedBuffer+esi+1], al
mov al, [strBuffer+ecx+1]
and al, 0Fh
shl al, 2
add ecx, 2
dec ebx
.IF ecx > ebx
sub ecx, 2
inc ebx
; Third char and four
mov al, [codes+eax]
mov [strEncodedBuffer+esi+2], al
mov [strEncodedBuffer+esi+3], '='
.ELSE
sub ecx, 2
inc ebx
; Third char
mov dl, [strBuffer+ecx+2]
and dl, 0C0h
shr dl, 6
or al, dl
mov al, [codes+eax]
mov [strEncodedBuffer+esi+2], al
; Four char
mov al, [strBuffer+ecx+2]
and al, 3Fh
mov al, [codes+eax]
mov [strEncodedBuffer+esi+3], al
.ENDIF
.ENDIF
add ecx, 3
add esi, 4
.endw
; End string character
mov [strEncodedBuffer+esi+4], 0
popad
ret
encodeString endp
;
; Decode String
; ---------------------------------------------------------------------------------
decodeString proc
pushad
strLen [strEncodedBuffer]
mov ebx, eax
xor ecx, ecx
xor eax, eax
xor edx, edx
xor esi, esi
.while ecx < ebx
mov al, [strEncodedBuffer+ecx+0]
mov al, indexOf(al)
mov dl, [strEncodedBuffer+ecx+1]
mov dl, indexOf(dl)
shl al, 2
shr dl, 4
or al, dl
mov [strBuffer+esi], al ; First
inc esi
mov al, [strEncodedBuffer+ecx+1]
mov al, indexOf(al)
mov dl, [strEncodedBuffer+ecx+2]
.IF dl == '='
jmp _end
.ENDIF
mov dl, indexOf(dl)
shl al, 4
shr dl, 2
or al, dl
mov [strBuffer+esi], al ; Second
inc esi
mov al, [strEncodedBuffer+ecx+2]
mov al, indexOf(al)
mov dl, [strEncodedBuffer+ecx+3]
mov dl, indexOf(dl)
shl al, 6
or al, dl
mov [strBuffer+esi], al ; Third
inc esi
add ecx, 4
.endw
_end:
mov [strBuffer+esi], 0
popad
ret
decodeString endp
; ---------------------------------------------------------------------------------
; #############################################
; # UTILITY FUNCTION #
; #############################################
;
; Clear command prompt window and set the colors
; ---------------------------------------------------------------------------------
ClearScreenAndColor proc
LOCAL coordScreen:COORD
LOCAL cCharsWritten:DWORD
LOCAL csbi:CONSOLE_SCREEN_BUFFER_INFO
LOCAL dwConSize:DWORD
LOCAL hStdout:HANDLE
pushad
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov hStdout, eax
invoke GetConsoleScreenBufferInfo, hStdout, addr csbi
.IF eax == 0
print "Error 1"
jmp _exit_clear
.ENDIF
movzx ebx, word ptr csbi.dwSize.y
movzx eax, word ptr csbi.dwSize.x
mul ebx
mov dwConSize, eax
invoke FillConsoleOutputCharacter, hStdout, ' ', dwConSize, 0, addr cCharsWritten
.IF eax == 0
print "Error 2"
jmp _exit_clear
.ENDIF
invoke GetConsoleScreenBufferInfo, hStdout, addr csbi
.IF eax == 0
print "Error 3"
jmp _exit_clear
.ENDIF
; Set Background and Foreground colors
invoke FillConsoleOutputAttribute, hStdout, (BACKGROUND_BLUE or BACKGROUND_INTENSITY or FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_RED or FOREGROUND_INTENSITY), 65535, 0, addr cCharsWritten
invoke SetConsoleTextAttribute, hStdout, (BACKGROUND_BLUE or BACKGROUND_INTENSITY or FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_RED or FOREGROUND_INTENSITY)
.IF eax == 0
print "Error 4"
invoke GetLastError
jmp _exit_clear
.ENDIF
invoke SetConsoleCursorPosition, hStdout, 0
_exit_clear:
popad
ret
ClearScreenAndColor endp
end start