7 minutes
Practical Reverse Engineering - Exercise 1, Page 35
Table of Contents
Question
Repeat the walk-through by yourself. Draw the stack layout, including parameters and local variables.
Answer
Here is the VirusTotal
link to the malware sample in question:
wship4.dll
And here is the raw disassembly of the DllMain
routine as generated by IDA Pro
for reference:
.text:10001C60 ; =============== S U B R O U T I N E =======================================
.text:10001C60
.text:10001C60 ; Attributes: bp-based frame
.text:10001C60
.text:10001C60 ; BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
.text:10001C60 _DllMain@12 proc near ; CODE XREF: DllEntryPoint+4B↓p
.text:10001C60
.text:10001C60 pe = PROCESSENTRY32 ptr -130h
.text:10001C60 var_8 = byte ptr -8
.text:10001C60 hinstDLL = dword ptr 8
.text:10001C60 fdwReason = dword ptr 0Ch
.text:10001C60 lpvReserved = dword ptr 10h
.text:10001C60
.text:10001C60 000 55 push ebp
.text:10001C61 004 8B EC mov ebp, esp
.text:10001C63 004 81 EC 30 01 00 00 sub esp, 130h
.text:10001C69 134 57 push edi
.text:10001C6A 138 0F 01 4D F8 sidt fword ptr [ebp+var_8]
.text:10001C6E 138 8B 45 FA mov eax, dword ptr [ebp+var_8+2]
.text:10001C71 138 3D 00 F4 03 80 cmp eax, 8003F400h
.text:10001C76 138 76 10 jbe short loc_10001C88
.text:10001C78 138 3D 00 74 04 80 cmp eax, 80047400h
.text:10001C7D 138 73 09 jnb short loc_10001C88
.text:10001C7F 138 33 C0 xor eax, eax
.text:10001C81 138 5F pop edi
.text:10001C82 134 8B E5 mov esp, ebp
.text:10001C84 004 5D pop ebp
.text:10001C85 000 C2 0C 00 retn 0Ch
.text:10001C88 ; ---------------------------------------------------------------------------
.text:10001C88
.text:10001C88 loc_10001C88: ; CODE XREF: DllMain(x,x,x)+16↑j
.text:10001C88 ; DllMain(x,x,x)+1D↑j
.text:10001C88 138 33 C0 xor eax, eax
.text:10001C8A 138 B9 49 00 00 00 mov ecx, 49h ; 'I'
.text:10001C8F 138 8D BD D4 FE FF FF lea edi, [ebp+pe.cntUsage]
.text:10001C95 138 C7 85 D0 FE FF FF 00 00 00 00 mov [ebp+pe.dwSize], 0
.text:10001C9F 138 50 push eax ; th32ProcessID
.text:10001CA0 13C 6A 02 push 2 ; dwFlags
.text:10001CA2 140 F3 AB rep stosd
.text:10001CA4 140 E8 2D 2F 00 00 call CreateToolhelp32Snapshot
.text:10001CA9 138 8B F8 mov edi, eax
.text:10001CAB 138 83 FF FF cmp edi, 0FFFFFFFFh
.text:10001CAE 138 75 09 jnz short loc_10001CB9
.text:10001CB0 138 33 C0 xor eax, eax
.text:10001CB2 138 5F pop edi
.text:10001CB3 134 8B E5 mov esp, ebp
.text:10001CB5 004 5D pop ebp
.text:10001CB6 000 C2 0C 00 retn 0Ch
.text:10001CB9 ; ---------------------------------------------------------------------------
.text:10001CB9
.text:10001CB9 loc_10001CB9: ; CODE XREF: DllMain(x,x,x)+4E↑j
.text:10001CB9 138 8D 85 D0 FE FF FF lea eax, [ebp+pe]
.text:10001CBF 138 56 push esi
.text:10001CC0 13C 50 push eax ; lppe
.text:10001CC1 140 57 push edi ; hSnapshot
.text:10001CC2 144 C7 85 D0 FE FF FF 28 01 00 00 mov [ebp+pe.dwSize], 128h
.text:10001CCC 144 E8 FF 2E 00 00 call Process32First
.text:10001CD1 13C 85 C0 test eax, eax
.text:10001CD3 13C 74 4F jz short loc_10001D24
.text:10001CD5 13C 8B 35 C0 50 00 10 mov esi, ds:_stricmp
.text:10001CDB 13C 8D 8D F4 FE FF FF lea ecx, [ebp+pe.szExeFile]
.text:10001CE1 13C 68 50 7C 00 10 push offset String2 ; "explorer.exe"
.text:10001CE6 140 51 push ecx ; String1
.text:10001CE7 144 FF D6 call esi ; _stricmp
.text:10001CE9 144 83 C4 08 add esp, 8
.text:10001CEC 13C 85 C0 test eax, eax
.text:10001CEE 13C 74 26 jz short loc_10001D16
.text:10001CF0
.text:10001CF0 loc_10001CF0: ; CODE XREF: DllMain(x,x,x)+B4↓j
.text:10001CF0 13C 8D 95 D0 FE FF FF lea edx, [ebp+pe]
.text:10001CF6 13C 52 push edx ; lppe
.text:10001CF7 140 57 push edi ; hSnapshot
.text:10001CF8 144 E8 CD 2E 00 00 call Process32Next
.text:10001CFD 13C 85 C0 test eax, eax
.text:10001CFF 13C 74 23 jz short loc_10001D24
.text:10001D01 13C 8D 85 F4 FE FF FF lea eax, [ebp+pe.szExeFile]
.text:10001D07 13C 68 50 7C 00 10 push offset String2 ; "explorer.exe"
.text:10001D0C 140 50 push eax ; String1
.text:10001D0D 144 FF D6 call esi ; _stricmp
.text:10001D0F 144 83 C4 08 add esp, 8
.text:10001D12 13C 85 C0 test eax, eax
.text:10001D14 13C 75 DA jnz short loc_10001CF0
.text:10001D16
.text:10001D16 loc_10001D16: ; CODE XREF: DllMain(x,x,x)+8E↑j
.text:10001D16 13C 8B 85 E8 FE FF FF mov eax, [ebp+pe.th32ParentProcessID]
.text:10001D1C 13C 8B 8D D8 FE FF FF mov ecx, [ebp+pe.th32ProcessID]
.text:10001D22 13C EB 06 jmp short loc_10001D2A
.text:10001D24 ; ---------------------------------------------------------------------------
.text:10001D24
.text:10001D24 loc_10001D24: ; CODE XREF: DllMain(x,x,x)+73↑j
.text:10001D24 ; DllMain(x,x,x)+9F↑j
.text:10001D24 13C 8B 45 0C mov eax, [ebp+fdwReason]
.text:10001D27 13C 8B 4D 0C mov ecx, [ebp+fdwReason]
.text:10001D2A
.text:10001D2A loc_10001D2A: ; CODE XREF: DllMain(x,x,x)+C2↑j
.text:10001D2A 13C 3B C1 cmp eax, ecx
.text:10001D2C 13C 5E pop esi
.text:10001D2D 138 75 09 jnz short loc_10001D38
.text:10001D2F 138 33 C0 xor eax, eax
.text:10001D31 138 5F pop edi
.text:10001D32 134 8B E5 mov esp, ebp
.text:10001D34 004 5D pop ebp
.text:10001D35 000 C2 0C 00 retn 0Ch
.text:10001D38 ; ---------------------------------------------------------------------------
.text:10001D38
.text:10001D38 loc_10001D38: ; CODE XREF: DllMain(x,x,x)+CD↑j
.text:10001D38 138 8B 45 0C mov eax, [ebp+fdwReason]
.text:10001D3B 138 48 dec eax
.text:10001D3C 138 75 15 jnz short loc_10001D53
.text:10001D3E 138 6A 00 push 0 ; lpThreadId
.text:10001D40 13C 6A 00 push 0 ; dwCreationFlags
.text:10001D42 140 6A 00 push 0 ; lpParameter
.text:10001D44 144 68 D0 32 00 10 push offset StartAddress ; lpStartAddress
.text:10001D49 148 6A 00 push 0 ; dwStackSize
.text:10001D4B 14C 6A 00 push 0 ; lpThreadAttributes
.text:10001D4D 150 FF 15 20 50 00 10 call ds:CreateThread
.text:10001D53
.text:10001D53 loc_10001D53: ; CODE XREF: DllMain(x,x,x)+DC↑j
.text:10001D53 138 B8 01 00 00 00 mov eax, 1
.text:10001D58 138 5F pop edi
.text:10001D59 134 8B E5 mov esp, ebp
.text:10001D5B 004 5D pop ebp
.text:10001D5C 000 C2 0C 00 retn 0Ch
.text:10001D5C _DllMain@12 endp
Here’s how the stack diagram looks like at the start of the DllMain
routine:
And here’s how the local stack frame looks like after the execution of the function prologue:
Note how 0x130
worth of space is allocated on the stack in what can only be presumed is for storing the local variables. Also, note that the offsets are now relative to the base frame pointer.
We can see from the above disassembly that one of the local variables is a structure of type PROCESSENTRY32(which IDA
rather ambiguously has named pe
). Now, we know that sizeof(pe) == 0x128
bytes but the program allocated 0x130
bytes worth of space on the stack for local variables. That must mean that the second local variable(var_8
) is of size 0x8
bytes.
A little later into the disassembly just after the function prologue, we can see that var_8
is indeed used to store the contents of the IDTR
using the sidt instruction. In x86
nt
, the data structure used to represent the contents of the GDT
and IDT
registers is defined like so:
// 0x8 bytes(sizeof)
typedef struct _DESCRIPTOR {
USHORT Pad; // 0x0
USHORT Limit; // 0x2
ULONG Base; // 0x4
} KDESCRIPTOR, *PKDESCRIPTOR;
Ergo, var_8
can be inferred to be of type KDESCRIPTOR which also corroborates our previous size calculation.
So the complete stack layout can be illustrated like so:
Finally, we can see a raw decompilation of the above routine using Hex-Rays decompiler
on https://dogbolt.org/:
|
|
1321 Words
2022-08-24 02:00