Make a standalone patch
 
1. General Theory


Once you patched a program you cracked, you might want to share it. Instead of uploading the entire executable, you can make a small patch that changes the neccessary bytes.

Now how are we going to do that?

=> First we have to look for the file we have to patch. Most patches suppose that the file is in the same directory.

=> If it's there, we have to open it.

=> Next we should check if it's the exact same file as the one we cracked. We could eg. check the size, or some random bytes, or even better, the bytes we are going to patch.

=> If it is the same, we can do the neccessary adjustments : )
Put the filepointer on the right position, and write the new opcodes to it.

=> Close the file, and give a message about the status.

 

Take a program you just cracked, or use this example I will use.
Let's code this...

2. API Theory


What API's will we need to code this?

First of all, we will have to open the executable. The suitable API is :

HANDLE CreateFile(

LPCTSTR lpFileName, // pointer to name of the file
DWORD dwDesiredAccess, // access (read-write) mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
DWORD dwCreationDistribution, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy
);

This API is used for opening, or creating a file.
dwDesiredAccess should be 'GENERIC_WRITE' because we want to write to the file.
dwShareMode = 'FILE_SHARE_WRITE'
dwCreationDistribution = 'OPEN_EXISTING' We only want to open a file that is there. If it's not there, the function will fail, and we can give an Error Message.
Check your WIN32.HLP for details. If you don't have this API library, get it in the Reference section.
As you can see the API returns the handle of the file we requested. We need this handle for the next step : writing to the file.

BOOL WriteFile(

HANDLE hFile, // handle to file to write to
LPCVOID lpBuffer, // pointer to data to write to file
DWORD nNumberOfBytesToWrite, // number of bytes to write
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O
);


We will use this API to write the two bytes to the file (in the right place, of course :)
The handle hFile is the one CreateFile has returned.
3. The Target


The Target is crackme5.exe, let say we don't find a valid serial, and we want to patch it.
Of course you are a good cracker : ) and you found the bytes to patch quickly.
Here they are :

Offset 53Fh : 74h, 15h -> 90h, 90h

That's all the information we need : )

4. The Code
 

2. Skip the dialogbox-procedure


Sometimes, the program checks if the nag is called. That way the above methode will fail. (eg PaintShopPro)
Another easy way to bypass the nag, is let the program call the dialogbox, and then end the diaologbox immediatly.

How? Let's find out :

How can we find the dialogbox procedure?
Easy, the address was used by DialogBoxParam! (address 401418 : push 0040122B)
Ok, jump to 40122B code in W32Dasm.

We are here :

 
0040122B 55		push ebp
0040122C 8BEC		mov ebp, esp
0040122E 8B450C		mov eax, dword ptr [ebp+0C]
00401231 2D10010000	sub eax, 00000110
00401236 740A		je 00401242	//WM_INITDIALOG ?
00401238 48		dec eax
00401239 7433		je 0040126E	//WM_COMMAND ?
0040123B 83E802		sub eax, 00000002
0040123E 741A		je 0040125A	//WM_TIMER ?
00401240 EB41		jmp 00401283


* Referenced by a (U)nconditional or (C)onditional Jump at Address: 00401236(C)

00401242 6A00		push 00000000
00401244 FF35E8B04000	push dword ptr [0040B0E8]	//Push Timervalue.
0040124A FF35ECB04000	push dword ptr [0040B0EC]
00401250 FF7508		push [ebp+08]
	

* Reference To: USER32.SetTimer, Ord:0000h
 
                                  
00401253 E80A8F0000	Call 0040A162	//Call SetTimer
00401258 EB2D		jmp 00401287	//We can change this jump


* Referenced by a (U)nconditional or (C)onditional Jump at Address: 0040123E(C)


0040125A 6A01		push 00000001
0040125C 6A01		push 00000001
0040125E FF7508		push [ebp+08]


* Reference To: USER32.GetDlgItem, Ord:0000h

                                  
00401261 E8AE8E0000	Call 0040A114
00401266 50		push eax


* Reference To: USER32.EnableWindow, Ord:0000h

                                  
00401267 E8968E0000	Call 0040A102	//Enable the button
0040126C EB19		jmp 00401287


* Referenced by a (U)nconditional or (C)onditional Jump at Address: 00401239(C)


0040126E 668B5510	mov dx, word ptr [ebp+10]
00401272 66FFCA		dec dx
00401275 7510		jne 00401287
00401277 6A01		push 00000001
00401279 FF7508		push [ebp+08]


* Reference To: USER32.EndDialog, Ord:0000h

                                  
0040127C E8878E0000	Call 0040A108
00401281 EB04		jmp 00401287
	


We notice the SetTimer API in the WM_INITDIALOG.

If we want to exit this procedure, we have to call the EndDialog Function (40127c).
We can easily change the jump at address 401258 'jmp 401287' into 'jmp 401277'
That way, we start the dialogbox, and we close it before it is displayed :)
This requires a patch of only one byte. change 'EB 2D' in 'EB 1D' (This changes the jump to jump 10h bytes less far).

Run the program, no nag ! :)

3. Reduce the TimerValue

As you can see in the above code, When the timer is set, we have some variable that are pushed on the stack for it. One of them (00401244) is the time (in millisec.)

How do we know that? Try to figure this one out yourself! Use win32.hlp !

push dword ptr [0040B0E8]

To know what value is in there, we press the 'Data Hex'-button in W32Dasm and search for 40B0E8

 
0040B080 2D 20 43 6F 70 79 72 69	- Copyri
0040B088 67 68 74 20 31 39 39 36	ght 1996
0040B090 20 42 6F 72 6C 61 6E 64	Borland
0040B098 20 49 6E 74 6C 2E 00 00	Intl...
0040B0A0 00 B0 40 00 48 B0 40 00	..@.H.@.
0040B0A8 48 B0 40 00 6C B0 40 00	H.@.l.@.
0040B0B0 01 00 00 00 00 00 00 00	........
0040B0B8 E4 14 40 00 80 6A 40 00	..@..j@.
0040B0C0 AC 6A 40 00 00 00 00 00	.j@.....
0040B0C8 08 C4 40 00 00 4C D2 40	..@..L.@
0040B0D0 00 E4 D2 40 00 00 01 00	...@....
0040B0D8 00 00 00 00 00 00 00 00	........
0040B0E0 00 00 00 00 00 00 00 90	........
0040B0E8 10 27 00 00 01 00 00 00	.'......  <-- Here !
0040B0F0 4D 79 57 69 6E 64 6F 77	MyWindow
0040B0F8 43 6C 61 73 73 00 00 00	Class...
0040B100 00 00 00 00 54 65 78 74	....Text
	

Since Intel uses the 'Little Indian' way, our dword value is = 00 00 27 10 h = 10000 decimal

10000 millsec = 10 sec This is the value we want to change !

Find the value in your hexeditor, and change it too 00 00 00 00 = 0 sec. (or any other value you want)

Now run the program, we see that the nag appears but the 10 second delay is gone... :)


I showed you three ways to kill a nagscreen, but there are many more ways... To kill a nagscreen the 'right way' you should also remove the DialogBox in the Resource section. This reduces the file size :) But this is beyond the scope of this tutorial. If you are interested in more information about this, or if you have questions about this tutorial, mail me at Detn@hotmail.com

If you manage to remove the NAG, you have a fast and small texteditor for free! :)

Greetings,

Detten
Detn@hotmail.com