PicView v1.32
[Reversing essay]
published by Tsehp, July 2000.

Subject: Unpacking asprotected programs
Target: PicView v1.32
URL: http://abroaddesign.hypermart.net/picview/picview.zip
Author: BlackB
Date: 2000-07-23
Tools used: IcePatch v2, SoftICE, IceDump, Hex Workshop v3.x
Difficulty (scale 1-5): 3

Before starting!
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!!
I. Introduction

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!
Then why do I write another tutorial on unpacking the same program? Because, in my modest opinion, not everything is explained clear enough for newbie - novice Fravias / crackers. Some steps are not explained, or not mentioned at all.
See this tutorial as some sort of positive addition to Predator's essay ;-)

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
Install in in your SoftICE directory and run it. I won't explain you how everything works but I do will tell you what you have to change in order to hide SoftICE properly from ASProtect. Here's what you should fill in:

VXD ID for Winice: 203
VXD Name for Winice: BLAC (can be anything tho)
Winice Module Name: BLACKB (can be anything)
VXD ID for SiwVid: 7A60
VXD Name for SiwVid: WISDIV
VXD Name for SiwDebug: WISGUBED
For the "INT Settings" make everything zero.

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.
That same approach would work with ASProtected programs too, only....it would take hours, maybe days to get at the end of the unpacking routine. Therefore we'll have to find a method to get almost near the end of the unpacking routine.
Do you also hear a little 'beep' or 'tick' when loading PicView? It must be pretty near the end of the unpacking routine, as the splashscreen appears seconds after that. So let's set a: bpx messagebeep. Now run PicView and press F12 a few times (two times I guess) to get into the main code. You should see this:

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.

In this call, everything of the program starts running. So I assume that this is the end of the unpacking routine. But we still don't have our OEP. Trace into that call, keep on tracing and you will notice that at a certain moment, EAX will contain following value: 4E3DF8. This is our OEP!
You may wonder: "How can I know?": In 90% of the cases, the OEP is stored at the end of the unpacking routine in EAX or in some other cases pushed. (Then it would be PUSH 004E3DF8).
If you only want to crack PicView (which is not described in this essay), you could try the approach I used in my essay on ACDSee. I don't know if it will work, it's just an idea.

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!
Now we have to dump the unpacked process. First run Procdump and PE Edit PicView.exe . Remember the Size of image and Image base. In this case they are: 144000 and 400000.
The best place to be to dump a packed program is at the end of the unpacking routine or at the beginning of the unpacked program. Let's take the second one ;-) SoftICE will have to break on 4E3DF8: set a breakpoint on messagebeep again, run PicView, press F12 until you're in the main code and then type: bpm 4e3df8 x. This way, SoftICE will break when the instruction at memory location 4E3DF8 is executed, in English: when the real program starts executing.
When there, type: /dump 400000 144000 c:\temp\image.exe. This will dump the unpacked image with the scrambled import table.

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
Note that you type 4E9000 and not E9000! (offset when running = offset_of_idata + imagebase = E9000 + 400000).

Now we have to merge our clean import table with our image.exe. Open up Hex Workshop, open image.exe, click on "Edit - Goto", select hex and type E9000. Now you are where the importtable starts. Now select exactly 3000h bytes by holding your shift key and scrolling down with the down cursor or pagedown if you want to make it go faster. You can follow the amount of bytes you selected in the statusbar (bottom) of hex workshop. When 3000h bytes (and note that that is a hex value, therefore I use the 'h' at the end of it) are selected, click on "File - Replace by file" and select our dumped idata.dat. NOw the merging is finished.

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.
Last thing to do now is fixing the PE so our unpacked program won't crash: click on 'directory' and change the RVA of the Import Table (in this case E9000). Click OK and goto "Sections". Note that you need to do following procedure for EVERY section:

1. Right click on the section, click on Edit Section
2. Change characteristics from C0000040 into E0000060
3. Select VSize, copy it to clipboard (CTRL-C), select PSize and paste the VSize value (CTRL-V).
4. Select RVA, copy it to clipboard (CTRL-V), select Offset and paste the RVA value (CTRL-V).
5. Click OK and go to step 1 for the next section until every section is done.

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.
You can't really patch this CRC check as it isn't unpacked yet in the PicView.exe on your harddisk. But again, you may use my approach I used in my essay on ACDSee to patch it.

Well I'm kinda finished now :) Cya


IV. In the end

Thanks and credits go to Predator and Risc.
Hope you learned something! See you all!



Essay written by The Blackbird 1999-2000
This essay can be freely distributed/ published/ printed etc... as long as no modifications are made.