一文带你实现遍历android内存模块
1.Android内存模块遍历原理
在android系统上,要遍历app进程中的内存模块数据,必须用到proc文件系统。
proc它是由linux内核挂着到内存中,它提供内核配置、进程状态输出等功能。
用adb命令方式可以进行查看app进程中所有加载的模块信息。
cat /proc/%d/maps : cat是查看的意思, %d表示要查看的APP的进程pid
maps文件中显示出来的各个列信息解释:
第1列:模块内容在内存中的地址范围,以16进制显示。
第2列:模块内容在内存中的读取权限,r代表可读,w代表可写,x代表可执行,p代表私有,s代码共享。
第3列:模块内容对应模块文件中的偏移。
第4列:模块文件在文件系统中的主次设备号。
第5列:模块文件在文件系统中的节点号。
第6列:模块文件在文件系统中的路径。
2.android内存模块遍历实现
//存储模块信息的结构体
struct ProcMap {
void *startAddr;
void *endAddr;
size_t length;
std::string perms;
long offset;
std::string dev;
int inode;
std::string pathname;
bool isValid() { return (startAddr != NULL && endAddr != NULL && !pathname.empty()); }
};
//获取模块信息函数
bool getAPPMod(int pid)
{
ProcMap retMap;
char line[512] = {0};
char mapPath[128] = {0};
sprintf(mapPath, "/proc/%d/maps", pid);
FILE *fp = fopen(mapPath, "r");
if (fp != NULL)
{
while (fgets(line, sizeof(line), fp)) {
char tmpPerms[5] = {}, tmpDev[12] = {}, tmpPathname[455] = {};
sscanf(line, "%llx-%llx %s %ld %s %d %s",
(long long unsigned *) &retMap.startAddr,
(long long unsigned *) &retMap.endAddr,
tmpPerms, &retMap.offset, tmpDev, &retMap.inode, tmpPathname);
}
}
return true;
}