Reversing the Hell out of Muad'Dib's ReverseMe1 - Calling functions dynamically - By CaptRE ---------------------------------------------------------------- Publisher's Note: Muad'Dib's ReverseMe can be found here: www.immortaldescendants.org/database/muad/rm1.zip The reversed exe from this essay can be found here: www.immortaldescendants.org/database/muad/solutions/rm1-rev.exe ---------------------------------------------------------------- This is going to be my first tutorial. I hope it's worth reading for y'all. I like the ReverseMe's.... But, wouldn't it be very easy to just do the thing we're asked for: make the exit-button work? Yes, it would,. Therefore i'll reverse a bit further... ---------------------------------------------------------------- Tools: ---------------------------------------------------------------- This is gonna be a tutorial where all the changes are directly made with HIEW. Also W32Dasm may be a great help. ---------------------------------------------------------------- Goal: ---------------------------------------------------------------- 1. Make the messagebox let you prompt for "Wanna see my AboutBox before exiting?" with "Yes/No" buttons and a Questionmark Icon. 2. Exit the program on "No" 3. Show the AboutBox on "Yes" with a special Icon and our own Text 4. Exit on klicking "OK"... ---------------------------------------------------------------- How to do it: ---------------------------------------------------------------- MY GOD! What have I said.. Is it too tough to be done? Don't know, but let's try it out... The first thing is that when we deadlist, the Shel32.dll (where the AboutBox-Function is at) isn't loaded. This means it has to be loaded, for otherwise we can't execute the Functions we need. This means we must the "GetProcAddress" Function to dynamically retreive the address of the Functions. We can type the "GetProcAddress" over the "GetModuleHandleA" in the importtable (Address 402084, Offset 684). But how do we get the handle to "KERNEL32.DLL"??? There goes "ExitProcess", overwiritten by "LoadLibraryA" at Address 402076, Offset 676. Now we have 2 functions to get dynamically all the Handles and Functions we need! You can even see those changes when deadlisting the Exe-file. The ExitProcess is a function that will be gone forever, but the EndDialog-function will do the Exit-Job just fine. ---------------------------------------------------------------- "On-Paper" coding: ---------------------------------------------------------------- Next step: make a list of all the Functions we need. * ShellAboutA - Shell32.dll * ExtractIconA - Shell32.dll This means that we need the String "SHELL32.DLL" for the LoadLibrary Function. What other Strings do we need? * The strings of the 2 needed Functions "ShellAboutA" and "ExtractIconA" * The Title of our AboutBox: "See what you can do!!" * The first Textline in the AboutBox: "By CaptRE". HEY... what do I see our Win32.hlp-file has to say about ShellAbout? "Points to text that the function displays in the title bar of the Shell About dialog box and on the first line of the dialog box after the text "Microsoft Windows" or "Microsoft Windows NT." If the text contains a "#" separator, dividing it into two parts, the function displays the first part in the title bar, and the second part on the first line after the text "Microsoft Windows" or "Microsoft Windows NT". So we'll make it one String then: "See what you can do!!#By CaptRE" * The Title of our MessageBox: "WannaSeeAbout?" * The text of our MessageBox: "Do you want to see my AboutBox before you leave?" Now find a place to insert those Strings. I decided to take the .Data-Section. I calculated (F8/F6 in Hiew) Offset+VirtSize=800+3C=83C. That's a free Space... but after some Trial and Error I found out that I had to leave a few spaces (that's Zero's in Hex!), for at execution my first String was beeing crippled. I started at 00403041 (Offset 841) and inserted my Strings: Notice: you have to leave a Space (thats NOT a Spacebar, but 2 Zero's in Hex!) between each String. Now let's go to work! ---------------------------------------------------------------- Make the changes: ---------------------------------------------------------------- Change the messagebox into our own Title and Text with a YesNo button and a Questionmark Icon. 1. Search in the appropriate Header-file or API-viewer the Values for MB_YESNO + MB_ICONQUESTION (Public Const MB_YESNO = &H4&, Public Const MB_ICONQUESTION = &H20&) So the Value needed is 20h+4h=24h. 2. Change the Push at Offset 43E into PUSH 024 3. Change the Push at Offset 440h into PUSH 403075 = "WannaSeeAbout?" (Don't know how to get this Address? Very simple: in Hiew change to Hex-Mode (F4/F2) then search for the text we've just added. Put the cursor on the first Character of the String and read the Address in the Titlebar of Hiew!). 4. Change the Push at Offset 445 into PUSH 403084 (Text: "Do you want...") 5. Save with F9 Done! Next! ---------------------------------------------------------------- Some more "On-Paper" coding: ---------------------------------------------------------------- Redirect the original call to GetModuleHandleA: 1. Let's see where we can put our new code. In Hiew: F8/F6. In the .TEXT-section we can insert it at Offset+VirtSize=400+8A=48A. 2. Jump from original to new Code. A good place to do this is where the call to the MessageBox is made. 3. Change the call at offset 402 into the call to "LoadLibraryA". See your Win32.hlp-file: the two functions are almost identical! 4. At the new code location: call the MessageboxA function 5. Yes/No clicks are saved in EAX. Check if "Yes" or "No" is pushed 6. If No: stop program 7. Push string "Shell32.dll" 8. LoadLibrary "Shell32.dll". The handle of Shell32.dll will be returned in EAX. 9. Push string "ExtractIconA" 10. Push the pointer of Shell32.dll (=EAX) 11. Call GetProcAddress. The returnvalue will be in EAX, that's the pointer to the function "ExtractIconA". 12. Push indexnumber of the icon. Let's take number 35 (map with tools). The hex-value has to be pushed, i.e. 32. 13. Push string "Shell32.dll" 14. Push instancehandle. Let it be 0. 15. Call ExtractIconA. That is: call EAX (remember?). 16. The returnvalue will be in EAX. Save the Returnvalue (Handle of the Icon) into a Buffer, otherwise it will be overwritten when calling the ShellAboutA Function. Which Buffer?? The Buffer as used in the original code of course! Look at Offset 407... 17. Push String "Shell32.dll" again 18. Call "LoadLibrary" again The returnvalue will be in EAX. 19. Push the string "ShellAboutA" 20. Push the pointer of Shell32.dll (=EAX) 21. Call "GetProcAddress" 22. Push the iconhandle. We saved it into a buffer in pt.15, so: push this buffer! 23. Push the string with my name. I use this string twice (see pt 23). 24. Push the string with the title and first line of text 25. Push the handle of the parent window. Let it be 0. 26. Call "ShellAboutA" (=EAX). 27. Jump to original code to stop the program. LET's DO IT! ---------------------------------------------------------------- Insert the code: ---------------------------------------------------------------- At Offset 402: CALL 00000046C 0000048A: E8F5FFFFFF call 000000484 MessageBoxA 0000048F: 50 push eax Save result of the click 00000490: 83F807 cmp eax,007 ;" " Is it NO? 00000493: 74C5 je 00000045A It is! Exit! 00000495: 68B6304000 push 0004030B6 ;" @0¶" "Shell32.dll" 0000049A: E8CDFFFFFF call 00000046C LoadLibraryA 0000049F: 68C2304000 push 0004030C2 ;" @0Â" "ExtractIconA" 000004A4: 50 push eax Pointer shell32.dll 000004A5: E8C8FFFFFF call 000000472 GetProcAddress 000004AA: 6A23 push 023 Index Iconhandle in Shell32.dll 000004AC: 68B6304000 push 0004030B6 ;" @0¶" "Shell32.dll" 000004B1: 6A00 push 000 InstanceHandle 000004B3: FFD0 call eax ExtractIconA 000004B5: A338304000 mov [000403038],eax Save IconHandle in buffer 000004BA: 68B6304000 push 0004030B6 ;" @0¶" "Shell32.dll" 000004BF: E8A8FFFFFF call 00000046C LoadLibrary 000004C4: 6841304000 push 000403041 ;" @0A" "ShellAboutA" 000004C9: 50 push eax Pointer Shell32.dll 000004CA: E8A3FFFFFF call 000000472 GetProcAddress 000004CF: FF3538304000 push d,[000403038] Iconhandle 000004D5: 6866304000 push 000403066 ;" @0f" My Name-string 000004DA: 684D304000 push 00040304D ;" @0M" Title & First line-String 000004DF: 6A00 push 000 ParentWindow Handle 000004E1: FFD0 call eax ShellAboutA 000004E3: E972FFFFFF jmp 00000045A Exit! ---------------------------------------------------------------- Final notes: ---------------------------------------------------------------- I know I could have made some JUMPS so that the repeated code for getting the pointer to Shel32.dll isn't redundant, but I kept it simple for educational purpouses. The same thing for the strings used in the MessageBox: I could have overwritten the original strings to keep the space needed minimized. Also I could have loaded the ExitProcess function to make a clean exit..... Look at the code... Think.... Right!! You've got total controll of every program when implementing this dynamic calling of functions!! Have Fun and Learn..... CaptRE CaptRE@Hotmail.com