Generating a patch for a packed program
Another approach to cracking packed programs
Packers
Packers & Unpackers 
7 September 1999
by  Lord Soth
Courtesy of Fravia's page of reverse engineering
and the Immortal Descendants, Inc.
slightly edited 
by fravia+ 
fra_00xx 
98xxxx 
handle 
1100 
NA 
PC
A different approach in unpacking, this is a crackme crack, thoroughly explained and well worth following for all those among you that want to learn.
There is a crack, a crack in everything That's how the light gets in
Rating
( )Beginner (x)Intermediate ( )Advanced ( )Expert 

This essay is for those who can't patch their packed targets and want to try a different approach of getting the job done ;-) 
Immortal Descendants CrackMe 5
crackme coded by Torn@do
Written by Lord Soth
 

Introduction 

Hello to everyone reading this new little paper.

In this text file I'll try to describe my latest idea at patching a packed executable
file.
I'm sure that if you dealt with packed/encrypted programs, you know something about
what can be done to patch them. The common methods are NO patching (trying to beat the
protection from a different angle, like serial gen), unpacking then patching (not good
if the person trying to 'crack' the program doesn't know how to unpack it), reversing
the unpacking routine and patching the packed file itself (I think its pretty hard not
to mention time consuming), and lastly, the best way, patching in program runtime.
This last method can be done by either PPatcher or by writing a small exe that will
patch in runtime using any condition we want (hooks and stuff).
Tools required 
Tools needed: SoftIce, ProcDump, and your favourite hexeditor.

Target's URL/FTP 
http://www.ImmortalDescendants.com

    You can find the ID crackme 5 on our site and if you look hard enough, you can also find my essay in text format, along with the CrackMe and a patch I made myself, so you'll see that this method actually works :)

Program History 

Nothing much to say about this program's history, it was created by Torn@do to train newbies to crack packed programs, and practice their key file reconstruction.

Essay 

The method I plan to show you here is a bit different, It does'nt involve coding of
a patcher, unless you call comparing a patched file and the original (and then generating
a patch), a patch :)

The steps involved:

1.  Finding what we wanna patch, and knowing the op-codes we want to replace, and their location.
2.  Finding the place where we jump to the Original Entry Point.
3.  Finding a suitable place in the original EXE to incorporate our 'patcher'.
4.  Inject the code inside to the location we found in step 2.

The method in general is based on the fact that the unpacking routine is sitting inside the EXE just waiting for us to use it. Why don't use it ?
Lets say that the program unpacks, and then we inject a snippet of code, just before we go to the original entry point (OEP), that will patch our now unpacked program. This way the program unpacks, and just before jumping to the application, it goes through the new  snippet which in turn patches the program. Under most circumstances, this is possible, since the process running has permission to write to his own code area of course.

For demostration purposes (I had to see if it can be pulled naturally :), I will use a target program. I chose the Immortal Descendants CrackMe 5, which was coded by Torn@do. I chose this crackme because I only need to show the basic principal behind this method, and this is a relatively small program, and its packed with ASpack, which is a farily common packer.

What we'll try to do is this. After we run the crackme, we see a button "About..". Clicking this button will pop up a dialog box with all kinds of information :)
Our goal will be to patch this dialog so when we click on the About button, nothing will happen, and we wanna do this with a simple patch.

Lets get to work then :)

Step 1 - Finding what we want to patch, location and op-codes

Ok, we wanna patch this dialog box, and there are several APIs for this. Instead of trying them all, lets find out what imports this program is using. Naturally, because this is a packed program, we can't look at the imports directly (with PE browse or a disassembly), so we'll need to go into the code and THEN find the imports. Here's a way to do it:

We need to find at least ONE API that this program uses. It does'nt matter which. In this case, I used a BP on WM_COMMAND when clicking on the About button, and then some tracing till I got to the crackme's code. Then I just looked inside for an API call. The tracing can be shortened, at least in Win9x by the following BP:

BPX k32thk1632prolog

Returning from this call (not an API), will bring us to something like this :

CALL [KERNEL32!K32THK1632PROLOG]
CALL [....]
CALL [KERNEL32!K32THK1632EPILOG]

This is a standard code inside windows, the middle CALL will take us to another code area which if we trace through (not very long), will call our program's Windows Procedure.
Of course, we need to get to this point by a BMSG as I described a bit earlier.
Once we are inside the code, and we locate an API, we'll do the following search (in my case I found a reference to ReadFile):

s ds:0 l ffffffff "ReadFile"

This will search the selector pointed to by DS from location 0 to the end, and look for ReadFile. The caps are imperative since the API names are case-sensitive in a search.
Once we land on the ReadFile string it should be around the data area of our crackme, for me I found it at 0041XXXX and something :)
I landed in a data area containing the names of ALL imported APIs by this program. I scrolled up and down a bit and looked for any reference to a dialog box API, and indeed I found the following name: DialogBoxParamA

The next obvious thing would be to put a BPX on it:

bpx dialogboxparama

Continue execution, and click the About button, and then we'll be back in SI. F12 (P RET), will take us to the calling routine, and there we'll have the following snippet of code:

