我一直在尝试用 C 语言编写一个程序来读取游戏中虚拟内存地址的值,这样我就可以知道它何时加载。这在 Windows 上很容易做到,但我似乎找不到太多关于在 Linux 上做到这一点的信息。
我尝试过的所有解决方案要么不起作用,要么导致游戏冻结。我需要一个可以每帧或尽可能接近地读取该地址的解决方案。
我可以采取什么方法来做到这一点?
到目前为止,我已经尝试使用 ptrace 并从 /proc/mem 读取。使用 ptrace 会导致程序冻结,到目前为止我还没有从 /proc/mem 读取数据来工作。
编辑:我决定尝试使用 process_vm_readv 系统调用,游戏不再冻结,但由于某种原因它输出数字 3640913997。
这是代码
#include <stdio.h>
#include <sys/uio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/ptrace.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <iostream>
struct StockPid
{
pid_t pid;
char buff[512];
FILE *pid_pipe;
} stockthepid;
void Func_StockPid(const char *processtarget)
{
stockthepid.pid_pipe = popen(processtarget, "r");
fgets(stockthepid.buff, 512, stockthepid.pid_pipe);
stockthepid.pid = strtoul(stockthepid.buff, NULL, 10);
if (stockthepid.pid == 0)
{
printf("Jet Set Radio isn't running. \n");
pclose(stockthepid.pid_pipe);
exit(-1);
}
else
{
printf("Jet Set Radio is running - PID NUMBER -> {%d} \n", stockthepid.pid);
pclose(stockthepid.pid_pipe);
}
}
void ReadProcessMemory(int pid) {
struct iovec in;
in.iov_base= (void *) 0x58FAAC;
in.iov_len = 4;
uint32_t foo;
struct iovec out;
out.iov_base = &foo;
out.iov_len = sizeof(foo);
do {
ssize_t nread = process_vm_readv(stockthepid.pid, &out, 1, &in, 1, 0);
if(nread == -1) {
printf("error %s");
} else if(nread != in.iov_len) {
printf("error: short read of %li bytes", (ssize_t)nread);
}
std::cout << foo << std::endl;
} while(true);
}
int main()
{
Func_StockPid("pidof -s jetsetradio.exe");
ReadProcessMemory(stockthepid.pid);
return 0;
}
再次编辑:):更改in.iov_len
为 2 会得到一个我期望的数字 (61517),但该数字永远不会改变。