Domanda

I am memory editing a game called Assault Cube which can be found at: http://assault.cubers.net/

I'm not sure how to describe it, so I've made a video of me doing it: www.youtube.com/watch?v=SS1swxQIbDI

Notice that my ammo goes down before the edit. After the edit, the ammo stays constant. Basically, at 0x45B75F, I need to insert two NOPs.

I've found the following on the internet:

1.

BYTE NewBytes[] = { 0xXX, 0xXX, 0xXX, 0xXX, 0xXX };
*(PBYTE)0xXXXXXXXX[0] = NewBytes;

So I tried doing:

BYTE NewBytes[] = { 0x90, 0x90 };
*(PBYTE)0x45B75F[0] = NewBytes;

But I get this error: error C2109: subscript requires array or pointer type

2.

DWORD origProtect;
VirtualProtect( ( void* )0x77D142CF, 5, PAGE_EXECUTE_READWRITE, &origProtect );
memcpy( ( void* )0x77D142CF, "\x8B\xFF\x55\x8B\xEC", 5 );
VirtualProtect( ( void* )0x77D142CF, 5, origProtect, NULL );

I would prefer to not use memcpy or any method.

3.

char val = 0x48;
BOOL success = WriteProcessMemory(target, 0x10134CE0, &val, 1, NULL);

Again, I would prefer to not use a method.

4.

uint8_t* code = (uint8_t*)0x45B75F;
*code = 0x90;

The above gives me these errors:

error C2065: 'uint8_t' : undeclared identifier
error C2065: 'code' : undeclared identifier
error C2065: 'uint8_t' : undeclared identifier
error C2059: syntax error : ')'
error C2065: 'code' : undeclared identifier

5.

*(char*)0x45B75F = 0x90;

This results in a crash.

È stato utile?

Soluzione

1. You've double-dereferenced here. What you want is:

*((BYTE *) (0x45B75F + 0)) = NewBytes[0];
*((BYTE *) (0x45B75F + 1)) = NewBytes[1];

When overwriting code, you need to ensure that execution is not running the code that you're overwriting. Otherwise, you might introduce a race condition where you accidentally introduce invalid or undesired instructions for a short period of time. You might look into atomic operations (where applicable) for performing your binary rewriting.

2. Your aversion to memcpy here seems questionable. It is possible that the compiler will optimise the memcpy into a doubleword-MOV, followed by a single byte MOV. You can force this issue by encoding your 5 bytes into one 32-bit integer, and a single byte. Alternatively, you can write 5 consecutive writes to memory, and the compiler might automatically combine them. For example:

code[0] = byte0;
code[1] = byte1;
etc.

3. Why do you want to avoid using this function? I am unfamiliar with windows, but this appears to be a standard way to write to another process's memory.

4. uint8_t is defined in stdint.h C99 standard library header; you must include it. The error about code not being declared is a side-effect of the former error with uint8_t.

5. That is not unreasonable. You're injecting a NOP into an assumed well-defined address, with no regard to what you're overwriting. Take this simple example:

Suppose I have an instruction in memory call I1, and it takes up two bytes: [I1_0, I1_1]. Right now, what you're doing is potentially overwriting one of those bytes with a NOP, with no regard as to whether the surrounding bytes will remain valid as instructions, e.g. [0x90, I1_1] or [I1_0, 0x90]. If I1_0 or I1_1 alone are invalid opcode sequences, then of course the program will crash!

Another reason why this might not work is that it's common (at least on Mac and Linux) for a debugger (in your case, OllyDbg) to lay out the address space of the process being debugged in a different way than the OS will when the process is run natively. That means that an address like 0x45B75F might be meaningful in the debugger but meaningless when trying to operate on the memory of a native process.

A third reason why this might not work is that the write to memory (without more information from you) appears to be operating on the memory of your process and not the memory of another process (unless that is what you are trying to do). If that memory address is even mapped, it still might not be available for writing (due to page protection).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top