This is a short tutorial which covers the basics of modifying windows binary files. We will be making a (very) simple modification to notepad so that it beeps when it is first run. You should have a basic knowledge of assembly and preferably some experience using the Olly Debugger. Since we will be working on notepad, it is recommended that you make a copy of the original binary (C:\Windows\System32\notepad.exe) to play with. Also make sure you have sounds enabled in the Control Panel.
Since we want to make notepad "beep", we first need to figure
out how that is done. Looking up MessageBeep in win32.hlp shows:
The MessageBeep function plays a waveform sound. The waveform
sound for each sound type is identified by an entry in the [sounds]
section of the registry.
BOOL MessageBeep(
UINT uType // sound type
);
Parameters
uType
Specifies the sound type, as identified by an entry in the [sounds]
section of the registry. This parameter can be one of the following
values:
Value Sound
0xFFFFFFFF Standard beep using the computer speaker
MB_ICONASTERISK SystemAsterisk
MB_ICONEXCLAMATION SystemExclamation
MB_ICONHAND SystemHand
MB_ICONQUESTION SystemQuestion
MB_OK SystemDefault
This is a simple function and only takes one argument, uType.
Since
I don't know the values associated with parameters such as
MB_ICONASTERISK offhand, we will just use 0xffffffff (-1) (MB_OK is 0,
so you can use that instead if you like). Next we need to find the
address of the MessageBeep function in notepad, so open up notepad.exe
with Olly, 'Right-click -> Search For -> All Intermodular
Calls':
We find two calls to MessageBeep at memory addresses 01003565 and
01003568; double click on 01003565 and you'll see:
0100355E MOV EDI,DWORD PTR DS:[<&USER32.MessageBeep>]
01003564 PUSH ESI
01003565 CALL EDI
Click on the line at 0100355e, and just below the code pane you will see that the address of MessageBeep is at 77d61f4c:
Next, we need to find a place to add our code. Scroll around
the code a bit in Olly, and starting at 01008747 there is a nice chunk
of free space we can use (there is a better way to find code caves, but
we will save that for later):
01008747 00 DB 00
01008748 00 DB 00
01008749 00 DB 00
*snip*
01008FFD 00 DB 00
01008FFE 00 DB 00
01008FFF 00 DB 00
0100739D > 6A 70 PUSH 70
0100739F 68 98180001 PUSH notepad.01001898
010073A4 E8 BF010000 CALL notepad.01007568
010073A9 . 33DB XOR EBX,EBX
The call at 010073A4 looks like a good place to change the
execution
of the program to point to our code, so 'Right-click ->
Assemble'
and change 'CALL notepad.01007568' to 'JMP 01008750'. Write down the
next address (010073A9) because we'll need to jump back to this address
once our code is finished. Now go to 01008750 (Ctl+G) and enter the
following instructions:
pushad <---Save the register values
pushfd <---Save the flag values
push -1 <---Push the MessageBeep argument
call 77d61f4c <---Call MessageBeep
popfd <---Restore the original register values
popad <---Restore the original flag values
call 01007568 <---Make the call that we replaced
jmp 010073A9 <---Jump back into the regular program code
Press F9 to run, and you should hear an audible beep just before the notepad window appears. To save our modifications, close out notepad and go back to 01008750; 'Right-click -> Copy to executable -> All modifications'. In the new window that pops up, Right-click -> Save as -> notepad_new.exe. Now you can exit Olly, run notepad_new.exe and you'll see that we have successfully modified notepad.
While the addition of an audio beep is more of an annoyance than anything, it does serve as an easy first project in modifying closed-source applications. For a lot of great RCE tutorials, visit Fravia's site; for a more advanced tutorial on adding Windows functionality, see LaZaRuS's Windows calculator tutorial.