 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Sadret How do I cheat?
Reputation: 0
Joined: 17 Jan 2021 Posts: 2
|
Posted: Sun Jan 17, 2021 3:58 pm Post subject: [Java] ReadProcessMemory and base module address |
|
|
Hi,
like so many others I have problems with ReadProcessMemory and the base module address. Because there are so many issues about this, it's hard to find those that apply to me via the board search. I found out some things, but there are still questions. So this is my situation.
A few years ago, I wrote a program that monitored some memory addresses of a game. It was quiet simple, there was an address which's value pointed to another address, I added one offset, done:
Code: |
ptr = OpenProcess(0x0010, processId)
address = ReadProcessMemory(ptr, 0x012D5A90)
value = ReadProcessMemory(ptr, address + 0x7CD8)
|
This is just pseudo-code, because I actually use a Java wrapper for that.
The initial address 0x012D5A90 I did get from somewhere else, not CE related.
A few months ago, there was a big update of the game and my tool stopped working. The game also changed to 64 bit, if that matters. So now I decided to use CE to recreate my program.
I used the pointer scan tool to search for the correct pointer/address. As expected, I found something like this:
Base Address: Game.exe+02099b08
Offset 0: 984
// no other offsets
Points to: 1E89B96BDD4
Naturally, I expected the following to work:
Code: |
ptr = OpenProcess(0x0010, processId)
address = ReadProcessMemory(ptr, 0x02099b08)
value = ReadProcessMemory(ptr, address + 0x984)
|
But it doesn't, it gives unrelated data. So I started searching and found this board. Here, everyone is talking about getting the base module address of the process. As far as I understood, this is the memory address of the process in the main memory. But why do we need it? Doesn't ReadProcessMemory already take an address that is relative to the process' memory?
As my program worked fine before, I am really expecting that I just need to change the two numbers 0x012D5A90 and 0x7CD8, so that it will work again. How do I get these numbers out of CE?
Thanks in advance for any help.
EDIT:
@ Dark Byte: this only answers one of my three questions, right? I'd still like to know what this base address is and what ReadProcessMemory takes as an argument.
@ atom0s: Thanks for the hint.
After updating my JNA to 5.6.0, I used Module32... to get the base address. I had to adjust some things to 64 bit, but now it is running. Demo is below.
The base address seems to be static, is that safe to assume? This would fit my approach of the earlier (32 bit) version of the game.
Last edited by Sadret on Mon Jan 18, 2021 8:20 am; edited 2 times in total |
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25796 Location: The netherlands
|
|
Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Mon Jan 18, 2021 4:59 am Post subject: |
|
|
You need to make sure your code is accounting for the fact that things are 64bit. Pointers/address will require 8 bytes of space instead of 4. In most cases, people tend to overlook that and still attempt to read their pointers as if it were 32bit and land up using the wrong addresses/offsets.
Rather than pseudo code as well, better to post your real code if you have issues with something code related. Can help us help you better.
_________________
- Retired. |
|
Back to top |
|
 |
Sadret How do I cheat?
Reputation: 0
Joined: 17 Jan 2021 Posts: 2
|
Posted: Mon Jan 18, 2021 8:08 am Post subject: |
|
|
For anyone else who is using Java/JNA and needs an example implementation, here you go.
Attention: this is only for 64 bit programs.
Requirements: JNA and JNA platform (tested with 5.6.0).
Helper methods:
Code: |
public static int findProcessId(String processName) {
Tlhelp32.PROCESSENTRY32.ByReference processInfo = new Tlhelp32.PROCESSENTRY32.ByReference();
WinNT.HANDLE processesSnapshot = Kernel32.INSTANCE.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new DWORD(0L));
try {
Kernel32.INSTANCE.Process32First(processesSnapshot, processInfo);
do
if (processName.equals(Native.toString(processInfo.szExeFile)))
return processInfo.th32ProcessID.intValue();
while (Kernel32.INSTANCE.Process32Next(processesSnapshot, processInfo));
return 0;
} finally {
Kernel32.INSTANCE.CloseHandle(processesSnapshot);
}
}
public static Pointer findModuleBase(long pid, String moduleName) {
Tlhelp32.MODULEENTRY32W.ByReference moduleInfo = new Tlhelp32.MODULEENTRY32W.ByReference();
WinNT.HANDLE processesSnapshot = Kernel32.INSTANCE.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPMODULE, new DWORD(pid));
try {
Kernel32.INSTANCE.Module32FirstW(processesSnapshot, moduleInfo);
do
if (String.valueOf(moduleInfo.szExePath).contains(moduleName))
return moduleInfo.modBaseAddr;
while (Kernel32.INSTANCE.Module32NextW(processesSnapshot, moduleInfo));
return Pointer.NULL;
} finally {
Kernel32.INSTANCE.CloseHandle(processesSnapshot);
}
}
public static int readIntFromMemory(int pid, Pointer address) {
HANDLE handle = Kernel32.INSTANCE.OpenProcess(0x0010, true, pid);
Memory output = new Memory(4);
Kernel32.INSTANCE.ReadProcessMemory(handle, address, output, 4, null);
return output.getInt(0);
}
public static Pointer readPointerFromMemory(long pid, Pointer address) {
HANDLE handle = Kernel32.INSTANCE.OpenProcess(0x0010, true, (int) pid);
Memory output = new Memory(8);
Kernel32.INSTANCE.ReadProcessMemory(handle, address, output, 8, null);
return new Pointer(output.getLong(0));
}
|
Usage:
Let's say CE gave you:
Base Address: game.exe + 0x02099b08
Offset 0: 0x8e4
and no other offsets.
Code: |
String processName = "game.exe";
int address = 0x02099b08;
int offset = 0x8e4;
int pid = Process.findProcessId(processName);
Pointer baseAddress = Process.findModuleBase(pid, processName);
Pointer pointer = Process.readPointerFromMemory(pid, baseAddress.share(address));
int value = Process.readIntFromMemory(pid, pointer.share(offset));
|
For more information on what the kernel methods do and what the arguments are, you can look at the officical microsoft docs.
|
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|