A KeyGen

Making Code_Insides Crackme #5..Self Keygen
 

by Harlequin

  March  2001

 

  

Tools Used:

 
 W32Dasm V 8.93
Softice
 Text/Hex Editor

 

 

Introduction

Code_Insides crackme #5 is a name/company/serial protection. Get it at crackmes.cjb.net

I am not going to go into how the serial is generated I would like to leave you something to do :-) What this essay will do is show you how to turn the crackme into its own keygenerator.

The Essay

Ok I actually only used Softice to crack the program but if we want to make it into its own keygen we are going to need a deadlisting.

Code_Inside has once again played around with the PE headers a little so that W32Dasm will not disassemble it so we have to correct them. In a standard PE header the Optional headers are E0h bytes long and this is what W32Dasm expects, in this program though you will notice that they are F0h bytes long.
How do you notice??? :-) well if it is not immediately apparent you check out the word value 20 bytes into the PE header. Another option is to open the program with Quickview and check the optional header size.

To correct the headers delete the extra 16 bytes from before the section headers and to correct the file size insert 16 blank bytes after the section headers. Update the optional header size at offset 94h to E0h and we are done. While we are here though change the section attributes to E0000060h for each section so that W32Dasm will recognize them as code.

Disassemble the program and we see some weird code something is not as it should be. Go to the program entry point and the code here looks a little better. If you check out the code you will see that is is altering the rest of the program code in memory. What it does we need not concern ourselves with just scroll down until we reach this:

:004012F3 B800104000              mov eax, 00401000
:004012F8 FFD0 call eax
:004012FA C3 ret

This is where the program jumps to the now decoded code. Edit the call to jump to itself by changing it to EBFEh and run the program. It goes into the eternal loop, load procdump and select dump partial, accept the default values of 400000h and 3000h and dump the program. Open your dumped program in ProcDump PE editor, we have a dumped program but if we run it the decode functions will destroy our code so to avoid running them change the entry point to 1000h.

We are done and now have a deadlisting and a decoded file we can begin our work.

As I said I am not going to go into the details of how the serial is generated you can do that yourself there is a check we need to take care of though.

:00401155 2BF7                    sub esi, edi
:00401157 39CE cmp esi, ecx
:00401159 7302 jnb 0040115D
:0040115B EB2D jmp 0040118A

This little bit of code effectively checks to see if the serial number we entered is bigger than the length of the name and the company combined. This is not exactly true as the name company length is derived from the number of 31h values in the matrix and as one of these values could be overwritten the total length could be less than the actual length. For our purposes though this is not important we just want to carry on no matter the serial length so:

:00401155 2BF7                    sub esi, edi
:00401157 39CE cmp esi, ecx
:00401159 9090 nop nop
:0040115B EB2D jmp 0040118A

Next we need our serial as generated by the program. A bpx:

bpx 40120A DO "d esi"

will reveal the real serial and where it is checked:

:00401208 8B07                    mov eax, dword ptr [edi]
:0040120A 8B0E mov ecx, dword ptr [esi]
:0040120C 85C0 test eax, eax
:0040120E 743E je 0040124E
:00401210 3BC1 cmp eax, ecx
:00401212 7402 je 00401216
:00401214 EB08 jmp 0040121E

The jmp at 401214h is only taken if we have a bad serial number so this seems like a perfect place to re-direct the code.

First though we want to place the real serial number in the serial edit box to do this we need the SetDlgItemTextA API which is not included in the program so we must add it.

At offset 1C90h add the following:

User32.dll
two zero bytes
SetDlgItemTextA
1 zero byte
Array1 = Address of 1st zero byte after User32.dll in reverse (9A1C0000h)
zero dword
Array2 = Address of 1st zero byte after User32.dll in reverse (9A1C0000h)

Now we need to add our entry to the import table so at offset 1CECh enter:

Address of Array1 in reverse (AC1C0000h)
zero Dword
zero Dword
Address of User32.dll (901C0000h)
Address of Array2 in reverse (B41C0000h)

Now we have to update the PE header to point to our new import table so at offset: 100h change the import table address to our new address:
EC1C0000h
and update the import table size to take account of our added 5 dwords so add 14h to the 38h at offset 104h:
4C000000h

Finally we need to update the .idata section as the import table starts on the boundary so at offsets 1ACh and 1B4h:
EC1C0000h

We need not worry about the size of the idata section (rdata) as the current 300h bytes more than cover it.

So we have our new API now we need to make it do what we want, we need to enter our new code. I make a quick note of what we want to do so that I can gather the relevant information as follows:

  1. jmp our new address entered at 00401214h

  2. push real serial address entered at 0040127Dh
  3. push id of serial edit box
  4. push dlghnd
  5. call [secondarray]
  6. jmp back to normal code

1. I decide to overwrite our old decoding functions so the new code will go at 0040127Dh
2. Real serial address will simply be esi
3. Serial editbox ID = 0000CCCCh
4. This one is a little more difficult. To find it I placed a bpx GetDlgItemTextA clicked check and found out what this value was. I then placed a bpx 0040120Ah and when softice broke did a 'd esp' and searched for our value. I found it at esp+4 of course we have just pushed two dwords onto the stack so we have to take account of this. Our value is now at esp+C
5. Secondarray address is 00401CB4h
6. We jump back to where we would have left off at 0040121Eh

Thats all there is, now we load the process into W32Dasm and click Patch code. Type in our new instructions at the relevant addresses and save it. If you have my W32Dasm Disassembled patch you can simply click Make Permanent if not copy the bytes from the patch window and hand edit them into the file :-) (You can get my W32Dasm patch at protools (protools.cjb.net) under the W32Dasm section)

Thats all there is to it our new code will look like this:

1.
:00401159 90 nop
:0040115A 90 nop
2.
:00401214 EB67 jmp 0040127D
3.
:0040127D 56 push esi
:0040127E 68CCCC0000 push 0000CCCC
:00401283 FF74240C push [esp+0C]
:00401287 FF15B41C4000 call dword ptr [00401CB4]
:0040128D EB8F jmp 0040121E
 

In Conclusion 

So there you go, Code_Inside asked for a Keygen this was the easiest and quickest way saves writing my own program :-)

You should take the time to look at the serial generation routine too it is a little different and interesting

 

Final Notes

Thanks go to:

Muad'dib for the crackmes site (crackmes.cjb.net)

Code_Inside for this little crackme

 

 

Essay by:      Harlequin
Page Created: 7th March 2001