Android模块遍历方法
一、背景
Android,中文俗称安卓,是一个以Linux为基础的开放源代码移动设备操作系统,主要用于智能手机和平板电脑,由Google成立的开放手持设备联盟持续领导与开发中。
在许多类 Unix 计算机系统中, procfs 是进程文件系统的缩写,包含一个伪文件系统,用于通过内核访问进程信息。这个文件系统通常被挂载到/proc目录。由于/proc不是一个真正的文件系统,它也就不占用存储空间,只是占用有限的内存。/proc/[pid]/maps里面存放的某一进程下的当前映射到内存中的模块列表信息。
二、maps内容格式
1. 内容展示
以进程/system/bin/sh为例,通过ps看到它的pid为21358,调用cat /proc/21358/maps(必须有权限,如root用户或者和该进程属于同一用户),查看它的内容:
2. 格式解析:
可以看到,maps的文件固定为6列,最后1列的内容有些没有。第1列是地址,表示模块在进程空间的范围;第2列是虚拟内存的权限,r=读,w=写,x=执行,s=共享(多进程共享),p=私有(即copy-on-write,如果有一进程要修改模块内容,会在进程的内存空间中单独拷贝一份);第3列为偏移量,为模块内容在文件的偏移;第4列为映射模块的主设备号和次设备号;第5列为映射模块在文件系统中的节点号,如果是文件的话;第6列是映射模块在文件系统中的路径。实际上,这6项是由linux内核的头文件mm.h中的vm_area_struct结构体中的数据成员。
三、模块遍历实现
函数说明:获取某一进程的某一模块的信息,因为没有使用的需求,这里没有返回信息。
参数1:进程的pid。
参数2:要搜索的模块名称。
void searchModuleInfo(pid_t pid, const char *pszModName)
{
FILE *fp;
char szMapFilePath[32];
char szMapFileItem[256];
char *pszStrItem, *pszStrItemBackup;
memeset(szMapFilePath, 0, 32);
memset(szMapFileItem, 0, 256);
if (pid < 0)
{
snprintf(szMapFilePath, 31, "/proc/self/maps");
}
else
{
snprintf(szMapFilePath, 31, "/proc/%d/maps", pid);
}
fp = fopen(szMapFilePath, "r");
if (fp == NULL)
{
return ;
}
while (fgets(szMapFileItem, sizeof(szMapFileItem), fp) != NULL)
{
if (strstr(szMapFileItem, pszModName))
{
pszStrItem = strtok_r(szMapFileItem, " t", &pszStrItemBackup); // 地址信息
pszStrItem = strtok_r(NULL, " t", &pszStrItemBackup); // 权限信息
pszStrItem = strtok_r(NULL, " t", &pszStrItemBackup); // 偏移信息
pszStrItem = strtok_r(NULL, " t", &pszStrItemBackup); // 设备信息
pszStrItem = strtok_r(NULL, " t", &pszStrItemBackup); // 节点信息
pszStrItem = strtok_r(NULL, " t", &pszStrItemBackup); // 路径信息
if (pszStrItem != NULL) // 判断是否有路径信息
{
if (pszStrItem[strlen(pszStrItem) - 1] == 'n')
pszStrItem[strlen(pszStrItem) - 1] = 0; // 此为完整路径的模块信息
}
break;
}
}
fclose(fp);
return ;
}
*转载请注明来自游戏安全实验室(GSLAB.QQ.COM)