2015-04-17 20 views
2

所以我想制作一个可以从另一个程序读取数据的Java程序。它来自游戏,我不能(据我所知)从文件中获取信息(它运行在服务器端)。我将如何做到这一点?目前我正在阅读屏幕上的像素,但我认为这不是正确的方法。我可以以某种方式访问​​RAM吗?信息将被存储在那里。读取像素的问题是它应该在更多的计算机上运行,​​并且它们不一定具有相同的窗口分辨率/位置(可能是窗口模式)。有任何想法吗?Java - 阅读有关其他程序的信息?

+1

你有没有考虑过使用不同的语言,如C++?您可以开发一个动态链接库,您可以使用指针将其注入游戏并从内存中读取。否则,您可以使用JNA并使用'ReadProcessMemory'从进程中读取内存。 –

+0

唯一的问题是我不知道任何C语言。 – StupidQuestions

+1

我刚刚对我的评论进行了扩充,并为您留下了答案,希望它可以帮助您交配。 –

回答

8

Java不一定是最好的语言。完成你想要做的事情的方法是制作一个注入式DLL,它使用指针从内存中读取数据或使用ReadProcessMemory从外部进程读取内存。

如果您确定要为此使用Java,则可以使用JNA Library访问本机方法ReadProcessMemory,并且可以使用类似CheatEngine这样的工具来查找内存地址。

Kernel32加载(其中ReadProcessMemory方法),你必须沿着这行做一些事情:

Kernel32 kernel32 = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class); 

然后你需要知道你需要完成你想要做什么的访问权限,可在Microsoft's website找到。在这种情况下,我们只想读取,因此我们需要的访问权限是PROCESS_VM_READ (0x0010)。然后,我们可以将此值存储在一个const:

public static final int PROCESS_VM_READ = 0x0010; 

然后如果我们仰望的ReadProcessMemory语法,我们发现语法是这样的:

BOOL WINAPI ReadProcessMemory(
    _In_ HANDLE hProcess, 
    _In_ LPCVOID lpBaseAddress, 
    _Out_ LPVOID lpBuffer, 
    _In_ SIZE_T nSize, 
    _Out_ SIZE_T *lpNumberOfBytesRead 
); 

ReadProcessMemory把一个进程句柄(Pointer在JNA中),要从中读取的内存地址(可以说我们要从静态值0x10101AAA82中读取),要读取的缓冲区,值的大小以及输出读取的字节数的最后一个值,我们将设置为因为我们并不在乎。

因此,首先,我们要打开一个指向我们想从中读取数据的过程中,假设你知道进程的PID:

Pointer process = kernel32.OpenProcess(PROCESS_VM_READ, pid); 

,现在我们有句柄过程(即。的ReadProcessMemory

我们要读将是的Memory,我们可以通过传递我们想要读取值的大小实例化一个实例缓冲区中的第一个参数,可以说我要读2字节在这种情况下。

Memory memory = new Memory(2); 

现在,我们已经得到了我们需要阅读我们的记忆中值的所有参数:

kernel32.ReadProcessMemory(process, 0x10101AAA82, memory, 2, null); 

这意味着我们想要从过程process从内存中读取地址0x10101AAA822 bytesmemory内存。

现在我们可以得到我们刚才读到的价值了!如果我的值是一个整数,我们可以在memory上调用getInt(offset),因为我们想从头开始读取,所以我们将传递0作为偏移量。您也可以运行getStringgetCharjavadoc上列出的任何东西。现在你有你的价值!

+0

这真的很好!非常感谢。 – StupidQuestions

+1

没问题,如果您还有其他问题可以随时问 –

+0

哪种语言对这类东西更好? – Hamid

0

你实际上正在努力或多或少的编程一个机器人。 我建议试图弄清楚负责信息传递的文件和/或端口是什么(这可能很难)。 我不确定Java是否是最好的解决方法。 (Visual Basic可能?)

+0

啊有趣。分析进来的数据包。它不是一个机器人(好吧,不是作弊),它应该收集关于你的游戏的数据并分析它,这样用户就可以看到结果。 – StupidQuestions

+0

这就是我将如何去做。但这可能会很棘手。考虑你必须对通信接口进行逆向工程,这不是每个人都说的代码,而是编译好的机器代码。 –