Linux系统开启MMU后,应用程序的所有页面并不是一口气加载进来,而是遇到访问未映射的线性地址时,通过触发PageFault触发从
对应的二进制文件加载指定位置的内容到页面。这不便于对应用程序进行分析,故写此代码激活应用程序指定范围内的线性地址。
#include <sys/ptrace.h>
#include <sys/types.h>#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define ARG_COUNT 4
int main(int iArgc, char* ppchArgv[])
{
int iPid = 0;
unsigned long ulStartAddr = 0;
unsigned long ulEndAddr = 0;
unsigned long ulTmp = 0;
unsigned long i = 0;
unsigned long ulCurValue = 0;
if (ARG_COUNT != iArgc)
{
printf("Usage: ./try1 pid startAddr endAddr\n");
return 0;
}
iPid = atoi(ppchArgv[1]);
ulStartAddr = strtoul(ppchArgv[2], NULL, 10);
ulEndAddr = strtoul(ppchArgv[3], NULL, 10);
if (ulStartAddr > ulEndAddr)
{
ulTmp = ulStartAddr;
ulStartAddr = ulEndAddr;
ulEndAddr = ulTmp;
}
printf("Pid:%d,StartAddr:%lu,EndAddr:%lu\n",
iPid, ulStartAddr, ulEndAddr);
errno = 0;
ptrace(PTRACE_ATTACH, iPid, NULL, NULL);
if (0 != errno)
{
printf("Attach %d Failed,errno:%d\n", iPid, errno);
return 0;
}
wait(NULL);
for (i = ulStartAddr; i <= ulEndAddr; i += sizeof(unsigned long))
{
errno = 0;
ulCurValue = ptrace(PTRACE_PEEKDATA, iPid, i, NULL);
if (0 != errno)
{
continue;
}
printf("%08X ", ulCurValue);
}
printf("\n");
errno = 0;
ptrace(PTRACE_DETACH, iPid, NULL, NULL);
if (0 != errno)
{
printf("Detach %d Failed,errno:%d\n", iPid, errno);
return 0;
}
return 0;
}