Code Injection : Inserting a MessageBox - by Sunshine

Download Example File: (including this tut and file discussed in this tut; right click -> save target)

1. Introduction

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.

Tools needed:
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)

int MessageBox
( 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 be executed?
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
.text 000002B4 00001000 00000400 00000400 60000020
.rdata 000001F2 00002000 00000200 00000800 40000040
.data 0000012C 00003000 00000200 00000A00 C0000040

- 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):
push 00
push 0040312C
push 00403148
push 00
call d,[402018]
jmp 400

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