写在前面需要一定的计算机基础
安卓编译运行环境
已root手机
C4droid + SDL + GCC
中文版下载链接 https://www.lanzous.com/b958367
GameGuardian修改器 https://gameguardian.net/download
用于查看内存修改情况
安装完成后请在设置中以root身份运行
/proc/${pid}/mem 访问其他进程的内存变量
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 可读可写打开
以下可选项可以同时指定0个或多个,和必选项按位或起来作为flags 参数。可选项有很多,这里只介绍一部分,其它选项可参考open(2)的Man Page:
O_APPEND 表示追加。如果文件已有内容,这次打开文件所写的数据附加到文件的末尾而不 覆盖原来的内容。
O_CREAT 若此文件不存在则创建它。使用此选项时需要提供第三个参数mode ,表示该文件 的访问权限。
O_EXCL 如果同时指定了O_CREAT,并且文件已存在,则出错返回。
O_TRUNC 如果文件已存在,并且以只写或可读可写方式打开,则将其长度截断(Truncate)为0字节。
O_NONBLOCK 对于设备文件,以O_NONBLOCK 方式打开可以做非阻塞I/O(Nonblock I/O),非阻塞I/O
O_DIRECT: 无缓冲的输入、输出。
O_SYNC:以同步IO方式c打开文件。
BusyBox
killall [-l] [-q] [-SIG] process-name
向给定进程发送一个信号(默认:TERM)
Options:
-l 列出所有的信号名称和数字
-q 如果没有进程被终止,不要抱怨
killall -l
1) HUP
2) INT
3) QUIT
4) ILL
5) TRAP
6) ABRT
7) BUS
8) FPE
9) KILL
10) USR1
11) SEGV
12) USR2
13) PIPE
14) ALRM
15) TERM
16) STKFLT
17) CHLD
18) CONT
19) STOP
20) TSTP
21) TTIN
22) TTOU
23) URG
24) XCPU
25) XFSZ
26) VTALRM
27) PROF
28) WINCH
29) POLL
30) PWR
31) SYS
killall -CONT com.tencent.mobileqq 恢复游戏进程
killall -STOP com.tencent.mobileqq 暂停游戏进程
pread64() pread64() 函数原型
#include
ssize_t pread64(int fildes, void *buf, size_t nbyte, off64_t offset);
ssize_t pwrite64(int fildes, const void *buf, size_t nbyte, off64_t offset);
Arguments:
filedes
The file descriptor for the file you want to write in.
buff
A pointer to a buffer that contains the data you want to write.
nbytes
The number of bytes to write.
offset
The desired position inside the file.
#include
#include
#include
#include
#include
#include
static int fd=0;
//查找游戏进程pid
int find_proc_pid(const char* pack_name)
{
int id=-1,pid=-1;
DIR* dir=0;
FILE* file=0;
char filename[32]={0};
char cmdline[256]={0};
struct dirent*entry=0;
if(pack_name==NULL)
return-1;
dir=opendir("/proc");
if(dir==NULL)
return-1;
while((entry=readdir(dir))!=NULL)
{
id = atoi(entry->d_name);
if(id>0)
{
sprintf(filename,"/proc/%d/cmdline",id);
file = fopen(filename,"r");
if(file)
{
fgets(cmdline,sizeof(cmdline),file);
fclose(file);
if(strcmp(pack_name,cmdline)==0)
{
pid = id;
break;
}
}
}
}
closedir(dir);
return pid;
}
//获取mem文件句柄
int open_proc_mem(int id)
{
if(id<=0)
return -1;
char mempath[30]={0};
int hwnd = -1;
sprintf(mempath,"/proc/%d/mem",id);
//puts(mempath);
hwnd=open(mempath,O_RDWR,O_SYNC);
return hwnd;
}
//关闭mem句柄
void close_proc_mem(int hwnd)
{
if(hwnd-0)
close(hwnd);
}
//读取文件数据
void pread64_mem(int fd,void* buff,int size,long* addr)
{
if(fd<=0 || buff==NULL ||size<=0 || addr==NULL)
return;
pread64(fd,buff,size,(unsigned long)addr);
}
void pwrite64_mem(int fd,const void* buff,int size,long* addr)
{
if(fd<=0 || buff==NULL ||size<=0 || addr==NULL)
return;
pwrite64(fd,buff,size,(unsigned long)addr);
}
int main()
{
char * game ="com.aide.ndk";
long buf[1]={100};
//com.tencent.tmgp.pubgmhd”;
//com.tencent.ig";
//"com.tyhg.kjh";
//"coa.tencent.ig";
int pid=find_proc_pid(game);
printf("pid=%d\n",pid);
fd = open_proc_mem(pid);
//printf("fd=%d\n",fd);
long base=0;
long * addr = (long*)0xEDEF8D30;
pwrite64_mem(fd,&buf[0],4,addr);
pread64_mem(fd,&base,4,addr);
printf("value=%d---addr=%x\n",base,addr);
//close_proc_mea(fd);
return 0;
}
代码需要修改的两处
内存地址 long * addr = (long*)0xEDEF8D30;
包名 char * game =“com.aide.ndk”;
最后编译运行,GameGuardian中查看内存变化
这只是初步积木的第一步读写内存,需要内存地址进行修改,后续笔者如果有功夫会get 模糊搜索 联合搜索 特征码 还有和64位应用的变量类型区别 结合app方框矩阵绘制线条 以及和pc内存绝对地址的区别 。