Sample H. The function sub_10BB6 has a loop searching for something. First recover the function prototype and then infer the types based on the context. Hint: You should probably have a copy of the PE specification nearby.
Here is an image that details the PE file format, which is useful for referencing offsets.
The structs that make up the PE file format are:
typedef struct _IMAGE_DOS_HEADER { WORD e_magic; /* 0x0 */ WORD e_cblp; /* 0x2 */ WORD e_cp; /* 0x4 */ WORD e_crlc; /* 0x6 */ WORD e_cparhdr; /* 0x8 */ WORD e_minalloc; /* 0xa */ WORD e_maxalloc; /* 0xc */ WORD e_ss; /* 0xe */ WORD e_sp; /* 0x10 */ WORD e_csum; /* 0x12 */ WORD e_ip; /* 0x14 */ WORD e_cs; /* 0x16 */ WORD e_lfarlc; /* 0x18 */ WORD e_ovno; /* 0x1a */ WORD e_res[4]; /* 0x1c */ WORD e_oemid; /* 0x24 */ WORD e_oeminfo; /* 0x26 */ WORD e_res2[10]; /* 0x28 */ LONG e_lfanew; /* 0x3c */ } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; typedef struct _IMAGE_NT_HEADERS { DWORD Signature; /* 0x0 */ union { IMAGE_FILE_HEADER FileHeader; /* 0x4 */ struct { WORD Machine; /* 0x4 */ WORD NumberOfSections; /* 0x6 */ DWORD TimeDateStamp; /* 0x8 */ DWORD PointerToSymbolTable; /* 0xc */ DWORD NumberOfSymbols; /* 0x10 */ WORD SizeOfOptionalHeader; /* 0x14 */ WORD Characteristics; /* 0x16 */ } } IMAGE_OPTIONAL_HEADER OptionalHeader; /* 0x18 */ } IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
Here is the disassembly of the function in Sample H:
sub_10BB2: mov eax, [esp+4] push ebx push esi mov esi, [eax+3Ch] add esi, eax movzx eax, word ptr [esi+14h] xor ebx, ebx cmp [esi+6], bx push edi lea edi, [eax+esi+18h] jbe short loc_10BEB loc_10BCE: push [esp+0Ch+8] ; _DWORD push edi ; _DWORD call ds:dword_169A4 test eax, eax pop ecx pop ecx jz short loc_10BF3 movzx eax, word ptr [esi+6] add edi, 28h inc ebx cmp ebx, eax jb short loc_10BCE loc_10BEB: xor eax, eax loc_10BED: pop edi pop esi pop ebx retn 8 loc_10BF3: mov eax, edi jmp short loc_10BED
Making the assumption that our first argument is a pointer to the DOS header (from the hint in the question), we can use a little bit of math to calculate the offsets and see everything lines up. The search code could be written in a for loop but I used a while loop for more clarity.
PIMAGE_SECTION_HEADER sub_10BB2(PVOID pPE, PVOID arg2) { PIMAGE_DOS_HEADER pDOS; PIMAGE_NT_HEADERS pNT; PIMAGE_SECTION_HEADER pSection; WORD dwOptHdrSize; DWORD dwCurrentSection; /* mov eax, [esp+4] */ pDOS = (PIMAGE_DOS_HEADER) pPE; /* mov esi, [eax+3Ch] */ /* add esi, eax */ pNT = (pDOS + pDOS->e_lfanew); /* movzx eax, word ptr [esi+14h] */ dwOptHdrSize = pNT->FileHeader.SizeOfOptionalHeader; /* xor ebx, ebx */ dwCurrentSection = 0; /* cmp [esi+6], bx */ if (pNT->NumberOfSections == 0) return NULL; /* lea edi, [eax+esi+18h] */ pSection = IMAGE_FIRST_SECTION(pNT); while (1) { /* push [esp+0Ch+8] */ /* push edi */ /* call ds:dword_169A4 */ /* test eax, eax */ if (*(BOOL)dword_169A4)(pSection, arg2)) return pSection; /* add edi, 28h */ ++pSection; /* struct increment */ /* inc ebx */ ++dwCurrentSection; /* movzx eax, word ptr [esi+6] */ /* cmp ebx, eax */ if (dwCurrentSection > pNT->NumberOfSections) return NULL; } }
No comments :
Post a Comment