023F:004035D0  6A00                        PUSH    00
023F:004035D2  68F0354000           PUSH    004035F0
023F:004035D7  A1B0EA4000         MOV     EAX,[0040EAB0]
023F:004035DC  56                            PUSH    ESI
023F:004035DD  6A67                       PUSH    67
023F:004035DF  50                             PUSH    EAX
023F:004035E0  FF1594124100      CALL    [USER32!DialogBoxParamA]
023F:004035E6  B801000000           MOV     EAX,00000001                               ; <<<< WE ARE HERE!!
023F:004035EB  5E                            POP     ESI
023F:004035EC  C21000                   RET     0010
023F:004035EF  CC                            INT     3
 

We landed after the call to the dialog. Now, if we'll look at the Win32API guide, we'll see that 5 parameters are being transferred to this API, and those are the 5 PUSH instructions we see above the CALL. If we wanna get rid of the dialog we'll need to skip those PUSHs and the CALL.
We'll assemble a little JMP instruction, type :

a 4035d0

Then we can enter the following code:

JMP 4035E6

As soon as we press Enter (assumind we have Code On), we'll see an EB14 instead of the 6A00 at memory location 004035D0. This is how our jump instruction looks like in memory.
Remember these two bytes, we'll wanna write them to this location (004035D0) when the program gets unpacked.
So far we've done nothing special. Its time to move to the next phase of the plan :)

Step 2 - Finding the jump to the original entry point (OEP)

Ok, now we have to find when our program actually gets unpacked. This is so that we'll know when we can safely patch the program.
Before we can even do anything, we need to be able to break with SI on the beginning of the loader code. For that we'll use ProcDump.
Miz wrote a great essay on how to manually unpack a program, and in there he uses ProcDump's PE Editor to change the .TEXT section's attributes from C0000040 to E0000020. This will tell the symbol loader that the .TEXT section indeed contains CODE, and that it will break on it. For those of you who have'nt read that essay, I suggest doing so now.

Finding the jump to the OEP may not be a trivial part. It ALWAYS requires some tracing into code, and might take a bit of time if you don't know the packer involved. A good guidline is to try to step over any calls and look at the SI window. Generally, when you'll see a few comments like:

Load32=..... and stuff like that, you'll know the program has been unpacked. Now comes a tricky part. You have to monitor all the registers (normally EAX) very closely and look for a potential OEP. In this case, the OEP was stored in EAX, and it was 00405500 if I'm not mistaken.
Here is a little snippet of code of how ASpack does this jump:

023F:0042606A  E822000000               CALL    00426091
023F:0042606F  E88A020000               CALL    004262FE
023F:00426074  E80F030000               CALL    00426388
023F:00426079  E836030000               CALL    004263B4
023F:0042607E  8B853E6F4400         MOV     EAX,[EBP+00446F3E]
023F:00426084  0385526F4400          ADD     EAX,[EBP+00446F52]
023F:0042608A  8944241C                  MOV     [ESP+1C],EAX
023F:0042608E  61                                POPAD
023F:0042608F  50                                PUSH    EAX
023F:00426090  C3                                RET
023F:00426091  80BDA570440000    CMP     BYTE PTR [EBP+004470A5],00
023F:00426098  741D                           JZ      004260B7

Notice those four CALLs there. After the fourth CALL we get the Load32 comment on the SI window, and then we know that we are green to patch. Right after that, the OEP is calculated inside EAX, and it is pushed on the stack, and using a RET, it actually jumps to the OEP, and hence the start of the program.
Ok, our problems begin here actually. Now that we know where the unpacking ends and the program begins, we need to inject a snippet of code that will patch our dialog box.
Now, since we want to put our code between the unpacking routine and that RET instruction, we'll have to be a bit creative. As you can see we don't really have room to work here because every single byte is being used somehow.
So this brings us to the next stage of the patch.

Step 3 - Finding a suitable place to inject our code to

So, what we know so far is how to patch and when we jump to the OEP. We'll now search for a place to inject our malicious code :)
Open up your favourite hex editor and look for the hex string : 8944241C6150C3

This hex string is in fact the opcodes of the instructions at address 0042608A to 00426090.
After we find this pattern (there is only one in the EXE), we'll need to find an empty place somewhere near it. I scrolled a bit down (a few sections), and I found the following place:

