使用 Ptrace 检索系统调用,在第一个之后停止
Posted
技术标签:
【中文标题】使用 Ptrace 检索系统调用,在第一个之后停止【英文标题】:Retrieving system calls with Ptrace, stopping after first one 【发布时间】:2012-04-26 20:34:22 【问题描述】:我正在尝试检索所有系统调用的数量,并最终检索给定程序使用 ptrace 调用的系统调用的名称。我在一个 64 位系统上,所以我使用 ORIG_RAX * 8 来使用 ptrace 查找系统调用。我目前只能检索第一个系统调用,示例运行的输出如下。有什么想法吗?
谢谢!
输出: griffinm@well $ g++ mystrace.cc
~/cs153/assn2
griffinm@well $ a.out ls
Please wait
The child made a system call 59
a.out mystrace.cc mystrace.cc~
Number of machine instructions : 252376
~/cs153/assn2
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#define ORIG_RAX 120
int main( int argc, char* argv[])
long long counter = 0; /* machine instruction counter */
int wait_val; /* child's return value */
int pid;
long orig_eax; /* child's process id */
puts("Please wait");
switch (pid = fork())
case -1:
perror("fork");
break;
case 0:
ptrace(PTRACE_TRACEME, 0, 0, 0);
execvp(argv[1], NULL);
break;
default:
wait(&wait_val);
orig_eax = ptrace(PTRACE_PEEKUSER,
pid, ORIG_RAX,
NULL);
printf("The child made a "
"system call %ld\n", orig_eax);
while (wait_val == 1407 )
counter++;
if (ptrace(PTRACE_SINGLESTEP, pid, 0, 0) != 0)
perror("ptrace");
wait(&wait_val);
printf("Number of machine instructions : %lld\n", counter);
return 0;
Update Default Case:
Default:
wait(&wait_val);
while (wait_val == 1407 )
counter++;
if (ptrace(PTRACE_SYSCALL, pid, 0, 0) != 0)
perror("ptrace");
orig_eax = ptrace(PTRACE_PEEKUSER,
pid, 8*ORIG_RAX,
NULL);
cout<<orig_eax<<endl;
wait(&wait_val);
编辑:
Output:
griffinm@well $ a.out pwd
Please wait
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
/home/csmajs/griffinm/cs153/assn2
-1
-1
-1
-1
-1
-1
我认为 8*Orig_RAX 是问题所在,机器是 64 位的,就像我说的那样。有什么想法吗?
【问题讨论】:
您不应该硬编码数字 1407 来比较wait(2)
的返回值——这是一个实现细节。相反,您应该测试while (WIFSTOPPED(wait_val) && WSTOPSIG(wait_val) == SIGTRAP)
。
谢谢!我的教授给了我们一些用于 while 循环条件的骨架代码。我觉得有办法让它更通用。
【参考方案1】:
您可能希望使用PTRACE_SYSCALL
而不是PTRACE_SINGLESTEP
来让子进程运行到下一个系统调用,而不仅仅是一条指令。然后你可以再次使用PTRACE_PEEKUSER
来查看它是什么系统调用。
【讨论】:
我试过了,并在我原来的问题中发布了更新的结果以上是关于使用 Ptrace 检索系统调用,在第一个之后停止的主要内容,如果未能解决你的问题,请参考以下文章