我正在玩ptrace。我有一个简单的程序,它加载我构建的共享库,然后调用其中的两个函数。共享库和主程序都有一些sleep()调用,给我时间来附加。
当程序运行时,我cat / proc / [pid] / maps来确定共享对象的内存在哪里。我想转储加载的文本部分(或我选择的任何其他部分)的内容。
在ptrace程序中,我附加,等待停止,然后尝试PTRACE_PEEKDATA读取内存。 [通过以下更新修复]问题是,我总是收到EIO错误。为什么会这样?这个过程显然存在,如果我这样做,我可以看到它处于't'状态 - 被跟踪阻止。
更新:ESRCH错误已修复(ptrace调用中缺少参数)。我现在正在尝试读取EIO错误。为什么会这样?对ptrace的调用(PTRACE_PEEKDATA ...)似乎是正确的,内存地址在页面对齐的边界上。
主程序(待跟踪)。用-ldl
编译#include <stdio.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <unistd.h>
typedef int (*Add_t)(int, int);
typedef int (*Mul_t)(int, int);
#define LIB_PATH "./libmylib.so"
int main()
{
void *pHandle = NULL;
Mul_t pfnMultiply = NULL;
Add_t pfnAdd = NULL;
int a = 5, b = 10;
int i=0;
printf("My pid: %u\n", getpid());
pHandle = dlopen(LIB_PATH, RTLD_NOW);
if (pHandle == NULL)
{
printf("Did not find library!\n");
return -1;
}
pfnMultiply = dlsym(pHandle, "Mul");
if (pfnMultiply == NULL)
{
printf("Could not find multiply symbol");
return -1;
}
pfnAdd = dlsym(pHandle, "Add");
if (pfnAdd == NULL)
{
printf("Could not find add symbol");
return -1;
}
printf("add function address: %p, function pointer address: %x\n", pfnAdd, &pfnAdd);
printf("mul function address: %p, function pointer address: %x\n", pfnMultiply, &pfnMultiply);
printf("a + b = %d\n", pfnAdd(a, b));
printf("a * b = %d\n", pfnMultiply(a, b));
fflush(stdout);
for (i=0; i < 120; i++)
{
if (i % 10 == 0) { printf("sleeping: %d of %d\n", i, 120); }
fflush(stdout);
sleep(1);
}
printf("done!\n");
return 0;
}
库。使用-shared -fPIC编译
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>
volatile void *pFunc = 0xAAAAAAAA;
volatile void *pFunc2 = 0xBBBBBBBB;
int Add(int a, int b)
{
printf("sleeping 200...\n");
sleep(200);
return a + b;
}
int Mul(int a, int b)
{
return a*b;
}
示踪
#include <stdio.h>
#include <stdlib.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char **argv)
{
unsigned int pid = (unsigned int)atoi(argv[1]);
unsigned long long searchStart = strtoull(argv[2], NULL, 16);
long long searchEnd = strtoull(argv[3], NULL, 16);
long long pos = searchStart;
int status = 0;
printf("Attaching to pid: %d\n", pid);
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1)
{
printf("Ptrace attach failed. Error: %s\n", strerror(errno));
return -1;
}
printf("Attached\n");
printf("Waiting for pid to stop\n");
while (1)
{
if (waitpid(pid, &status, 0) == -1)
{
printf("Waitpid failed. Error: %s\n", strerror(errno));
return -1;
}
if (WIFSTOPPED(status))
{
printf("stopped...\n");
if (WSTOPSIG(status) == SIGSTOP)
{
printf("Got SIGSTOP\n");
break;
}
else
{
printf("Did not get SIGSTOP");
ptrace(PTRACE_CONT, pid, 0, WSTOPSIG(status));
}
}
}
printf("Process stopped\n");
unsigned long long value = 0;
printf("Looking at pos: %llx\n", pos);
value = ptrace(PTRACE_PEEKDATA, pid, (void *)&pos, NULL);
if (value = -1)
{
printf("Error reading data\n");
}
else
{
printf("Value: %llu\n", value);
}
for (pos; pos < searchEnd; pos++)
{
long value = 0;
errno = 0;
value = ptrace(PTRACE_PEEKDATA, pid, (void *)&pos, NULL);
if (errno != 0 && value == -1)
{
switch(errno)
{
case EBUSY:
printf("EBUSY\n");
break;
case EFAULT:
printf("EFAULT\n");
break;
case EINVAL:
printf("EINVAL\n");
break;
case EIO:
printf("EIO\n");
break;
case EPERM:
printf("EPERM\n");
break;
case ESRCH:
printf("ESRCH\n");
break;
}
printf("Error: %s\n", strerror(errno));
break;
}
if (value != 0 && value != 0xffffffffffffffff)
{
printf("%llx: %llx\n", pos, value);
}
}
printf("done\n");
sleep(800);
return 0;
}
输出
user@machine:~/projects/scratch/x86$ ./call
My pid: 30776
add function address: 0x7f371292a805, function pointer address: e87569e8
mul function address: 0x7f371292a862, function pointer address: e87569e0
Me: 0x7f371292a805
sleeping 200...
a + b = 15
a * b = 50
sleeping: 0 of 120
sleeping: 10 of 120
sleeping: 20 of 120
sleeping: 30 of 120
sleeping: 40 of 120
sleeping: 50 of 120
sleeping: 60 of 120
sleeping: 70 of 120
sleeping: 80 of 120
sleeping: 90 of 120
sleeping: 100 of 120
sleeping: 110 of 120
done!
While that program is running...
user@machine:~/projects/scratch$ cat /proc/30776/maps | grep lib
7f371292a000-7f371292b000 r-xp 00000000 00:5c 14136507 /home/user/projects/scratch/x86/libmylib.so
7f371292b000-7f3712b2a000 ---p 00001000 00:5c 14136507 /home/user/projects/scratch/x86/libmylib.so
7f3712b2a000-7f3712b2b000 r--p 00000000 00:5c 14136507 /home/user/projects/scratch/x86/libmylib.so
7f3712b2b000-7f3712b2c000 rw-p 00001000 00:5c 14136507 /home/user/projects/scratch/x86/libmylib.so
7f3712b2c000-7f3712ce7000 r-xp 00000000 08:01 4200143 /lib/x86_64-linux-gnu/libc-2.19.so
7f3712ce7000-7f3712ee7000 ---p 001bb000 08:01 4200143 /lib/x86_64-linux-gnu/libc-2.19.so
7f3712ee7000-7f3712eeb000 r--p 001bb000 08:01 4200143 /lib/x86_64-linux-gnu/libc-2.19.so
7f3712eeb000-7f3712eed000 rw-p 001bf000 08:01 4200143 /lib/x86_64-linux-gnu/libc-2.19.so
7f3712ef2000-7f3712ef5000 r-xp 00000000 08:01 4200131 /lib/x86_64-linux-gnu/libdl-2.19.so
7f3712ef5000-7f37130f4000 ---p 00003000 08:01 4200131 /lib/x86_64-linux-gnu/libdl-2.19.so
7f37130f4000-7f37130f5000 r--p 00002000 08:01 4200131 /lib/x86_64-linux-gnu/libdl-2.19.so
7f37130f5000-7f37130f6000 rw-p 00003000 08:01 4200131 /lib/x86_64-linux-gnu/libdl-2.19.so
7f37130f6000-7f3713119000 r-xp 00000000 08:01 4200137 /lib/x86_64-linux-gnu/ld-2.19.so
7f3713318000-7f3713319000 r--p 00022000 08:01 4200137 /lib/x86_64-linux-gnu/ld-2.19.so
7f3713319000-7f371331a000 rw-p 00023000 08:01 4200137 /lib/x86_64-linux-gnu/ld-2.19.so
user@machine:~/projects/scratch$ ./trace 30776 0x7f371292a000 0x7f371292b000
Attaching to pid: 30776
Ptrace attach failed. Error: Operation not permitted
user@machine:~/projects/scratch$ sudo bash
root@machine:~/projects/scratch# ./trace 30776 0x7f371292a000 0x7f371292b000
Attaching to pid: 30776
Attached
Waiting for pid to stop
stopped...
Got SIGSTOP
Process stopped
Looking at pos: 7f371292a000
Value: 0
ESRCH
Error: No such process
done