023F:00426500     0C 89 46 10 83 C6 14 8B-95 52 6F 44 00 E9 B8 FE      ..F......RoD....
023F:00426510     FF FF C3 AC AA 58 87 DB-00 20 00 00 08 00 00 00     .....X... ......
023F:00426520     00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 55          ...............U
023F:00426530     00 00 00 00 40 00 00 60-02 00 00 00 00 00 00 50          ....@..`.......P
023F:00426540     02 00 00 00 00 00 00 00-00 00 46 60 00 00 00 10          ..........F`....
023F:00426550     00 00 00 A4 00 00 00 C0-00 00 00 02 00 00 00 D0        ................
023F:00426560     00 00 00 1C 00 00 00 10-01 00 00 0A 00 00 40 28         ..............@(
023F:00426570     01 00 C0 1D 01 00 00 00-00 00 00 00 00 00 00 00         ................
023F:00426580     00 89 44 24 1C 61 66 C7-05 D0 35 40 00 EB 14 50       ..D$.af...5@...P
023F:00426590     C3 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00         ................
023F:004265A0     00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00         ................
023F:004265B0     00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00         ................
023F:004265C0     00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00         ................
023F:004265D0     00 00 00 00 00 00 00 00-00 00 6B 65 72 6E 65 6C       ..........kernel
023F:004265E0     33 32 2E 64 6C 6C 00 56-69 72 74 75 61 6C 41 6C     32.dll.VirtualAl
023F:004265F0     6C 6F 63 00 56 69 72 74-75 61 6C 46 72 65 65 00       loc.VirtualFree.

I saw this in the original file and I said : "what da ??? how can text be right after program code ???". Then I realized that somewhere before the text begins, the code ends. I decided to use those little zeroes we see in there. BTW, this is a dump from SI, not from my hex editor, and it is already patched, but lets leave that for now.
In short, I found a lot of zeroes I could turn into code. I loaded the program in SI and when I got to the loader routine, I displayed the code area in the data area:

d eip

I did this so I could look for the above text in the data window. Scrolling a bit down I did find it in the location it was supposed to be. I figured I found the place I could use to inject my code, but I had to make the program execute to that point somehow.
Here comes the great part.

When I decided on a place to inject my code (I chose 00426581, it was easy to locate in the hex editor as well because of the pattern just a line before it), I went back to the end of the packer routine. In order for the CPU to execute instructions at 00426581 I had to put a jump there, so I assembled the following instructions:

a 42608A, and then:

JMP 00426581

Notice that this instruction is 5 bytes long. I could'nt just put it instead of the RET instruction. So the solution was to copy the opcodes of all the instructions this last JMP overwritten and put them in the new location and then add my patching code.
Writing down the pattern: 894424106150C3
I will put my code between the 50 and the C3 (the C3 is the code for the RET instruction, that will take me to the program, and I don't want that before I patch!)
I assembled that pattern into 00426581:

MOV [ESP+1C],EAX
POPAD

and now I've added this line:

MOV WORD PTR [004035D0],14EB  << This will put EB14 at the to-be patched location :)

and finished with:

PUSH EAX
RET

The whole thing now looks like this: 8944241C6166C705D0354000EB1450C3.

What have I done here in fact ??
What I did was to relocate a small part of the end of the unpacking code so I could add my patcher's code to it. This has to be done in a place that you KNOW that the program won't ever touch.
What was left to do was to patch the original EXE file using a hex editor. We'll search for the end of the unpacker routine using this string: 894424106150C3
Once found, we'll change it to this: E9F20400009090 , which is the JMP 00426581 along with two NOPs right after it, just to make it look nice :)
The last step is to put the rest of the code where those zeroes were before. I scrolled down in my hex editor and I found a familiar pattern (look at offset 00426570). It was easy to see where 00426581 starts in my hex editor once I had that point of reference. I put the code in, which was (to remind you): 8944241C6166C705D0354000EB1450C3, and then I closed everything up.

After the patch was done , we'll check that it actually works by running to the program and clicking on the About button, which, if you followed my instructions, should now be shooting blanks :)
All was left to do is to generate a patch using any patch generator of your choice. That concludes this exercise, ladies and gentlemen :)

On this note, I used eGIS's MKpatch, in my opinion, the best patcher I've ever seen, simple, efficient, small and fast :)

Final Notes 
Conlusion to this whole method

This whole method, in a couple of words require some planning, but when its executed, its well worth it. What we're doing is find the OEP, and before we go into the main program, we put in another code snippet to patch what we want. If we have the room to just throw the code in , the better!. However if we don't as in my case, we'll have to look elsewhere and redirect the program to that location. When redirecting, always make sure you get the address right, because you'll have to patch the EXE file and put the code in the EXACT same place that the JUMP is pointing at, and this could be tricky. Again, a good way to do this is by finding a familiar pattern and writing it down (or remembering whichever you prefer hehehe). I hope you enjoyed this little execrise. The patch was 601 bytes long, pretty slick , no process patching and no nothing. If you have any questions you can email or ICQ me : lordsoth8@hotmail.com

lordsoth@immortaldescendants.com

ICQ # 5178515

Greetings:

Torn@do, Lucifer48, Jeff, BJanes, MisterZ-, +Sandman, Volatility, alpine, Miz, and all the other great crackers out 
there including +Fravia, +ORC, +Frog's Print and the others I don't remember.
Of course if I left anyone out, I'm sorry, I'm just in a big hurry.
Ob Duh 
This crackme can be downloaded for free of course, so you can't really steal it ;-)

You are deep inside fravia's page of reverse engineering, choose your way out:
redhomepage redlinks redsearch_forms red+ORC redhow to protect redacademy database
redreality cracking redhow to search redjavascript wars
redtools redanonymity academy redcocktails redantismut CGI-scripts redmail_fravia+
redIs reverse engineering legal?