So I want to make a Java program that can read data from another program. It's from a game, and I can't (to my knowledge) get the information from the files (it's run serverside). How would I do this? Currently I'm reading pixels from the screen, but I don't think it's the proper way to do it. Can I somehow access the RAM? The information would be stored there. Problem with reading the pixels is it should run on more computers, and they don't necessarily have the same resolution / placement of the window (could be windowed mode). Any ideas?
Java isn't necessarily the best language for this. A way of accomplishing what you want to do is make an injectable DLL which uses pointers to read from the memory or use ReadProcessMemory
to read memory from an external process.
If you're sure you want to use Java for this you can use the JNA Library to access the native method ReadProcessMemory
and you can find the memory addresses using a tool like CheatEngine.
To load in Kernel32
(where the ReadProcessMemory
method is) you must do something along the lines of this:
Kernel32 kernel32 = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
You then need to know the access rights you need to accomplish what you want to do, which can be found at Microsoft's website. In this case we're wanting to read only so the access right we need is PROCESS_VM_READ (0x0010)
. We can then store this value in a const:
public static final int PROCESS_VM_READ = 0x0010;
Then if we look up the syntax of ReadProcessMemory, we find that the syntax is like this:
BOOL WINAPI ReadProcessMemory(
_In_ HANDLE hProcess,
_In_ LPCVOID lpBaseAddress,
_Out_ LPVOID lpBuffer,
_In_ SIZE_T nSize,
_Out_ SIZE_T *lpNumberOfBytesRead
);
ReadProcessMemory
takes a process handle (Pointer
in JNA), the memory address to read from (lets say we want to read from static value 0x10101AAA82
), the buffer to read to, the size of the value and the last value which outputs the number of bytes read we'll set to null
since we don't really care.
So first, we want to open a pointer to the process we want to read from, assuming you know the PID of the process:
Pointer process = kernel32.OpenProcess(PROCESS_VM_READ, pid);
and now we have the handle to the process (ie. the first parameter of ReadProcessMemory
The buffer we're going to read to is going to be an instance of Memory which we can instantiate by passing in the size of the value we want to read, lets say I want to read 2 bytes in this situation.
Memory memory = new Memory(2);
We've now got all the parameters we need to read our memory value:
kernel32.ReadProcessMemory(process, 0x10101AAA82, memory, 2, null);
Which means we want to read 2 bytes
from memory address 0x10101AAA82
from process process
into the memory
memory.
Now we can get the value of what we've just read! If my value is an integer we can call getInt(offset)
on memory
and since we want to read from the start we'll pass in 0
as the offset. You can also run getString
, getChar
or anything listed on the javadoc. And now you have your value!
You are actually trying to more or less program a bot. I would recommend trying to figure out what are the files and/or ports responsible for this information passing (which can be hard). And I am not sure that Java is the best way to go about it. (Visual Basic maybe?)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With