Difference between revisions of ".dll Injection and Patching"

From SkullSecurity
Jump to navigation Jump to search
Line 1: Line 1:
{{construction}}
{{Infobox assembly}}
{{Infobox assembly}}


Line 48: Line 49:


The HackFunction can be any function, but remember that no parameters are passed and no return value can be accepted. By modifying the code in the wrapper, both of those are possible. Just remember that the stack has to be left in the same position as it started in.
The HackFunction can be any function, but remember that no parameters are passed and no return value can be accepted. By modifying the code in the wrapper, both of those are possible. Just remember that the stack has to be left in the same position as it started in.
{{construction}}
'''''This section has not been tested and is written from memory. Will update later.'''''
{{construction}}
The actual patch is done with the following C code (generally in, or called from, DLL_PROCESS_ATTACH). Note that this isn't the best way to do it, this could be cleaned up a lot, but this is the simplest way:
<pre>
/* These two lines create the wrapper then point it at the hack function */
char strWrapper[] = "\x29\x90\x88\xee\x4f\x00\x60\xe9AAAA\x61\xc3";
*((int*)(strWrapper + 8)) = (int) &HackFunction;
/* This calculates
int intDistance = strWrapper - addressToPatch;
HANDLE hProcess = GetCurrentProcess();
WriteProcessMemory(hProcess, [address to patch], strWrapper, SIZE_T nSize,
  SIZE_T* lpNumberOfBytesWritten
);
</pre>


== Questions ==
== Questions ==
Feel free to edit this section and post questions, I'll do my best to answer them. But you may need to contact me to let me know that a question exists.
Feel free to edit this section and post questions, I'll do my best to answer them. But you may need to contact me to let me know that a question exists.

Revision as of 01:59, 16 March 2007

Stop hand.png This page is under construction. USE AT YOUR OWN RISK!







Assembly Language Tutorial
Please choose a tutorial page:

.dll injection is the easiest and most common way to write a hack.

To perform an injection, a process is told to load an attacker-controlled .dll file into its space. When loaded, the .dll file adds jumps (or "hooks") to certain places in the target program that automatically call functions in the .dll file. This allows the .dll file to capture specific events, such as packets being received, commands being typed, or anything else.

Injection

If you want a program to do it for you without reading any further, feel free to grab the one I wrote. It works well, but can't really be automated.

If you want to learn more about injection, feel free to browse my code here or download the code here. It's my first (and only) Windowsy program, so it might be valuable some day! But seriously, be gentle, and if you think you can improve it I'd welcome the change.

Basically, a program calls CreateRemoteThread() in the foreign process, giving it some code. The code given simply calls LoadLibrary() on your selected .dll file, which loads it into the program's address space.

If you want any more details about how injection works, check out Richter's book or my source code. It's been a long time, and I've always just used that program.


Patching

When loaded, the .dll file, in DLL_PROCESS_ATTACH, typically overwrites sections of the program's code, using WriteProcessMemory(), to point to itself. The overwritten code must also be run before the hack is (or after, but I generally do it before). Otherwise, the commands will never be run, and the program will likely misbehave.

The Patch

The first step to writing the patch is to have the game's code call code controlled by the .dll file. A call is 5 bytes of machine code (E8 + the distance) that alters the stack, so we need one or more instructions that don't touch the stack and that are 5+ characters long. This instruction would make a good candidate:

.text:0040209B 29 90 88 EE 4F 00                 sub     dword_4FEE88[eax], edx

Once the patch is added, the code will look like this:

.text:0040209B E8 xx xx xx xx                    call    [wrapper]
.text:004020A2 90                                nop

The first 5 bytes, 29 90 88 EE 4F, were overwritten with the machine code to make a function call to the .dll-controlled code, the "wrapper". The final byte of the machine code, 00, was overwritten by a nop instruction. Leaving the final instruction intact would likely cause problems, since we don't know what the instruction "00" represents, so it is replaced with a safe "nop".

The Wrapper

The easiest way to ensure that the original code runs is to create a wrapper in the .dll that has those exact bytes, then jumps to the attackers actual function. This process can be referred to as "rebounding," although I prefer just calling it "writing a wrapper". Here is what we want the wrapper string to do:

29 90 88 EE 4F 00   sub  dword_4FEE88[eax], edx   ; This was the code replaced in the patch
E8 xx xx xx xx      jmp  HackFunction             ; This is the ultimate destination of the code

Additionally, it's often a good idea to ensure that all registers are backed up and restored. If you wish to do that, then the wrapper would be:

29 90 88 EE 4F 00   sub  dword_4FEE88[eax], edx   ; This was the code replaced in the patch
60                  pushad                        ; Preserve the state of the registers
E9 xx xx xx xx      call  HackFunction            ; This is the ultimate destination of the code
61                  popad                         ; Restore the registers
C3                  ret                           ; Because this wrapper is doing a "call", we have to return


Which translates to the following machine code:

char *wrapper = "\x29\x90\x88\xee\x4f\x00\x60\xe9\x??\x??\x??\x??\x61\xc3";

Where the four unknown bytes are the distance between them and the HackFunction.

The HackFunction can be any function, but remember that no parameters are passed and no return value can be accepted. By modifying the code in the wrapper, both of those are possible. Just remember that the stack has to be left in the same position as it started in.

Stop hand.png This page is under construction. USE AT YOUR OWN RISK!







This section has not been tested and is written from memory. Will update later.

Stop hand.png This page is under construction. USE AT YOUR OWN RISK!







The actual patch is done with the following C code (generally in, or called from, DLL_PROCESS_ATTACH). Note that this isn't the best way to do it, this could be cleaned up a lot, but this is the simplest way:

 /* These two lines create the wrapper then point it at the hack function */
 char strWrapper[] = "\x29\x90\x88\xee\x4f\x00\x60\xe9AAAA\x61\xc3";
 *((int*)(strWrapper + 8)) = (int) &HackFunction; 

 /* This calculates 
 int intDistance = strWrapper - addressToPatch;

 HANDLE hProcess = GetCurrentProcess();
 WriteProcessMemory(hProcess, [address to patch], strWrapper, SIZE_T nSize,
  SIZE_T* lpNumberOfBytesWritten
);

Questions

Feel free to edit this section and post questions, I'll do my best to answer them. But you may need to contact me to let me know that a question exists.