Linux ptrace内存读取与存储;过程管理

Linux ptrace内存读取与存储;过程管理,linux,ubuntu,ptrace,Linux,Ubuntu,Ptrace,我试图读取Linux上的进程内存(确切地说是Xubuntu)。虽然我以前在Windows中使用Win32API ReadProcessMemory()进行过同样的读取,但我对Linux还是相当陌生。总的想法是,我正在尝试为一款游戏开发一些软件,它将获取我的统计数据并上传到服务器,服务器将跟踪我的进度并记录下来。最终的目标是制作一个机器人,它将自动玩游戏并提供有关游戏的数据。为了做到这一点,我需要能够访问进程的内存。在Windows中,这非常容易。在Linux中,它被证明有点复杂 我找到了一个内存

我试图读取Linux上的进程内存(确切地说是Xubuntu)。虽然我以前在Windows中使用Win32API ReadProcessMemory()进行过同样的读取,但我对Linux还是相当陌生。总的想法是,我正在尝试为一款游戏开发一些软件,它将获取我的统计数据并上传到服务器,服务器将跟踪我的进度并记录下来。最终的目标是制作一个机器人,它将自动玩游戏并提供有关游戏的数据。为了做到这一点,我需要能够访问进程的内存。在Windows中,这非常容易。在Linux中,它被证明有点复杂

我找到了一个内存地址,其中包含我要读取的信息。该信息是一个int32,存储在84a1bd8。我是用GameConverator 0.13找到的。重新启动后,地址保持正确,因此似乎没有ASLR(与Windows中一样)。我还知道ProcessID(我现在可以使用任务管理器找到它,不过如果有人知道通过类名、Exe名或类似名称获取PID的简单方法,那也太好了!)因此,看起来这应该是我真正需要使用PTRACE_PEEKDATA读取内存的全部了,对吗?这就是问题所在,似乎不是。我的代码如下所示:

#include <iostream>
#include <string>
#include <sys/ptrace.h>
#include <errno.h>

using namespace std;

int main()
{
    pid_t pid = 4847;
    int addr = 0x84a1bd8;
    long ret = ptrace(PTRACE_TRACEME, pid, NULL, NULL);
    cout << "ptrace Status: " << ret << endl;
    cout << "Errno: " << errno << endl;
    ret = ptrace(PTRACE_PEEKDATA, pid, (void*)addr, NULL);
    cout << "ptrace Status: " << ret << endl;
    cout << "Errno: " << errno << endl;
    ret = ptrace(PTRACE_DETACH, pid, NULL, NULL);
    cout << "ptrace Status: " << ret << endl;
    cout << "Errno: " << errno << endl;
    return 0;
}
ptrace Status: 0
Errno: 0
ptrace Status: -1
Errno: 3
ptrace Status: -1
Errno: 3
作为Linux的新手,我不知道在哪里可以找到错误代码,也不知道如何计算出这个错误的真正含义,甚至不知道我是否正确地声明了地址。我应该在它的十进制等价物中声明它为int吗?我有什么遗漏吗


感谢您的时间

发现解决方案是,在使用ptrace()时,您必须按顺序调用:

ptrace(PTRACE_ATTACH, pid, NULL, NULL)
ptrace(PTRACE_PEEKDATA, pid, addr, NULL)
ptrace(PTRACE_DETACH, pid, NULL, NULL)
因此,简单的答案是:在读取内存之前和之后,需要连接和分离内存

知道在attach和detach命令之间,进程将处于休眠状态也可能很有用,这意味着此方法不适合我的用途,但可能对其他人有用:)


多亏了@PeterL。感谢您的帮助。

请参阅peror()调用。此外,谢谢-错误列表将是无休止的有用。如果我的程序没有使用权限运行,这可能是错误3的原因吗?因为它可能无法访问进程…@PeterL。我刚从终端输入“sudo./ConsoleApplication”运行了这个程序,它没有做任何不同的事情。PID作为一个整数值是绝对正确的,有什么我遗漏的吗?当然不会这么简单!您是如何确定4847为PID的?您可能希望修改main()以获取参数,其中一个参数是您希望监视的PID。@PeterL。我在任务管理器和GameConverter中确定了它,它们都说明了我试图监视的进程的PID。。。我知道它会改变,但现在我不介意手动输入它,至少在我能够完成进程管理和内存读取的第一阶段之前。