Well the easiest way I've found is to find your addresses and such as usual in Cheat Engine or whatever program you use, then use the Read/WriteProcessMemory APIs.
A MW2 trainer would be easy enough as the addresses tend to be static (so you won't need to deal with them changing every time). Anyway, here's a few easy examples to get you started:
Code:
// This code will disable the timer on Just Cause 2's demo
// allowing you to play for however long you want.
procedure TfrmMain.btnDisableClick(Sender: TObject);
var
hProcess,HandleWindow: THandle;
ProcessID,temp:cardinal;
i:integer;
const
addresses:array [0..2] of dword=($00538748,$00538749,$0053874A);
patches:array [0..2] of byte=($90,$90,$90);
begin
HandleWindow :=FindWindow(nil,'Just Cause 2 Demo');
GetWindowThreadProcessId(HandleWindow,@ProcessID);
hProcess := OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessID);
for i:=0 to 2 do WriteProcessMemory(hProcess,ptr(addresses[i]),@patches[i],1,temp);
if hProcess <> 0 then
CloseHandle(hProcess);
end;
The above code is what you'd use if you were patching the program's code, ie. Cancelling an effect out.
So step-by-step through that code, we define two arrays, which are constant. The "addresses" array contains the addresses we wish to write to, and the "patches" array contains the bytes we'll be inserting.
Next, we find the Just Cause 2 Demo window, and hook the process.
After this, we run a loop, using "i" as our counter. This will loop 3 times (0,1,2), and for each run of the loop, a different byte is written to a different address (these are read from the arrays we already defined).
Lastly, we run a check to release the handle on the process.
=
Code:
// This code will set the Drift Multiplier in (Race Driver) GRID v1.00 to x99
procedure TfrmMain.Drift99Click(Sender: TObject);
var
hProcess,HandleWindow: THandle;
DriftMul:integer;
ProcessID,temp:cardinal;
address:dword;
begin
DriftMul:=99;
HandleWindow :=FindWindow(nil,'GRID');
GetWindowThreadProcessId(HandleWindow,@ProcessID);
hProcess := OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessID);
ReadProcessMemory(hProcess,ptr($343F77DC),@address,sizeOf(address),temp);
address:=address+$18;
WriteProcessMemory(hProcess,ptr(address),@DriftMul,sizeOf(DriftMul),temp);
if hProcess <> 0 then
CloseHandle(hProcess);
end;
Now this code is a small bit more complicated, as it deals with some DMA, but it is an example of writing a variable.
With this kind of editing, you won't be patching addresses with hex bytes as before, but writing "normal" data to addresses. In this example we are setting an integer value to 99. As such, there is only one bit of data to write, and only one address, so we no longer need loops or arrays.
As with the first snippet of code, we start out by finding and hooking the process, and setting up the data we'll need.
We want to write our data (myInt) to a particular address in the game's memory, however this address changes each time the game is run due to DMA so we must first find the address.
Its base is always stored at the address 343F77DC, so we use ReadProcessMemory to find the data it stores, and we put that data in the "address" variable. This is only the base to a larger structure however, and the value we want is stored at [address+18h], so we preform this calculation before we continue.
Now that we have our address we can do as before and use WriteProcessMemory to write our value (myInt) to the address.
Finally as before, we run a check to release the handle on the process.
=
Code:
// This code will set the Prestige of the user according to their own choice in CoD:MW2 v1.0.184
procedure TfrmMain.btnApplyPrestigeClick(Sender: TObject);
var
hProcess,HandleWindow: THandle;
ProcessID,temp:cardinal;
prestige:integer;
const
address:dword=$01B2B89C;
begin
prestige:=0;
if StrToInt(editPrestige.Text)<=10 then prestige:=StrToInt(editPrestige.Text);
HandleWindow :=FindWindow(nil,'Modern Warfare 2');
GetWindowThreadProcessId(HandleWindow,@ProcessID);
hProcess := OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessID);
WriteProcessMemory(hProcess,ptr(address),@prestige,sizeOf(Prestige),temp);
if hProcess <> 0 then
CloseHandle(hProcess);
end;
Okay, in our final example, we'll work with Call of Duty: Modern Warfare 2. In this game, the addresses are static and so we don't need to do much work like we did in the GRID example. This is once again setting the value of a variable.
We set out by setting the prestige variable to 0. Then we check a TEdit and read its value, convert it to an integer, and use that instead. If the text entered is not a valid integer, we still have prestige set to 0, rather than a crazy value that could be automatically set. If it is a valid integer, we make sure it's a valid prestige by making sure it's less than or equal to 10.
We then find the window as before, and write our value to the address containing the prestige, and do our final check and unhook.
Now at a guess what I'd do for ju***eigh is to set that to a value (such as 100), open cheatengine, search the value, change again (to for example 150), search for the new value, and repeat until you've found it. Do note however that that is bannable by VAC so do be careful.
I hope this helps! If you have any other questions or anything feel free to ask/pm me, I'd be glad to help.
- 0rbit