• Welcome to Valhalla Legends Archive.
 

DLL Injection / Writing Code to a Processes Memory

Started by Dyndrilliac, July 11, 2005, 08:05 AM

Previous topic - Next topic

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:long lpFunctionAddress = (void (__stdcall *)())&MyFunction;

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.
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

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.

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:

CALL lpFunctionAddress

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.
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

MyndFyre

You could, literally:


__asm call     myProc ; direct call (as opposed to indirect or register-direct)


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.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

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
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

MyndFyre

Quote from: Dyndrilliac on July 11, 2005, 12:42 PM
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
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):

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?

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.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

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".



Dyndrilliac

Thank you Adron!! *bows to your knowledge*.

Another way someone suggested I do it is this:MOV EAX, MyFunctionAddress
CALL EAX
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

Kp

Quote from: Dyndrilliac on July 12, 2005, 05:30 AMAnother way someone suggested I do it is this:MOV EAX, MyFunctionAddress
CALL EAX

That works, but Adron's method is better for several reasons:
  • Smaller.  Adron uses 5 bytes, you use 7.
  • Less disruptive: your method requires that EAX be free, while Adron's can be used even if all registers contain meaningful data.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

MyndFyre

Quote from: Kp on July 12, 2005, 06:57 PM
Quote from: Dyndrilliac on July 12, 2005, 05:30 AMAnother way someone suggested I do it is this:MOV EAX, MyFunctionAddress
CALL EAX

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

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.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.