我已经使用了这个答案https://stackoverflow.com/a/12016223/2536878。
正在开发x86。
我在ARM手机上尝试过此代码但无效(系统调用错误)。
我猜ORIG_EAX对ARM无效,那么使用什么值而不是ORIG_EAX?
现在我有了这段代码(适用于x86):
#include <signal.h>
#include <syscall.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <sys/user.h>
#include <sys/reg.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
int i;
pid_t child;
int status;
long orig_eax;
int kill_ret = 0;
char c[100];
child = fork();
if(child == 0)
{
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execvp(argv[1], argv + 1);
}
else
{
i = 0;
while(1)
{
wait(&status);
if (WIFEXITED(status) || WIFSIGNALED(status) )
break;
orig_eax = ptrace(PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL);
if (orig_eax == 2)
{
fprintf(stderr, "Got it\n");
kill_ret = kill(child, SIGKILL);
if (kill_ret == -1)
{
fprintf(stderr, "Failed to kill ---> %s\n", strerror(errno));
}
}
printf("%d time, system call %ld\n", i++, orig_eax);
syscall_prompt:
printf("Allow syscall? Y/N: ");
fflush(stdout);
read(0, c, 100);
if(c[0] != 'Y' && c[0] != 'N') {printf("\n"); goto syscall_prompt;}
if(c[0] == 'N') { kill_ret = kill(child, SIGKILL); if(kill_ret < 0) { fprintf(stderr, "Cannot kill child\n"); } exit(1); }
ptrace(PTRACE_SYSCALL, child, NULL, NULL);
}
}
printf("return\n");
return 0;
}