Results 1 to 11 of 11
  1. #1
    bitcode's Avatar
    Join Date
    Sep 2012
    Gender
    male
    Posts
    11
    Reputation
    10
    Thanks
    4

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

  2. #2
          ( ° ͜ʖ͡°)╭∩╮
    Former Staff
    MarkHC's Avatar
    Join Date
    Nov 2011
    Gender
    male
    Location
    127.0.0.1
    Posts
    2,750
    Reputation
    66
    Thanks
    14,529
    My Mood
    Angelic
    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);
    Last edited by MarkHC; 10-03-2012 at 10:06 PM.


    CoD Minion from 09/19/2012 to 01/10/2013

  3. The Following User Says Thank You to MarkHC For This Useful Post:

    bitcode (10-03-2012)

  4. #3
    bitcode's Avatar
    Join Date
    Sep 2012
    Gender
    male
    Posts
    11
    Reputation
    10
    Thanks
    4
    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.

  5. #4
    Broderick's Avatar
    Join Date
    Apr 2011
    Gender
    male
    Location
    Basement.
    Posts
    100
    Reputation
    42
    Thanks
    30
    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.
    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?

  6. The Following User Says Thank You to Broderick For This Useful Post:

    bitcode (10-04-2012)

  7. #5
    bitcode's Avatar
    Join Date
    Sep 2012
    Gender
    male
    Posts
    11
    Reputation
    10
    Thanks
    4
    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.
    Attached Thumbnails Attached Thumbnails
    myvalue.jpg  

    originalvalue.jpg  

    Last edited by bitcode; 10-04-2012 at 09:37 AM.

  8. The Following 2 Users Say Thank You to bitcode For This Useful Post:

    Hell_Demon (10-05-2012),intervention61 (10-04-2012)

  9. #6
    Jason's Avatar
    Join Date
    Apr 2010
    Gender
    male
    Location
    /dev/null
    Posts
    5,704
    Reputation
    918
    Thanks
    7,676
    My Mood
    Mellow
    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?

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

    https://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 Jeremy S. Anderson
    There are only two things to come out of Berkley, Unix and LSD,
    and I don’t think this is a coincidence
    You can win the rat race,
    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)

  10. The Following User Says Thank You to Jason For This Useful Post:

    bitcode (10-04-2012)

  11. #7
    bitcode's Avatar
    Join Date
    Sep 2012
    Gender
    male
    Posts
    11
    Reputation
    10
    Thanks
    4
    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.

  12. #8
    Jason's Avatar
    Join Date
    Apr 2010
    Gender
    male
    Location
    /dev/null
    Posts
    5,704
    Reputation
    918
    Thanks
    7,676
    My Mood
    Mellow
    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.

    Quote Originally Posted by Jeremy S. Anderson
    There are only two things to come out of Berkley, Unix and LSD,
    and I don’t think this is a coincidence
    You can win the rat race,
    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)

  13. The Following User Says Thank You to Jason For This Useful Post:

    bitcode (10-05-2012)

  14. #9
    bitcode's Avatar
    Join Date
    Sep 2012
    Gender
    male
    Posts
    11
    Reputation
    10
    Thanks
    4

    Cool

    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.

  15. #10
    giniyat101's Avatar
    Join Date
    Sep 2011
    Gender
    male
    Location
    Not telling.
    Posts
    1,935
    Reputation
    130
    Thanks
    1,380
    My Mood
    Dead
    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?

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

    https://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.
    Last edited by giniyat101; 10-04-2012 at 06:12 PM.


     



    [img]https://i43.photobucke*****m/albums/e367/DeteSting/Steam-update.gif[/img]

  16. The Following User Says Thank You to giniyat101 For This Useful Post:

    bitcode (10-05-2012)

  17. #11
    bitcode's Avatar
    Join Date
    Sep 2012
    Gender
    male
    Posts
    11
    Reputation
    10
    Thanks
    4
    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;
    }
    Last edited by bitcode; 10-05-2012 at 02:29 PM.

Similar Threads

  1. [Tutorial] Change your IP to unban yourself
    By Super-Man in forum Game Hacking Tutorials
    Replies: 3
    Last Post: 10-13-2019, 03:33 AM
  2. How to assemble instruction in IDA?
    By josue18 in forum Reverse Engineering
    Replies: 0
    Last Post: 10-02-2010, 08:29 PM
  3. Change nickname plz
    By ateu666 in forum WarRock - International Hacks
    Replies: 4
    Last Post: 07-10-2006, 06:59 AM
  4. list of weapon packets changed...
    By LuKan in forum WarRock - International Hacks
    Replies: 10
    Last Post: 02-09-2006, 05:19 AM
  5. [Tutorial]Change class without respawn
    By vir2000 in forum Game Hacking Tutorials
    Replies: 0
    Last Post: 01-04-2006, 01:47 PM