Killing Nagscreens
 
1. Kill the DialogBox-Call


In this tutorial, we will learn how to defeat nagscreens. We will see that there are different ways to do that.
Our target is editor.exe.

Get it here!

It has a nagscreen that stays there for 10 seconds :(
Let's find out how we can kill it :

The nagscreen, is in fact a DialogBox that is called before displaying the real program.
To do that, the API DialogBoxParam is used. So just search for the API in your import table (eg in W32DASM).

If you find more than one entry, and you don't know which one is the nagscreen, you can always check it in Soft Ice. (bpx DialogBoxParamA)

We find it here :


* Reference To: USER32.SendDlgItemMessageA, Ord:0000h
                                  
00401411 E8408D0000  Call 0040A156
00401416 6A00        push 00000000	;Push init value
00401418 682B124000  push 0040122B	;Push address of dialogbox-procedure
0040141D 53          push ebx		;Push handle owner


* Possible Reference to Dialog: DialogID_0384 
                                  
0040141E 6884030000  push 00000384	;Push INT Resource
00401423 6A00        push 00000000	;Push dialogtemplate


* Reference To: KERNEL32.GetModuleHandleA, Ord:0000h
                                  
00401425 E8F28B0000  Call 0040A01C	;Call Modulehandle (to get the handle)
0040142A 50          push eax		;Push handle DialogBox


* Reference To: USER32.DialogBoxParamA, Ord:0000h
                                  
0040142B E8C68C0000  Call 0040A0F6	;Call the nagscreen
00401430 E9A8000000  jmp  004014DD
		

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


00401435 837D1001    cmp dword ptr [ebp+10], 00000001
00401439 0F849E0000  je 004014DD

Now let's grab win32.hlp (you can find it in the Reference part of this site) and search for DialogBoxParam :

int DialogBoxParam

 (
HINSTANCE hInstance, // handle to application instance
LPCTSTR lpTemplateName, // identifies dialog box template
HWND hWndParent, // handle to owner window
DLGPROC lpDialogFunc, // pointer to dialog box procedure
LPARAM dwInitParam // initialization value
);

So if we reverse the code above to c++ syntaxis we have the following :

DialogBoxParam (GetModuleHandle(NULL),NULL,MAKEINTRESOURCE(IDD_NAG), hwnd, Nag_Routine);

All we have to do is NOP the entier code for the call out. Fire up your hexeditor, and change the offset A16 till offset A2F in 90's. (If you don't know how to find an offset or how to nop, read some other tutorials on this site (newbie rated))

Run editor.exe, the nag is gone! :)


Now what exactly did we do? We erased the code that calls the dialog. So, the code of the nag is still there, but it's not used anymore :)

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