跟随玩转ptrace的文章跑示例的时候提示出错。
代码:
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <linux/user.h>
/* For constantsORIG_EAX etc */
int main()
{
pid_t child;longorig_eax;
child =fork();
if(child ==0)
{
ptrace(PTRACE_TRACEME,0,NULL,NULL);
execl("/bin/ls","ls",NULL);
}
else{wait(NULL);
orig_eax =ptrace(PTRACE_PEEKUSER,child,4*ORIG_EAX,NULL);
printf("The child made a system call %ld\n",orig_eax);
ptrace(PTRACE_CONT,child,NULL,NULL);
}
return0;
}
error: ‘ORIG_EAX’ was not declared in this scope
因为作者给的示例是32位系统下的。移到64位上要进行如下修改。
A。把linux/user.h换成sys/reg.h。
B。ORIG_EAX改为ORIG_RAX。因为ORIG_EAX寄存器在64位下对应的是ORIG_RAX。
C。4*ORIG_EAX 修改为 =》8*ORIG_RAX 因为现在是64位寄存器。
该示例是使用了PTRACE_PEEKUSER参数的ptrace函数,
从用户内存空间的栈顶指针开始往回偏移,找到ORIG_EAX(64位下是ORIG_RAX)里存放的系统调用号。偏移量就是寄存器号*寄存器宽度。
示例的系统调用是execve
执行结果:
32位下是:The child made a system call 11
64位下是:The child made a system call 59
这是因为execve系统调用号在32位和64位下的值不同。
具体可以查看/usr/include/asm/unistd.h下的execve的定义。