This should work...
Call it like NowSum((BYTE*)0x2000490C);Code:void NowSum(BYTE* Address){ DWORD OldProt; VirtualProtect ( Address, 1, PAGE_EXECUTE_READWRITE, &OldProt); Address[0] = 0x3; VirtualProtect( Address, 1, OldProt, NULL); }
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.
Thanks.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; }
This should work...
Call it like NowSum((BYTE*)0x2000490C);Code:void NowSum(BYTE* Address){ DWORD OldProt; VirtualProtect ( Address, 1, PAGE_EXECUTE_READWRITE, &OldProt); Address[0] = 0x3; VirtualProtect( Address, 1, OldProt, NULL); }
Last edited by MarkHC; 10-03-2012 at 10:06 PM.
CoD Minion from 09/19/2012 to 01/10/2013
bitcode (10-03-2012)
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.
The fish trap exists because of the fish.
Once you've gotten the fish you can forget the trap.
The rabbit snare exists because of the rabbit.
Once you've gotten the rabbit, you can forget the snare.
Words exist because of meaning.
Once you've gotten the meaning, you can forget the words.
Where can I find a man who has forgotten words so I can talk with him?
bitcode (10-04-2012)
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?
https://www.mpgh.net/forum/attachment...pp-myvalue.jpg
https://www.mpgh.net/forum/attachment...ginalvalue.jpg
Thanks again.
Last edited by bitcode; 10-04-2012 at 09:37 AM.
Hell_Demon (10-05-2012),intervention61 (10-04-2012)
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.
You can win the rat race,Originally Posted by Jeremy S. Anderson
But you're still nothing but a fucking RAT.
++Latest Projects++
[Open Source] Injection Library
Simple PE Cipher
FilthyHooker - Simple Hooking Class
CLR Injector - Inject .NET dlls with ease
Simple Injection - An in-depth look
MPGH's .NET SDK
eJect - Simple Injector
Basic PE Explorer (BETA)
bitcode (10-04-2012)
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:
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.Code:DWORD* AddressOfSleep = (DWORD*) GetProcAddress(GetModuleHandle("Kernel32.dll"), "Sleep");
Anyway, thanks Jason.
You can win the rat race,Originally Posted by Jeremy S. Anderson
But you're still nothing but a fucking RAT.
++Latest Projects++
[Open Source] Injection Library
Simple PE Cipher
FilthyHooker - Simple Hooking Class
CLR Injector - Inject .NET dlls with ease
Simple Injection - An in-depth look
MPGH's .NET SDK
eJect - Simple Injector
Basic PE Explorer (BETA)
bitcode (10-05-2012)
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.
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.
Last edited by giniyat101; 10-04-2012 at 06:12 PM.
[img]https://i43.photobucke*****m/albums/e367/DeteSting/Steam-update.gif[/img]
bitcode (10-05-2012)
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:
This is the way that worked, for my surprise: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.
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*.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.
Wrong ways that I tried (with double quotes):
Right way (no quotes):Code:NowSum((DWORD*)"0x2000490C"); NowSum((DWORD*)"2000490C");
If I had tried the above version in the first day, I wouldn't have had trouble.Code:NowSum((DWORD*)0x2000490C);
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; }
Last edited by bitcode; 10-05-2012 at 02:29 PM.