SmileSolvedChanging Assembly Instructions in cpp

Posts 111 of 11 · Page 1 of 1
Changing Assembly Instructions in cpp
Hello,

I've seen some tutorials here about changing Assembly instructions and even after reading all the stuff, I can't manage to solve this.

Issue: can't change 2B Assembly instruction (SUB) to 03 instruction (ADD) in CPP. When I do it, the game crashes (more info in the comments).

I've used ollydbg to find out the address of the instruction. When I simply change it on ollydbg, it works fine. But it won't work when I write the cpp code for it. I was hoping you guys could help me with this.

Other note: I'm sure that the right instruction should be 03, because I changed it to 03 on ollydbg and it worked.

Code:
#include "stdafx.h"
#include <string.h>

void NowSum(DWORD* Address){   

	DWORD OldProt;
	
	char* CharPointer = (char*) Address;

	VirtualProtect((void*) Address, 1, 0x40, &OldProt); // I need to overwrite 1 byte
 
	*CharPointer = '\x03'; //Nothing happens to the game when I do this. Nothing is overwritten

	/* This is another way to do the job, but it crashes the game

	memcpy(Address, (void*)'\x03', 1);

	*/

	VirtualProtect((void*) Address, 1, OldProt, NULL);

}

void MainThread() {


	NowSum((DWORD*)"0x2000490C"); // I think the issue may be related to the way I'm passing the address here. I'm using a constant to do so. Is this right?

return;

}


BOOL APIENTRY DllMain( HANDLE hModule, DWORD  fdwReason, LPVOID lpReserved ) {    // main() function inside the dll

	if( fdwReason == DLL_PROCESS_ATTACH){
       CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&MainThread, NULL, NULL, NULL);
	   return TRUE;
	}

    return TRUE;
}
Thanks.
This should work...

Code:
void NowSum(BYTE* Address){
    DWORD OldProt;
    VirtualProtect ( Address, 1, PAGE_EXECUTE_READWRITE, &OldProt);

    Address[0] = 0x3;

    VirtualProtect( Address, 1, OldProt, NULL);
}
Call it like
NowSum((BYTE*)0x2000490C);
It didn't work. I think it must be related to game itself. It's Quake 2, single player. I'll try the same code on something else.

Thanks for the tip, Insane.
Quote Originally Posted by bitcode View Post
It didn't work. I think it must be related to game itself. It's Quake 2, single player. I'll try the same code on something else.

Thanks for the tip, Insane.
Are you sure the address is correct? I mean, have you actually checked to see if the value at 0x2000490C is actually a SUB opcode before you attempted to patch it? You may just have the wrong offset.
Quote Originally Posted by bitcode View Post
Broderick, I've attached screenshots of the original value and my value, changed on OllyDbg.

For what I've looked into, the address of an instruction should be in the left column, in hexadecimal. Is that right?

http://www.mpgh.net/forum/attachment...pp-myvalue.jpg

http://www.mpgh.net/forum/attachment...ginalvalue.jpg

Thanks again.
The address in Olly is not necessarily the same as the address of that value in loaded memory. Don't attach screenshots, they need to wait for approval. Just upload them to a free image site like imgur: the simple image sharer or something and paste the links here.
Quote Originally Posted by Jason View Post


The address in Olly is not necessarily the same as the address of that value in loaded memory. Don't attach screenshots, they need to wait for approval. Just upload them to a free image site like imgur: the simple image sharer or something and paste the links here.

Weird, cause Cheat Engine and OllyDbg returned the same memory address for that instruction.

How could I find the real address in memory then? In some tutorials they use this:

Code:
DWORD* AddressOfSleep	= (DWORD*) GetProcAddress(GetModuleHandle("Kernel32.dll"), "Sleep");
The only problem on using GetProcAddress() is that you must to know the function name. And that's why I'm not using it in the code I posted. And that's also why I'm stuck.

Anyway, thanks Jason.
Quote Originally Posted by bitcode View Post
Weird, cause Cheat Engine and OllyDbg returned the same memory address for that instruction.

How could I find the real address in memory then? In some tutorials they use this:

Code:
DWORD* AddressOfSleep	= (DWORD*) GetProcAddress(GetModuleHandle("Kernel32.dll"), "Sleep");
The only problem on using GetProcAddress() is that you must to know the function name. And that's why I'm not using it in the code I posted. And that's also why I'm stuck.

Anyway, thanks Jason.
You may need to add the modules base address. i.e
DWORD address = (DWORD)GetModuleHandle("modulename.extension") + 0x2000490C;

