We open the Lab18-04.exe file in PEiD and learn that it is packed with
ASPack 2.12 -> Alexey Solodovnikov. We then open the malware in OllyDbg and see that the first
instruction is pushad, which saves the registers onto the stack.
We know from Chapter 18 that setting a breakpoint on the stack to
search for the corresponding popad instruction may be a good
strategy for this packer. We step-over the pushad instruction, as
shown in Example C-181 at ❶.
Example C-181. Start of the unpacking stub
00411001 ❶PUSHAD
00411002 CALL Lab18-04.0041100A
00411007 JMP 459E14F7We’re going to use the same technique that we used in the previous lab. Once we
step-over the pushad instruction, our window looks like Figure C-68.
We right-click esp at ❶ and select Follow in Dump in
order to display the memory window, as shown in Figure C-68. We then click the top of the stack at
❷ and select Breakpoint ▸
Hardware, on Access ▸ DWORD to set a breakpoint on the stack instruction.
We press F9 to start the program again. The program eventually hits our breakpoint, and we see the code shown in Example C-182.
Example C-182. Instructions after our stack breakpoint is triggered
004113AF POPAD
004113B0 ❶JNZ SHORT Lab18-04.004113BA
004113B2 MOV EAX,1
004113B7 RETN 0C
004113BA PUSH Lab18-04.00403896
004113BF RETNWe see a jnz instruction at ❶, immediately after the popad
instruction. We know that the popad should be followed closely by
the tail jump, which transfers execution to the OEP. We step-over the jnz instruction and see that it jumps just a few instructions ahead. There we see a
push followed by a retn, which
transfers execution to the address pushed onto the stack and might be our tail jump.
When we step over the retn instruction, we see that our
instruction pointer has been transferred to another area of the program. As in previous labs,
OllyDbg may not have disassembled this code, as shown in Example C-183.
Example C-183. OEP of the code before OllyDbg has analyzed it
00403896 DB 55 ; CHAR 'U' 00403897 DB 8B 00403898 DB EC 00403899 DB 6A ; CHAR 'j' 0040389A DB FF 0040389B DB 68 ; CHAR 'h' 0040389C DB 88 0040389D DB B1 0040389E DB 40 ; CHAR '@' 0040389F DB 00
We know this is code, so we tell OllyDbg to disassemble it by right-clicking the first
byte and selecting Analysis ▸ Analyze Code. Now we see what
looks like legitimate code with the telltale GetModuleHandleA
function, as shown in Example C-184. This confirms our
suspicions that this is the OEP.
Example C-184. OEP after OllyDbg has analyzed the code
00403896 PUSH EBP 00403897 MOV EBP,ESP 00403899 PUSH -1 0040389B PUSH Lab18-04.0040B188 004038A0 PUSH Lab18-04.004064AC ; SE handler installation 004038A5 MOV EAX,DWORD PTR FS:[0] 004038AB PUSH EAX 004038AC MOV DWORD PTR FS:[0],ESP 004038B3 SUB ESP,10 004038B6 PUSH EBX 004038B7 PUSH ESI 004038B8 PUSH EDI 004038B9 MOV DWORD PTR SS:[EBP-18],ESP 004038BC CALL DWORD PTR DS:[40B0B8] ; kernel32.GetVersion
Next, we select Plugins ▸ OllyDump ▸ Dump Debugged Process. We click the Get EIP as OEP button, accept the default settings, and click Dump. In the dialog, we enter a filename to save a copy of the unpacked program.
Having dumped the program, run it to verify that it works properly. Then open it in IDA Pro to verify that it is unpacked and has the same functionality as Lab09-01.exe.