This is part 4 of ASM Injection: The Annoying Messagebox. – https://twitter.com/ro0ted/
I will be using Hex Calculator which is real program for this tutorial.
So load it in Olly:
We will be using the bookmark plugin to navigate through the code.
so first we want to bookmark the entry point:
So right click and go to bookmark, insert bookmark, a messagebox will appear.
Let’s name it EP:
Now right click>Bookmark> Go to Bookmarks to view your bookmarks:
This window will appear:
our goal is to find the WndProc or DlgProc callback functions so that we can trap the Windows message that tells the window to close and put our own code in it.
Right click search for> All Intermodular Calls:
This window appears:
We first look for RegisterClassA or RegisterClassExA, and if it’s there, as it is in this case, we can assume that this app uses a window for its main screen as opposed to a dialog box:
Should be note: If there is no RegisterClassA then we would look for DialogBoxParamA and go that way instead.
when a window is registered, the address for the message handler callback will be pushed onto the stack as one of the arguments. To find this we go up a line or two and look for the ubiquitous PUSH EAX:
Main message is located at 401280 let’s go there:
Seeing the Switch (cases 2…111) means that this is the message handler. I will go ahead and set a bookmark here as well called “Message Handler”.
Now place a BP at address 401292 as this is our first conditional jump:
Olly will now pause when any messages from Windows comes through our handler. (You will notice that if you move the mouse over the HexCalc window Olly will pause. This is because a mouse event has been passed into the handler. If this happens, just F9 until Olly is running again.)
Looking at the compares we can see that the windows message ID will be in EBX (this will not always be the case). We can see that EBX contains 0×20:
F9 several times until we get to the ID we want, 0×10.
They will be such things as WM_SETFOCUS, WM_MOUSEBUTTONDOWN etc. Keep pressing F9 until EBX contains 0×10:
These are the message IDs I went through to get to 0×10 (yours may be different): A0, 2A2, 21, 46, 1C, 86, 06, 281, 282, 07, 215, AE, 112.
OK, our WM_CLOSE message has come through. Now let’s single step and see what it does. First, it hits the jump at address 4012AC and will jump.
This JNZ points to the default case of the switch/case statement, basically the call to DefWindowProcA that tells Windows to handle this message for us. I am going to go ahead and put a bookmark at address 4012AC called “Jump to Code Cave”. So right click > Follow, we come here:
place a bookmark at address 401347 called “Normal Message Return”, I now hit F9 a couple more times and you will see the cleanup messages come through. These include 90, 46, 47, 281, 282, 2, 82. The window will actually close when the 02 message comes through. This is the message for WM_DESTROY. The app will then terminate.
Now we need a code cave scroll to the end of the code look for a bunch of zeros
Anyone of these DB 00 can be your start of the address for your code cave, I will select
00403EOD and bookmark it calling it Code Cave. These are my bookmarks now:
Let’s go ahead and start coding our cave. The first thing I want to do is copy EAX to ECX so I can modify it:
MOV ECX, EAX
I then want to clear everything but the lowest byte so that I can make ECX equal to the message ID only:
AND ECX, 0FF
When typing the’FF’ I must put the zero in front of it as Olly doesn’t like when you enter hex values that start with a letter without the initial zero. What this statement does is clears everything in ECX except the lowest byte to zero. So if EAX was FFFFEF10, meaning that AX held the ID of the WM_CLOSE message, ECX would equal FFFFFF10, and after the AND statement ECX would equal 00000010. Now I want to compare this ID with 0×10:
CMP ECX, 10
and if it’s not 10, we just want to jump where we would have initially jumped. Looking up at address 4012AC, we can see that we would have jumped to 401347. This is the beginning of the DefWindowProcA procedure. So add this jump:
So now every message that is not WM_CLOSE will go through normally, while the WM_CLOSE message will fall through into whatever we do next. Let’s not do anything crazy yet, just to see if our code works. We’ll just put a jump to the end of the DefWindowProcA routine to make sure our cave works. This will basically make the close button do nothing if we click the ‘X’ in the title bar. The address we want to jump to is 401359. This jumps to right after the call to DefWindowProcA. Here’s what our cave should look like after entering the instructions:
And we need to go up and change the JNZ to automatically jump to our code cave at address 4012AC. Just double-click on the bookmark “Jump to Code Cave” and we should land here:
Patching this jump to always jump to our code cave:
Our new patch:
which jumps to our code cave, right click> Follow:
Let’s go ahead and try it. First, place a BP on our patched jump to the code cave at address 4012AC and run the app. If you need to re-start the app first make sure you re-activate the patches:
Now we want to do the fun stuff.
If you read my other tutorials on ASM Injecting then you should know how to complete the next part, that’s what learning is. Here’s the format:
PUSH the style for Message box
PUSH the address of the title of the message box
if( counter == 0 )
PUSH address of first message’s text
elseif (counter == 1 )
PUSH the address of the 2nd message’s text
elseif (counter == 2 )
PUSH the address of the 3rd message’s text
jump to DefWindowProcA (fixing the stack before we jump) as we want to close the app now
PUSH the handle to the message box (null)
jump to after the DefWindowProcA call to continue so the app doesn’t close
Like my other tutorials when I ask you to finish it, i will post another one to see if you did it right. Consider it homework.
ASM Injecting Part 4 +
- You can follow any responses to this entry through the RSS 2.0 feed.
- Both comments and pings are currently closed.