First of all, i want to say that this is not to be used for cheating in online games, or give me an advantage over other players, it is striclty for learning purposes, and games are fun.
I have in a long time wanted to get a bit more in depth with the memory, reading assembly and reverse engineering. So i have fired up good old Quake for a fun exercise, to give myself ammo.
So i have used a memory searcher and found the dynamic address in memory that holds my ammo count. With the same tool i have found the address of the instruction.
42ABED 89 34 38 mov dword ptr [eax+edi], esi // Instruction
// DUMP
4E7E4A4 // 23.f Dynamic address of the ammo count
ESI = 41B80000
EAX = 4A4
EDI = 4E7E000
Surrounding assembly code:
0042ABDC | mov dword ptr ds:[edi],eax | edi:DbgUiRemoteBreakin
0042ABDE | jmp glquake.42A6DF |
0042ABE3 | mov eax,dword ptr ds:[edi] | edi:DbgUiRemoteBreakin
0042ABE5 | mov edi,dword ptr ds:[80B874] |
0042ABEB | mov esi,dword ptr ds:[esi] | esi:DbgUiRemoteBreakin
0042ABED | mov dword ptr ds:[eax+edi],esi |
0042ABF0 | jmp glquake.42A6DF |
0042ABF5 | mov edi,dword ptr ds:[edi] | edi:DbgUiRemoteBreakin
0042ABF7 | mov eax,dword ptr ds:[80B874] |
0042ABFC | add edi,eax |
0042ABFE | mov eax,dword ptr ds:[esi] | esi:DbgUiRemoteBreakin
So after a lot of reading forums i think i have understood some of it;
ESI
is what that holds my ammo, it is the hexadecimal representation of 23, which in fact is correct according to my notes.
EAX + EDI is my dynamic address for the ammo count.
4A4 + 4E7E000 = 4E7E4A4
So i took a wild guess here, if i write a byte array to the address of the instruction, would it set my ammo? sadly not and here is what i did:
C#
float ammoToGive = 100.0F;
Process gameProcess = Process.GetProcesses().Where(x => x.ProcessName.ToLower().Contains("glquake")).FirstOrDefault();
IntPtr processHandle = WinApi.OpenProcess(0x1F0FFF, false, gameProcess.Id);
int bytesWritten = 0;
byte[] buffer = BitConverter.GetBytes(ammoToGive);
WinApi.WriteProcessMemory((int)processHandle, 0x42ABED, buffer, (UInt32)buffer.Length, ref bytesWritten);
So when firing of this the game crashed.. Apparently there is more to this and i cant seem to fully understand how this instruction works. What would the next steps for me be?
Is the address for the instruction the wrong place to send this? If so, how would i get the correct address in memory to send this to?