Valhalla Legends Forums Archive | C/C++ Programming | DLL Injection / Writing Code to a Processes Memory

AuthorMessageTime
Dyndrilliac
Ok, so I'm injecting my DLL into a game. I want to force the game to call a function from my DLL at a location of my choosing.

I know that for the call instruction I'll need my functions address, which I can get with this:[code]long lpFunctionAddress = (void (__stdcall *)())&MyFunction;[/code]

What I don't understand is how to write the call to memory. I can't just copy over the opcode because I don't know how to translate the instruction, and I can't hardcode it because function address may vary.

Any suggestions? Any help on this subject is appreciated.
July 11, 2005, 1:05 PM
Arta
You need to find an appropriate part of the game, and save the instructions that are there. Then, write your function call to the game's memory. The game should call a naked function in your DLL, which reconstructs whatever instructions you removed from the game before calling your function (or the other way round). If you remove more bytes than you need for your call, remember to pad the call with NOPs. In your naked function, be careful to preserve the contents of any registers that you alter in the course of calling your function. You may wish to consider using a jump instead of a call (I've always found that easier).

When you unload your DLL, you can use the instructions that you saved at the beginning to restore the game's memory. If you don't care about unloading your DLL, then you don't really need to save anything.
July 11, 2005, 2:16 PM
Dyndrilliac
The thing is though I don't understand how to write my function call to the game's memory. I know how to get the address for the call, and I know where to put my call, but I don't know how to translate the call to opcode so I can write it to memory. Using my sample code to get the function address in my above post, I would need to write the following to memory:

[code]CALL lpFunctionAddress[/code]

I don't know how to go about doing that. I know how to recreate the stuff I overwrite, I just don't know how to write my function call to memory.
July 11, 2005, 3:09 PM
Myndfyr
You could, literally:

[code]
__asm call    myProc ; direct call (as opposed to indirect or register-direct)
[/code]

and then compile with it generating an assembly listing.  The generated assembly should have the actual address, as well as the opcodes generated.  That will tell you exactly how many bytes of memory you'll need to overwrite as well.
July 11, 2005, 3:24 PM
Dyndrilliac
The problem with that is that AFAIK, my function address will vary. And I don't know how to generate an assembly listing. I'm using Microsoft Visual C++ v6.0
July 11, 2005, 5:42 PM
Myndfyr
[quote author=Dyndrilliac link=topic=12168.msg120201#msg120201 date=1121103775]
The problem with that is that AFAIK, my function address will vary. And I don't know how to generate an assembly listing. I'm using Microsoft Visual C++ v6.0
[/quote]
Okay.  You'll always have the opcode and the four-byte constant after it.

1.) Make a byte array that you're going to make the opcode and four-byte pointer.
2.) Make a DWORD pointer into the byte array and make it point at the four-byte parameter.
3.) Overwrite that with the address of your function.

Example (I don't know the opcode, but this is what I mean):
[code]
typedef unsigned char BYTE;

BYTE instructs[6] = { 0x80, 0x00, 0x40, 0x45, 0x40, 0x00 }; // the first 0x40 is where the parameter is
DWORD* pDw = (DWORD*)(&(instructs[2]));
*pDw = (void (__stdcall *)())&MyFunction;
delete pDw; // right?
[/code]
Then overwrite the inproc address with the instructs data.  You may want to preserve the bytes that you're overwriting, as has been previously mentioned.
July 11, 2005, 7:44 PM
Adron
Call instructions use relative offsets. You need to put in the op code for a jmp/call, whichever you want, and after that a 4-byte value indicating the distance from the instruction after the jump/call you just patched in to your function.

Example:

Your function is at offset 10001456. You want to patch offset 402678 to call your function.

The next instruction after your call will be at 402678 + 5 = 40267D. The distance to jump is 10001456 - 40267D = FBFEDD9.

You store the call opcode E8 at location 402678 and the distance to jump FBFEDD9 at location 402679.

I.e. patch 402678 with "E8 D9 ED BF 0F".


July 11, 2005, 11:04 PM
Dyndrilliac
Thank you Adron!! *bows to your knowledge*.

Another way someone suggested I do it is this:[code]MOV EAX, MyFunctionAddress
CALL EAX[/code]
July 12, 2005, 10:30 AM
Kp
[quote author=Dyndrilliac link=topic=12168.msg120332#msg120332 date=1121164240]Another way someone suggested I do it is this:[code]MOV EAX, MyFunctionAddress
CALL EAX[/code][/quote]

That works, but Adron's method is better for several reasons:[list][li]Smaller.  Adron uses 5 bytes, you use 7.[/li][li]Less disruptive: your method requires that EAX be free, while Adron's can be used even if all registers contain meaningful data.[/li][/list]
July 12, 2005, 11:57 PM
Myndfyr
[quote author=Kp link=topic=12168.msg120422#msg120422 date=1121212635]
[quote author=Dyndrilliac link=topic=12168.msg120332#msg120332 date=1121164240]Another way someone suggested I do it is this:[code]MOV EAX, MyFunctionAddress
CALL EAX[/code][/quote]

That works, but Adron's method is better for several reasons:[list][li]Smaller.  Adron uses 5 bytes, you use 7.[/li][li]Less disruptive: your method requires that EAX be free, while Adron's can be used even if all registers contain meaningful data.[/li][/list]
[/quote]

Yeah, I thought about that one too, and in the end it was the overwriting of EAX that kept me from suggesting it.  If you had a push EAX / mov EAX, myFunction / call EAX / pop EAX, it might be worth it, but that's a lot more code than otherwise.
July 13, 2005, 12:06 AM

Search