But I dunno as I can't see anything relevant.
So, I got to understand that I'm dealing with threads here. At first I thought that the memory allocation would follow another kind of rule for threads. Does that make sense?

I've been running the program and generating logs to understand where I'm really pointing too -- and also if 0x2000490C is really where I want to change data.

So far, I just got confused.

I won't give up. I've never been so much into programming since my 15's. Haha

Still, if anyone has anything to add on this thread, please do. Anything that lead me somewhere will help. If you need more data from me, tell me what is that and I will provide somehow.

Thanks everybody.
Quote Originally Posted by bitcode View Post
Broderick, I've attached screenshots of the original value and my value, changed on OllyDbg.

For what I've looked into, the address of an instruction should be in the left column, in hexadecimal. Is that right?

http://www.mpgh.net/forum/attachment...pp-myvalue.jpg

http://www.mpgh.net/forum/attachment...ginalvalue.jpg

Thanks again.
if they are not from the main module (eg quake.exe) you will have to convert them to RVA then convert them back to VA during runtime

anyway the address 0x2000490C doesnt appear to be from the exe (exe starts at 0x400000 and wont be 0x1FC0490C bytes long ofc)
so check the loaded module base address.
Quote Originally Posted by Jason View Post


You may need to add the modules base address. i.e
DWORD address = (DWORD)GetModuleHandle("modulename.extension") + 0x2000490C;

But I dunno as I can't see anything relevant.
Problem solved.

And if I had followed Jason's instructions step by step, I would have solved it much earlier.

I was messing around with the code to see where the problem could be. Turns out that the problem was the way I was handling the address.

I was getting the address like this:
Code:
DWORD* Address = (DWORD*) GetModuleHandle(TEXT("gamex86.dll")) + 0x490C; // this is basically summing up 0x20000000 with 0x490C, which is 0x2000490C -- the address I confirmed many times.
This is the way that worked, for my surprise:
Code:
DWORD Address = (DWORD) GetModuleHandle(TEXT("gamex86.dll")) + 0x490C; // note that now Address is no longer a pointer. When I changed according to Jason's suggestion, it worked properly.
Looking at some logs that I created myself, I saw that when I was passing the argument as (DWORD*)"0x2000490C", the final address had a random byte in front of it, which led to the wrong address all the time. I imagined it was related to the conversion between char constant and DWORD*.

Wrong ways that I tried (with double quotes):
Code:
NowSum((DWORD*)"0x2000490C");
NowSum((DWORD*)"2000490C");
Right way (no quotes):
Code:
NowSum((DWORD*)0x2000490C);
If I had tried the above version in the first day, I wouldn't have had trouble.

Anyway, thank you all for the help.

EDIT: I just noticed that Insane also suggested removing the quotes in the first reply. So. I'm blind I guess.

EDIT 2: I would like to give you the final code so that everybody can learn something with my mistake. That's the whole point of the forum.

Code:
#include "stdafx.h"
#include <string.h>
#include <fstream>

using namespace std;


void NowSum(DWORD* Address) {   

	DWORD OldProt;
	
	char* CharPointer = (char*) Address;

	VirtualProtect(Address, 1, PAGE_EXECUTE_READWRITE, &OldProt); 

	*CharPointer = '\x03';

	VirtualProtect(Address, 1, OldProt, NULL);

	// log to understand wtf was going on
	ofstream myfile;
	myfile.open ("log.txt");
	myfile << "CharPointer: " << CharPointer << "\n";
	myfile << "*CharPointer: " << *CharPointer << "\n";
	myfile << "Address: " << Address << "\n";
	myfile << "(char*) Address: " << (char*) Address << "\n";
	myfile << "*(char*) Address: " << *(char*) Address << "\n";
	myfile.close();
	
}

void MainThread() {

	DWORD Address = (DWORD) GetModuleHandle(TEXT("gamex86.dll")) + 0x490C; 

	NowSum((DWORD*)Address); // I could use NowSum((DWORD*)0x2000490C), but as a template for future codes, I would use GetModuleHandle() anyway;

return;

}


BOOL APIENTRY DllMain( HANDLE hModule, DWORD  fdwReason, LPVOID lpReserved ) {    // main() function inside the dll

	if( fdwReason == DLL_PROCESS_ATTACH){
       CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&MainThread, NULL, NULL, NULL);
	   return TRUE;
	}

    return TRUE;
}
Posts 111 of 11 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?