format pe console 4.0
section '.text' readable writable executable
start:
call delta_offset ;Calculates the delta offset
delta_offset:
pop ebp ;Save the current address of the delta_offset routine in memory
sub ebp, delta_offset ;Current address of delta_offset ´- address of delta_offset at compilation time
;is equal to current address of virus body in memory. Now we can access any part of
;data embebbed in the code using [ebp+variable]
finding_kernel32:
mov ebx, [FS : 0x30] ;FS:0x30 is a pointer to the address of Process Environment Block (PEB)
;Now the Base Pointer (BX) points to the address of PEB in memory
mov ebx, [ebx + 0x0C] ;Now we move 0x0C (12 bytes) from the address of PEB
;We get the value of ebx+0x0c, in other words, the address that has the PEB->Ldr pointer
;Now we are in Ldr structure. We move the ebx pointer following the address in the
;PEB->Ldr pointer.
mov ebx, [ebx + 0x14] ; get PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
mov ebx, [ebx] ;2nd Entry
mov ebx, [ebx] ;3rd Entry
mov ebx, [ebx + 0x10] ; Get Kernel32 Base
mov [ebp+dwKernelBase] , ebx
add ebx, [ebx+0x3C] ; Start of PE header
mov ebx, [ebx+0x78] ; RVA of export dir
add ebx, [ebp+dwKernelBase] ; VA of export dir
mov [ebp+dwExportDirectory] , ebx
finding_address_of_getprocaddress:
lea edx,[ebp+api_GetProcAddress] ;Load in ebp the address of the API function name.
mov ecx,[ebp+len_GetProcAddress] ;Load in ecx the size of the API function name
call GetFunctionAddress ;Call GetFunctionAddress
mov [ebp+AGetProcAddressA] , eax ;The API function address in memory was stored by the
;GetFunctionAddress function in eax, now we save the address
;of the GetProcAddress in a variable for later use.
finding_address_of_loadlibrary:
lea edx,[ebp+api_LoadLibrary] ;Load in edx the API function name of LoadLibrary
push edx ;edx could be a parameter for an API
push dword [ebp+dwKernelBase] ;save in the stack the address of the kernel32 library
;dwKernelBase is used as handle
call eax ;Calls a function by its address (eax stores it)
;Could be GetProcAddress because in the instruction in
;the line 39 it moves the address of that API from eax
;and eax has no changes until 47 line.
loading_required_libraries:
mov [ebp+ALoadLibraryA] , eax ;The last function could return the address of LoadLibrary in
;in eax. eax register could be used by the last function as a
;return value.
;Now the eax register contains the address of LoadLibrary
lea edx , [ebp+szUser32] ;Loads in edx, the library name of User32.dll
push edx ;Put the edx value in the stack as a parameter for LoadLibrary
;I believe that the function could be LoadLibrary because
;it is an API that requires a string that contains the name of
;the library that you want to load.
call eax ;Call LoadLibrary API
mov [ebp+hUser32], eax
finding_addresses_of_apis:
lea edx , [ebp+api_MessageBoxA] ;Loads in edx the address of the name of MessageBoxA API
push edx ;Put the name of MessageBoxA as a parameter for a function
push eax ;I belive that eax is a handle to the loaded library
mov ebx,[ebp+AGetProcAddressA] ;Moves to ebx the address of GetProcAddressA
call ebx ;Invokes GetProcAddressA using its address
mov [ebp+AMessageBoxAA] , eax ;The last function (could be GetProcAddressA) returns the address of
;MessageBoxA in eax. We move the address of that API to a variable for
;later use.
;We start to search for functions inside
;kernel32.dll
set_exception_handler:
;A simple way to set a exception handler, avoiding the
;use of APIs that increase the size of the release.
push exception_handler
push dword [FS:0]
mov [FS:0], esp
main:
push 0 ;Put the HWND parameter
lea edx,[ebp+szTitle] ;Put the caption of the MessageBox
push edx
lea edx,[ebp+szMsg] ;Put the message body of the MessageBox
push edx
push 0 ;Buttons type (For example MB_OK)
call dword [ebp+AMessageBoxAA] ;Calls MessageBoxA API
;The following code tries to make many exceptions
int3 ;Software breakpoints
int3
int3
mov esi, 0 ;Access violation
mov dword [esi], "fail"
exit:
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; <<<<< GetFunctionAddress >>>>>> ;
; Extracts Function Address From Export Directory and returns it in eax ;
; Parameters : Function name in edx , Length in ecx ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetFunctionAddress:
push ebx ;Save status of registers before execute the subroutine
push esi ;to preserve its content. It could make some errors to the
push edi ;caller function if modify the values that are common to the whole
;program
mov esi, [ebp+dwExportDirectory]
mov esi, [esi+0x20] ;RVA of ENT
add esi, [ebp+dwKernelBase] ;VA of ENT
xor ebx,ebx
cld
looper:
inc ebx
lodsd ;Load a byte from the string pointed by SI into al register
add eax , [ebp+dwKernelBase] ;eax now points to the string of a function
push esi ;preserve it for the outer loop
mov esi,eax
mov edi,edx
cld ;The direction flag is clear, this means that the SI and DI pointers are
;incremented. (The instructions works to the forward direction)
push ecx ;Save ecx. Why?? The next instruction named "repe" decrements the counter.
;Because the ecx contains the length of the API name, we need to save it.
;In other parts of subroutine the program uses ecx register to compare the function
;with the kernel export table.
repe cmpsb ;Compare each byte of the array pointed by DS:SI with the array pointed by ES:DI
;Repeat until the counter is not equal to zero, in other words,
;it only stops when it find a difference or the counter reachs the end of the string
pop ecx ;Pop the length of the string, and put it in the counter for another loop if it's needed
pop esi ;Pop the last stack variable, and put it in esi.
jne looper
dec ebx
mov eax,[ebp+dwExportDirectory]
mov eax,[eax+0x24] ;RVA of EOT
add eax,[ebp+dwKernelBase] ;VA of EOT
movzx eax , word [ebx*2+eax] ;eax now holds the ordinal of our function
mov ebx,[ebp+dwExportDirectory]
mov ebx,[ebx+0x1C] ;RVA of EAT
add ebx,[ebp+dwKernelBase] ;VA of EAT
mov ebx,[eax*4+ebx]
add ebx,[ebp+dwKernelBase]
mov eax,ebx
pop edi ;Restore the registers to avoid generate a problem
pop esi ;in the caller function.
pop ebx
ret
exception_handler:
push 0 ;Put the HWND parameter
lea edx,[ebp+szTitle] ;Put the caption of the MessageBox
push edx
lea edx,[ebp+szMsgException] ;Put the message body of the MessageBox
push edx
push 0 ;Buttons type (For example MB_OK)
call dword [ebp+AMessageBoxAA] ;Calls MessageBoxA API
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Data Shit ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
szMsgException db 'Exception catched!!', 0
api_ExitProcess dd 0
szTitle: db "From the heaven",0
szMsg: db "Greetings from hell",0
szUser32 db "User32.dll",0
hUser32 dd 0
AGetProcAddressA: dd 0
api_GetProcAddress: db "GetProcAddress"
len_GetProcAddress: dd $-api_GetProcAddress
ALoadLibraryA: dd 0
api_LoadLibrary: db "LoadLibraryA",0
AMessageBoxAA: dd 0
api_MessageBoxA: db "MessageBoxA",0
dwKernelBase: dd 0
dwExportDirectory: dd 0