Hi all, a friend told me to take a look at this board whenever I got in trouble coding.

At the moment I'm studying a game, disassembling it, mapping out parts of the scripting engine, etc.
I have a proxy dll which I use to hook certain functions (d3d8.dll), and it already works well in the sense that it can read information from the game, draw its own bitmap and text to the game screen, etc.

Now, the next thing I want to do is redirect a certain function call to my own function. I have determined the location of the call (in the executable) to be 0x44FDB5. The actual function is located at 0x44FBE0.
The hex content of 0x44FDB5 is E8 26 FE FF FF.
Disassembled it reads 'Call COpcodeInterpreter'. From what I've been able to determine, E8 means it's a relative near jump, and subtracting 0x44FDB5 from 0xFBE0 does give me FFFFFE2B, which is damn close.
My reasoning is, I have to replace the relative jump with an absolute jump, to the address of my own function.

I've tried all kinds of code I could come up with, or could find on the net, but I can not seem to successfully insert my own call there.
At the moment I have the following code:

FARPROC ProcessOneCommandClone	= (FARPROC)0x44FBE0;
//The actual function!

int __declspec(naked) NewOpcodeInterpreter()		//This is the new function I am trying to get called by the game
{
	hexNo=0xbaba;
	__asm
	{
		call ProcessOneCommandClone		// Call the game's script opcode processor.
		ret							// return.
	}
}

void CustomRender(IDirect3DDevice8* pDevice)
{
	int func_address = (int)&NewOpcodeInterpreter;
	//int func_address = (int)&ProcessOneCommandClone;  // Address of our function
	//int func_address = 0x0044FBE0;  // Address of our function
	
	unsigned char *text = (unsigned char *)0x44FDB5;
	if (GetAsyncKeyState(VK_F6)&1)
	{
		OutputDebugString("TestRun.....");
		DWORD dwOld;
		VirtualProtect(text, 11, PAGE_EXECUTE_READWRITE, &dwOld);
		text[0] = 0xFF;  // CALL near absolute

		text[1] = func_address & 0xFF; // little endian
		text[2] = (func_address >> 8) & 0xFF;
		text[3] = (func_address >> 16) & 0xFF;
		text[4] = (func_address >> 24) & 0xFF;
		
		/*text[1] = 0xE0; // little endian
		text[2] = 0xFB;
		text[3] = 0x44;
		text[4] = 0x00;*/
	}
}

Could any C++ guru please take a look at this and tell me what I have done wrong? Thank you very much in advance ;-)

Recommended Answers

All 5 Replies

>>My reasoning is, I have to replace the relative jump with an absolute jump, to the address of my own function.

Bad idea. Why? Because the address in memory will change every time the program is loaded by the operating system. Therefore you will never know the address of your function in memory. And the byte offset to the beginning of a function in the *.exe file is not really relevant because it too will change when loaded into memory.

Wouldn't this:

int func_address = (int)&NewOpcodeInterpreter;

account for that? I'm a bit of a n00b at pointers and assembly call instructions.

No, but this will:

int (*function)() = &NewOpcodeInterpreter;

Okay, so if I were to use a relative jump as you said, i would calulate it somewhat like this (pseudocode):

relativeaddress=Addressofnewfunction - 0x44FDB5

or

relativeaddress=Addressofnewfunction - 0x44FDB5 - 0x5

Could you show me how I would do it in C++?

Thanks for your help so far!

Sorry for the double post, but I fixed the issue.
In case anyone is interested, all I had to do was this:

int func_address = (int)&NewOpcodeInterpreter;
	//int func_address = (int)&ProcessOneCommandClone;
	//int (*func_address)() = &NewOpcodeInterpreter;
	//int (func_address) = (int)&NewOpcodeInterpreter;
	func_address=func_address-0x44FDB5-0x5;

And remove this line:

text[0] = 0xFF;  // CALL near absolute

To make the call stay relative.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.