Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Read information about another program?

Tags:

java

pixel

ram

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?

like image 206
StupidQuestions Avatar asked Dec 20 '22 05:12

StupidQuestions


2 Answers

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!

like image 50
Jordan Doyle Avatar answered Dec 31 '22 16:12

Jordan Doyle


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?)

like image 25
Slow Trout Avatar answered Dec 31 '22 14:12

Slow Trout