published by Tsehp, July 2000.
Subject: Unpacking asprotected programs
This essay is for knowledge purposes only!!
Software developers spend much time in making their programs. They live from the money we give them!
Please buy good software!!
Welcome in this unpacking tutorial. Before I say anything else I want
to make clear that this essay is actually not my work. I was doing some
research work on Asprotect when I accidentally fell over "Unpacking
files packed / protected with the New ASProtect", a tutorial by
Predator. I was already working for a while on ASProtect and of curiousity
I read the tutorial Predator wrote. Some ideas I had were in his
essay......but as he was first and did the whole job, full credit
go to him and Risc!
|II. About the protection|
|ASProtect: Packed, Anti-debugger, CRC|
|III. Unpacking it|
The first thing I do before everything
is running the program! We get a messagebox: Debugger active! There's our
Anti-Debugger check. We could try and find it manually, but as there are
so many tools to hide SoftICE it would be a waste of time. I tried hiding
SoftICE with Frog's Print FrogSice but or PicView kept on crashing, or
everything worked fine, but I couldn't set any breakpoints. So.....another
utility had to be used named IcePatch which you can get at http://protools.cjb.net
Then click on APPLY and reboot your computer. Now run PicView again and it should run fine now. You can restore your SoftICE settings with the RESTORE button in IcePatch. Don't forget to reboot your computer to apply the changes.
First thing we have to do when dealing
with a packed program is locating the Original Program Entrypoint or
abbreviated: OEP. With other targets the approach we use is: tracing from
the start of the unpacking routine to the end of the unpacking routine,
and at the end we can find the OEP.
Start partial code
0137:0059353D XOR EAX,EAX 0137:0059353F POP EDX 0137:00593540 POP ECX 0137:00593541 POP ECX 0137:00593542 MOV FS:[EAX],EDX 0137:00593545 JMP 0059355A 0137:00593547 JMP 00583BC0 0137:0059354C MOV AX,000D 0137:00593550 CALL 005927A8 0137:00593555 CALL 00583E5C 0137:0059355A XOR EAX,EAX 0137:0059355C PUSH EBP 0137:0059355D PUSH 0059357A 0137:00593562 PUSH DWORD PTR FS:[EAX] 0137:00593565 MOV FS:[EAX],ESP 0137:00593568 MOV EAX,[EBP+08] 0137:0059356B CALL 00593184 0137:00593570 XOR EAX,EAX 0137:00593572 POP EDX 0137:00593573 POP ECX 0137:00593574 POP ECX 0137:00593575 MOV FS:[EAX],EDX 0137:00593578 JMP 0059358D 0137:0059357A JMP 00583BC0 0137:0059357F MOV AX,0011 0137:00593583 CALL 005927A8 0137:00593588 CALL 00583E5C 0137:0059358D XOR EAX,EAX 0137:0059358F PUSH EBP 0137:00593590 PUSH 005935C6 0137:00593595 PUSH DWORD PTR FS:[EAX] 0137:00593598 MOV FS:[EAX],ESP 0137:0059359B MOV EAX,005927A8 0137:005935A0 PUSH EAX 0137:005935A1 MOV EAX,[EBP+08] 0137:005935A4 MOV ECX,[EAX+10] 0137:005935A7 MOV EAX,[EBP+08] 0137:005935AA MOV EDX,[EAX+04] 0137:005935AD MOV EAX,[EBP+08] 0137:005935B0 MOV EAX,[EAX] 0137:005935B2 CALL 00592CC0 0137:005935B7 MOV [0059963C],AL 0137:005935BC XOR EAX,EAX 0137:005935BE POP EDX 0137:005935BF POP ECX 0137:005935C0 POP ECX 0137:005935C1 MOV FS:[EAX],EDX 0137:005935C4 JMP 005935D9 0137:005935C6 JMP 00583BC0 0137:005935CB MOV AX,000E 0137:005935CF CALL 005927A8 0137:005935D4 CALL 00583E5C 0137:005935D9 MOV EAX,[EBP+08] 0137:005935DC LEA ECX,[EAX+18] 0137:005935DF MOV EAX,[EBP+08] 0137:005935E2 MOV EDX,[EAX] 0137:005935E4 MOV EAX,[EBP+08] 0137:005935E7 MOV EAX,[EAX+1C] 0137:005935EA CALL 00592D4C (1.) 0137:005935EF POP EDI 0137:005935F0 POP ESI 0137:005935F1 POP EBX 0137:005935F2 POP ECX 0137:005935F3 POP ECX 0137:005935F4 POP EBP 0137:005935F5 RET 0004
End partial code
Trace all the way down to the call at the end. Note that the offsets
will be different on your computer. ASProtect seems to use variable
offsets. Therefore you can't set a breakpoint on 5935EA to break on the
call, as on your computer it will be another instruction.
With the average normal packer, we would
now dump the whole process with Procdump and only have to change the
entrypoint (=OEP) to make it work. In ASProtect's case, the Import Table
is scrambled/ encrypted and therefore, the dumped image even with the
right OEP will make it crash. So we have to dump the unpacked program and
then dump the untouched/ virgin/ decrypted Import Table. We'll do
everything with IceDump....a great tool btw. Please be sure you use the
latest IceDump version!
Next thing to do is dumping the untouched
Import Table. Look in Procdump PE editor again, click on
"sections" and note the RVA and VSize of the IDATA section. They
should be E9000 and 3000. Now set a breakpoint on LoadLibraryA. This is an
API that's used in many packed programs to load the import table. Run
PicView, SoftICE breaks, press F12 to get into the main ASProtect code.
We're ready to dump now, type: /dump 4E9000 3000 c:\temp\idata.dat
We still can't run our unpacked program as
we still have to change our OEP. Fire up Procdump PE Editor for our
image.exe and change the Entry Point to E3DF8.
When done exit Procdump, run PicView and see that it's running fine. :-)
I could stop writing know, because you sucessfully unpacked it, but I want to show you where the CRC check is located. First of all, change a non-important byte in PicView.exe . Run it and a messagebox "File corrupted" will appear. If a program wants to CRC check itself, it has to open itself in some way. Therefore, a good API to break on is ReadFile. So set a breakpoint on readfile and run PicView. Note that it may happen that SoftICE breaks on ReadFile but not called by PicView but by Explorer. In such a case, press F5 (= run until next breakpoint) until you see the programname 'Picview' appear in the bottom right corner of SoftICE. Then press F12 five times to get to the CRC check. I know it sounds stupid when I say "Press x times F12", because I know you wonder why five times, an how I know. It's pretty simple: when I was reversing this target I didn't press F12 five times, but I just traced with F10 until I thought I saw a suspicious jump. After I've found the CRC check I easily found out that you just have to press F12 five times until you get there. Anyway, this is the code:
Start partial code
0137:005A214A MOV EAX,[EBP-14] 0137:005A214D CMP EAX,[EBP-10] 0137:005A2150 JZ 005A2195 (1.) 0137:005A2152 MOV DL,[005A7680]
End partial code
(1.) If the file is not corrupted, the JZ jumps. If not, it
won't jump, and the messagebox will appear.
Well I'm kinda finished now :) Cya
|IV. In the end|
Thanks and credits go to Predator and Risc.
Essay written by The Blackbird © 1999-2000
This essay can be freely distributed/ published/ printed etc... as long as no modifications are made.