FUNCTIONS RE-ENABLING ON COOL EDIT 2000 Tutorial by UmE Introduction: today a lot of programs are proposed to the users as Demo versions with some functions disabled. This means that you see in the pop up menus some grayed voices that you can't use; normally you can enable this items with the API function EnableMenuItem but once you have enable them they not work the same. In this tut I'll try to show you how you can make a demo program work properly! Necessary tools: SoftIce 3.24 or better. Program description: Cool Edit 2000, cool2000.exe, 3.420.160 bytes. Let's start!!! Step 1: when you run the program a dialog box appear telling you which function you want to enable during your work session. This means that not all the functions are enabled when you use this software, but means also that the program contains the routines for the disabled items but switch them according with the choice you made at the startup. Our target is to make them work always! For example choose the option 3 and 4 tha t give you some functions as Filters, Noise reduction, Amplify, Envelope....but exclude the Save functionality. In this tut I'll show you how to re-enable the save function when it's disable but remember that you can apply the same procedure to all the other functions. First of all open a sample file and the notice that the Save and Save As items in the File menu are grayed. We want to enable them so open SoftIce (Ctrl+D) and place a break point on the EnableMenuItem function (bpx enablemenuitem). As you know the EnableMenuItem function has the following structure: BOOL EnableMenuItem ( HMENU hMenu // handle to menu resource UINT uIDEnableItem // menu item to enable, disable or gray UINT uEnable // menu item flags ); In ASM you got: PUSH uEnable PUSH uIDEnableItem PUSH hMenu CALL [KERNEL32!EnableMenuItem] For us is important to know which flags the program pass to this function in order to enable or disable a certain item. We also know that: uEnable=0 the item is enabled Ok, once you're out from SoftIce, click on the file menu and you'll be in SoftIce again. Press F11 to return to the code snippet that has called the function and you'll land here: :00411580 6A01 push 00000001 <-uEnable flag :00411582 6875010000 push 00000175 :00411587 56 push esi :00411588 FFD3 call ebx <- Call EnableMenuItem This is not the call that we're interested in because it passes a constan value to the function (1). If you press Ctrl+D the program continue to execute the EnableMenuItem function to enable or disable the various items. During this process you can notice that the EBP register holds the uIDEnableItem that has just been processed by the function so you can let the program executes the various EnableMenuItem functions until you see EBP=047E. In fact this is the ID for the Save As menu item. You can find the ID of the menu item dissassembling the file cool200.exe with W32Dasm and looking on the Menu Information section at the beginning of the listing. Once you notice EBP=047E press F11 and you'll be here: :004128A5 668B440C1C mov ax, word ptr [esp+ecx+1C] :004128AA 50 push eax :004128AB 55 push ebp :004128AC 56 push esi :004128AD FF15D0535600 Call dword ptr [005653D0] <-EnableMenuItem As you can see eax (uEnable flag) depends from the value of ESP and ECX. We can try to overcome this situation by changing the "mov ax, word ptr [esp+ecx+1C]" instruction with "mov ax, 0000" (we need also a nop after this instruction because it cover 5 bytes and the first instruction cover 6 bytes). To do this place a bp on 004128A5 address (bpx CS:004128A5) and then edit it as I've just explained(e 004128A5).In this manner the program will pass always 0 to the EnableMenuItem function. Disable all breakpoints (bd *) and exit from SoftIce. Click on the file menu again and you'll see that all the items are enabled. Groovie!! Now if you click on the Save As item the program will close itsel!! What's happened? Follow me and you'll see!! Step 2: now we've enabled the various menu items and now we want to make them work. As you know when you click on a menu item the program sends a WM_COMMAND to the system that process it according with ID associated at the menu item selected. Open SoftIce and type "hwnd". This instruction return the handle of the various windows open on your desktop. You can see in SoftIce the following parameters: Window Handle hQueue Sz QOwner Class Name Window Procedure We're interested to know the window handle of the main window of Cool Edit because we want to intercept the moment when the WM_COMMAND is generated and then observe what's happen from that point. So you'll see: Window Handle hQueue Sz QOwner Class Name Window Procedure 0414(1) 1087 32 COOL2000 COOL2000SS 32CF:0000051E Now place a breakpoint on message WM_COMMAND (it needs also the handle of the window): bmsg 0414 WM_COMMAND Exit from SoftIce and click on the Save As menu item.....you're in SoftIce again! Remember that we want to find a piece of code where the ID of the menu item selected is processed: we can find this point on the source code of the program we're reversing because the programmer can't modify a system dll and adapt it to his program! Place the following breakpoint: bpx k32thk1632prolog (for the reason of this choice I remind you the Lord Soth tutorial on function disabled re-enabling that you can find at www.ImmortalDescendants.com) and press Ctrl+D to exit SoftIce. You'll be shooted in SoftIce again; press F11 and you'll be in this point: CALL [KERNEL32!K32Thk1632Prolog] CALL [.....] <-This is very important!! CALL [KERNEL32!K32Thk1632Epilog] Step into the call after [KERNEL32!K32Thk1632Prolog] with F8 until you reach the cool2000 code. Now pay attention to the values of the various registers. Continue to step until you reach this point: :004C896D 8B8C24EC010000 mov ecx, dword ptr [esp+000001EC] :004C8974 8B9424E8010000 mov edx, dword ptr [esp+000001E8] :004C897B 51 push ecx :004C897C 52 push edx <- 1 :004C897D 57 push edi <- 2 :004C897E 50 push eax <- 3 :004C897F FF15C4545600 Call dword ptr [005654C4] <- 4 1- Push edx into the stack (edx=111). This is the hex code of the WM_COMMAND message. 2- Push edi into the stack (edi=047e). This is the ID of the Save As menu item 3- Push eax into the stack (eax=0414). This is the window handle of COOL2000. 4- Call the SendMessageA function. This function send the WM_COMMAND message into the message queue of the system. In the next step this message will be processed by the DefWindowProcA function. Step into (F8) the SendMessageA function until you reach the cool200 code again because is here that we will find our critical point. You'll reach the code here: :00422900 55 push ebp :00422901 8BEC mov ebp, esp :00422903 83E4F8 and esp, FFFFFFF8 :00422906 B854140000 mov eax, 00001454 :0042290B E890FE1100 call 005427A0 :00422910 A124AE5800 mov eax, dword ptr [0058AE24] :00422915 53 push ebx :00422916 56 push esi Now you can notice that EDI=047E so continue to trace until you'll se the program use EDI. From this point our ID will be compared with various constants to determine which ID we've selected. In fact after a few traceing we'll find: :0042C389 81FF7E040000 cmp edi, 0000047E <-Yeah!! Our ID!! :0042C38F 0F8738070000 ja 0042CACD :0042C395 0F840A080000 je 0042CBA5 <-Jump to 0042CBA5 At 0042CBA5 we find: :0042CBA5 6A01 push 00000001 :0042CBA7 E8C4AB0600 call 00497770 :0042CBAC 83C404 add esp, 00000004 :0042CBAF 85C0 test eax, eax :0042CBB1 7511 jne 0042CBC4 The call at 0042CBA7 choose if the selected ID has to be processed or thrashed. In fact it returns eax=0 for thrash the ID and eax=1 for execute the ID. In our case eax=0 and the program jumps to the ExitProcess function. So change jne in jmp and the Save As dialog will appear!! The function now works properly!! The procedure I've described in this tut can be applied to the other disabled functions and many crippled programs. I hope you've enjoyed during this tut! Bye! UmE Contact me at: ume15@hotmail.com