Code Injection : Inserting a MessageBox - by Sunshine
Download Example File: tutcimsg.zip (including this tut and file discussed in this tut; right click -> save target)
Ok, here comes the tut about injecting code.
We will insert a MessageBox at program start like a little "nagbox".
We will use my little example program in the zip file so I can better explain
what we do. Note: it's important that our target program import the
MessageBoxA function! That makes sense cause without it we can't use it. In
this case we have to import it by hand which I will discuss in another tutorial.
So check with Wdasm, PEditor, my Import Table Viewer or any other tool that
MessageBoxA function is imported.
Hiew and Hex Workshop (I used both)
Opgen (not absolutely necessary)
some knowledge about PE file format and little knowledge of ASM is never wrong!
Last word here: Sorry for my bad English, it's not my mother tongue! Ok, lets start..
2. What we have to do - some theory
Ok, at first we have a look how the MessageBoxA function looks like: (extract from Win32 Programmer's Reference)
( HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box );
hWnd and uType can be zero, but we have to save
our caption and our text somewhere in the file. Then we look for a place where
we can insert the code for our MessageBox. But what should we do that it will
We just change the Entrypoint of our file to the postion where we have inserted out MessageBox Code. Right after this, we jump to the original Entrypoint. The Entrypoint is the address where the program starts.
3. Let's play...
The section table of our file:
|Section||Virtual Size||Virtual Offset||Raw Size||Raw Offset||Characteristics|
- the .text section is our code section. Here
we'll insert our MessageBox code. This section starts at offset 400 and is
2B4 bytes long. So we can enter our code from 400 + 2B4 = 6B4. We have space
till offset 400 + 400 = 800. This is room for 400 - 2B4 = 14C bytes.
- the .data section is the section where we will put our caption and our text. It starts at offset A00 and is 12C bytes long. So we can enter our cap+text from A00 + 12C = B2C. We have space till offset A00 + 200 = C00. This is room for 200 - 12C = D4 bytes.
We'll see that this there is enough room in the file. If you don't find such caves, you have to make a new section... (yeah exactly what my older tut is about :-) )
First, we will enter our caption and our text in the file, more exactly in the .data section at offset B2C.
So start Hex Workshop, open our file, go to offset B2C and enter your text. This is what I have entered:
00000B10 7474 6F6E 0000 0000 0000 0000 0000 0000 tton............ 00000B20 0000 0000 0000 0000 0000 0000 5468 6973 ............This 00000B30 2069 7320 6D79 2063 6F6F 6C20 4D65 7373 is my cool Mess 00000B40 6167 6562 6F78 2100 2D3D 2059 6561 682C agebox!.-= Yeah, 00000B50 2069 7420 776F 726B 7321 2052 6576 6572 it works! Rever 00000B60 7369 6E67 2069 7320 7468 6520 6B65 7920 sing is the key 00000B70 746F 2065 7665 7279 7468 696E 673D 2D00 to everything=-. 00000B80 0000 0000 0000 0000 0000 0000 0000 0000 ................
Ok, you see that my caption starts at offset B2C and ends
at B46. Our text starts at offset B48 and ends at B7F. We need the starting
offsets later. It's important that there is a "00" after caption
and after text! We need also the virtual addresses and they are for B2C
= 40312C and for B48 = 403148.
(If you don't know: The VA (virtual address) is the RVA + imagebase!)
Fine, now we insert our code. But we need some more information. Open PEditor and we see that Entrypoint is 1000 (it's an RVA and the offset is 400). The last thing we need is the so-called opcode for MessageBox function. To get this opcode we use the little program Opgen by NeuRaL_NoiSE. You can also find it out in WDasm or Hiew by looking a bit around. Ok, the opcode for our MessageBox function in this file is 402018. Now we have everything.
Open Hiew, then open our file. Press 2x return key to view the Asm source. Now let's go to offset 6B4 (press F5, enter 6B4, press return).
If you know a bit Asm, you know that we have to push all argument in reverse order (first utype, then lpCaption, then lpText, then hWnd) and then call the function. So press F3, then F2 and now enter exactly as I have below (after each line press enter):
Now press escape, then F9 to update. Then it looks like the following:
.004012B4: 6A00 push 000
.004012B6: 682C314000 push 00040312C
.004012BB: 6848314000 push 000403148
.004012C0: 6A00 push 000
.004012C2: FF1518204000 call MessageBoxA
.004012C8: E933FDFFFF jmp .000401000
First we push the last argument which is uType (style).
As we said above, this can be zero. Then we push the caption which is at
VA 40312C and then our text at VA 403148. The handle can be zero. After
that we call with the help of our opcode the MessageBox. Then we jump to
the orignal Entrypoint at offset 400 (VA is 401000 as you see).
Must now work, does't it? NO! One thing we have forgotten.... think a bit... do you know it? Yeah, we haven't changed the Entrypoint yet. So our program will run as usual cause it does never execute our entered code! Our code begins at offset 6B4, so RVA is 12B4. Open PEditor,change Entrypoint from 00001000 to 000012B4 and hit "Apply changes".
That's all. We have inserted a nice nagbox. If we press ok in this box, the program starts as usual! Hope you understand everything! Have fun!
If you have questions, ideas, suggestions, don't hesitate to mail me!
Sunshine, May 2002
This Site is part of Sunshine's Homepage