linux/android进程的模块信息获取
2017-04-04 11:29
507 查看
本文参考自腾讯游戏安全实验室,感谢腾讯游戏安全实验室的技术分享,如有侵权,请联系我@@
linux进程空间中有较多的模块信息,模块信息一般包括:动态加载的链接库和可执行文件的信息。通过遍历模块可获取的进程信息包括:模块基地址和模块路径等。
下面我们以HelloWord 程序来讲讲解linux上进程模块信息的获取。该程序用C语言完成,调用了C语言标准库中的printf函数,源码如下:
编译输出:
进程内存模块的信息存放在proc文件系统下以pid为目录名称的maps文件中,通过读取
另开一个shell,查看helloword程序的进程信息:
map文件中每份模块的每列信息含义如下:
第1列:模块内容在内存中的地址范围,以16进制显示。
第2列:模块内容在内存中的读取权限,r代表可读,w代表可写,x代表可执行,p代表私有,s代表共享。
第3列:模块内容在对应模块文件中的偏移。
第4列:模块文件在文件系统中的主次设备号。
第5列:模块文件在文件系统中的节点号。
第6列: 模块文件在文件系统中的路径。
每列信息对应Linux内核中mm.h(最新版本在 mm_types.h文件中定义该结构)文件的
编译输出:
linux进程空间中有较多的模块信息,模块信息一般包括:动态加载的链接库和可执行文件的信息。通过遍历模块可获取的进程信息包括:模块基地址和模块路径等。
下面我们以HelloWord 程序来讲讲解linux上进程模块信息的获取。该程序用C语言完成,调用了C语言标准库中的printf函数,源码如下:
#include <stdio.h>**重点内容** int main(int argc,char ** argv){ printf("Hello World!\n"); getchar(); return 0; }
编译输出:
user1@user-virtual-machine:~/gamesafeTest$ gcc helloworld.c -o helloworld user1@user-virtual-machine:~/gamesafeTest$ ./helloworld Hello World! |
一、Linux内存模块遍历的原理
proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数。进程内存模块的信息存放在proc文件系统下以pid为目录名称的maps文件中,通过读取
cat /proc/<pid>/maps来读取内存的相关信息
另开一个shell,查看helloword程序的进程信息:
user1@user-virtual-machine:~$ ps -aux | grep helloworld user1 5059 0.0 0.0 4196 356 pts/0 S+ 00:13 0:00 ./helloworld user1 5082 0.0 0.0 15952 940 pts/4 S+ 00:14 0:00 grep --color=auto helloworld user1@user-virtual-machine:~$ cat /proc/5059/maps 00400000-00401000 r-xp 00000000 08:05 149801 /home/user1/gamesafeTest/helloworld 00600000-00601000 r--p 00000000 08:05 149801 /home/user1/gamesafeTest/helloworld 00601000-00602000 rw-p 00001000 08:05 149801 /home/user1/gamesafeTest/helloworld 7f883df80000-7f883e13b000 r-xp 00000000 08:02 408879 /lib/x86_64-linux-gnu/libc-2.19.so 7f883e13b000-7f883e33a000 ---p 001bb000 08:02 408879 /lib/x86_64-linux-gnu/libc-2.19.so 7f883e33a000-7f883e33e000 r--p 001ba000 08:02 408879 /lib/x86_64-linux-gnu/libc-2.19.so 7f883e33e000-7f883e340000 rw-p 001be000 08:02 408879 /lib/x86_64-linux-gnu/libc-2.19.so 7f883e340000-7f883e345000 rw-p 00000000 00:00 0 7f883e345000-7f883e368000 r-xp 00000000 08:02 408793 /lib/x86_64-linux-gnu/ld-2.19.so 7f883e54c000-7f883e54f000 rw-p 00000000 00:00 0 7f883e563000-7f883e567000 rw-p 00000000 00:00 0 7f883e567000-7f883e568000 r--p 00022000 08:02 408793 /lib/x86_64-linux-gnu/ld-2.19.so 7f883e568000-7f883e569000 rw-p 00023000 08:02 408793 /lib/x86_64-linux-gnu/ld-2.19.so 7f883e569000-7f883e56a000 rw-p 00000000 00:00 0 7ffe737f7000-7ffe73818000 rw-p 00000000 00:00 0 [stack] 7ffe7391e000-7ffe73920000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] user1@user-virtual-machine:~$
map文件中每份模块的每列信息含义如下:
第1列:模块内容在内存中的地址范围,以16进制显示。
第2列:模块内容在内存中的读取权限,r代表可读,w代表可写,x代表可执行,p代表私有,s代表共享。
第3列:模块内容在对应模块文件中的偏移。
第4列:模块文件在文件系统中的主次设备号。
第5列:模块文件在文件系统中的节点号。
第6列: 模块文件在文件系统中的路径。
每列信息对应Linux内核中mm.h(最新版本在 mm_types.h文件中定义该结构)文件的
vm_area_struct数据结构内容。关于虚拟内存最基本的管理单元为
struct vm_area_struct信息,它描述的是一段连续的具有相同访问属性的虚存空间。该虚存空间的大小为物理内存页面的整数倍
//Linux/include/linux/mm_types.h /* 295 * This struct defines a memory VMM memory area. There is one of these 296 * per VM-area/task. A VM area is any part of the process virtual memory 297 * space that has a special rule for the page-fault handlers (ie a shared 298 * library, the executable area etc). 299 */ 300 struct vm_area_struct { 301 /* The first cache line has the info for VMA tree walking. */ 302 303 unsigned long vm_start; /* Our start address within vm_mm. */ 304 unsigned long vm_end; /* The first byte after our end address 305 within vm_mm. */ 306 307 /* linked list of VM areas per task, sorted by address */ 308 struct vm_area_struct *vm_next, *vm_prev; 309 310 struct rb_node vm_rb; 311 312 /* 313 * Largest free memory gap in bytes to the left of this VMA. 314 * Either between this VMA and vma->vm_prev, or between one of the 315 * VMAs below us in the VMA rbtree and its ->vm_prev. This helps 316 * get_unmapped_area find a free area of the right size. 317 */ 318 unsigned long rb_subtree_gap; 319 320 /* Second cache line starts here. */ 321 322 struct mm_struct *vm_mm; /* The address space we belong to. */ 323 pgprot_t vm_page_prot; /* Access permissions of this VMA. */ 324 unsigned long vm_flags; /* Flags, see mm.h. */ 325 326 /* 327 * For areas with an address space and backing store, 328 * linkage into the address_space->i_mmap interval tree. 329 */ 330 struct { 331 struct rb_node rb; 332 unsigned long rb_subtree_last; 333 } shared; 334 335 /* 336 * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma 337 * list, after a COW of one of the file pages. A MAP_SHARED vma 338 * can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack 339 * or brk vma (with NULL file) can only be in an anon_vma list. 340 */ 341 struct list_head anon_vma_chain; /* Serialized by mmap_sem & 342 * page_table_lock */ 343 struct anon_vma *anon_vma; /* Serialized by page_table_lock */ 344 345 /* Function pointers to deal with this struct. */ 346 const struct vm_operations_struct *vm_ops; 347 348 /* Information about our backing store: */ 349 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE 350 units */ 351 struct file * vm_file; /* File we map to (can be NULL). */ 352 void * vm_private_data; /* was vm_pte (shared mem) */ 353 354 #ifndef CONFIG_MMU 355 struct vm_region *vm_region; /* NOMMU mapping region */ 356 #endif 357 #ifdef CONFIG_NUMA 358 struct mempolicy *vm_policy; /* NUMA policy for the VMA */ 359 #endif 360 struct vm_userfaultfd_ctx vm_userfaultfd_ctx; 361 }; 362
二、Linux内存模块遍历实现
乌班图64系统下获取”libc.so“模块内存加载基址和路径名.#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> bool GetModuleBase(long long &ulModBase,pid_t pid,const char * pszModName){ bool bRet = false; FILE * fp = NULL; char szMapFilePath[32]={0}; char szMapFileLine[1024]={0}; if(pszModName == NULL) { return bRet; } if(pid < 0) { sprintf(szMapFilePath,"/proc/self/maps"); }else{ sprintf(szMapFilePath,"/proc/%d/maps",pid); } fp = fopen(szMapFilePath,"r"); if(fp != NULL) { while(fgets(szMapFileLine,sizeof(szMapFileLine),fp)!=NULL) { if(strstr(szMapFileLine,pszModName)) { char * pszModAddrStart = strtok(szMapFileLine,"-"); if(pszModAddrStart) { ulModBase = strtoul(pszModAddrStart,NULL,16); if(ulModBase == 0x8000) ulModBase =0; bRet = true; break; } } } fclose(fp); } return bRet; } bool GetModuleFullName(pid_t pid,const char * pszModName,char *pszFullModName,int nBuffSize) { bool bRet = false; FILE * fp = NULL; char szMapFilePath[32]={0}; char szMapFileLine[1024]={0}; char * pszFullName = NULL; if(pszModName == NULL|| pszFullModName == NULL||nBuffSize<=0) { return bRet; } if(pid<0) { sprintf(szMapFilePath,"/proc/self/maps"); } else { sprintf(szMapFilePath,"/proc/%d/maps",pid); } fp = fopen(szMapFilePath,"r"); if(fp!=NULL) { while(fgets(szMapFileLine,sizeof(szMapFileLine),fp)!=NULL) { if(strstr(szMapFileLine,pszModName)) { if(szMapFileLine[strlen(szMapFileLine) -1]=='\n') { szMapFileLine[strlen(szMapFileLine) -1]=0; } pszFullName = strchr(szMapFileLine,'/'); if(pszFullName == NULL) { continue; } strncpy(pszFullModName,pszFullName,nBuffSize -1); bRet = true; } } fclose(fp); } return bRet; } int main(int argc,char ** argv) { long long ulCModBase = 0; char szCModPath[256] = {0}; if(GetModuleBase(ulCModBase,getpid(),"libc-2.19.so")) { printf("c mod base:0x%llx\n", ulCModBase); } if (GetModuleFullName(getpid(), "libc-2.19.so", szCModPath, 256)) { printf("c mod full path:%s\n", szCModPath); } printf("finish \n"); return 0; }
编译输出:
user1@user-virtual-machine:~/gamesafeTest$ g++ MapCheck.cpp -o mapcheck user1@user-virtual-machine:~/gamesafeTest$ ./mapcheck c mod base:0x7f28c6471000 c mod full path:/lib/x86_64-linux-gnu/libc-2.19.so finish
相关文章推荐
- Android中获取系统内存信息以及进程信息-----ActivityManager的使用(一)
- Android中获取系统内存信息以及进程信息-----ActivityManager的使用(一)
- Android中获取系统内存信息以及进程信息-----ActivityManager的使用
- VB 获取进程/模块信息 批量结束进程的代码
- Windows-核心编程-04-进程-获取进程 线程 模块(DLL)信息
- Android中获取系统内存信息以及进程信息-----ActivityManager的使用(一)
- Android中获取系统内存信息以及进程信息-----ActivityManager的使用(一)
- Android中获取系统内存信息以及进程信息-----ActivityManager的使用(一)
- Android中获取系统内存信息以及进程信息
- Android中获取系统内存信息以及进程信息-----ActivityManager的使用(一)
- Android中获取系统内存信息以及进程信息-----ActivityManager的使用(一)
- Android中获取系统内存信息以及进程信息-----ActivityManager的使用
- Android小功能 -- 获取系统内存信息以及进程信息
- 获取系统当前的进程及模块信息
- Android中获取系统内存信息以及进程信息-----ActivityManager的使用(一) .
- 获取系统进程模块信息
- 自制简易获取系统进程模块信息
- Android 5.0以上获取系统运行进程信息
- 获取进程模块的信息
- 进程的创建 获取信息 进程模块信息 结束等候进程 windows工作等14.4.28