Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何修改EIP';什么是tracee分叉过程?_Linux_Linux Kernel_Signals_Ptrace - Fatal编程技术网

Linux 如何修改EIP';什么是tracee分叉过程?

Linux 如何修改EIP';什么是tracee分叉过程?,linux,linux-kernel,signals,ptrace,Linux,Linux Kernel,Signals,Ptrace,我正在开发一个包含ptrace的Linux应用程序,以观察由fork()系统调用创建的另一个进程 严格地说:我想在分叉过程(chile过程或“tracee”)中实现故障注入 如下图所示: 跟踪器通过使用PTRACE_GETREGS请求从tracee获取regs(struct_user_regs)结构。之后,tracer修改tracee的EIP值(当内核切换到tracee时,订单执行将违反所谓的控制流错误CFE)。然后PTRAC E_CONT请求将发送给tracee以继续执行 不幸的是,在修改

我正在开发一个包含ptrace的Linux应用程序,以观察由fork()系统调用创建的另一个进程

严格地说:我想在分叉过程(chile过程或“tracee”)中实现故障注入

如下图所示:

跟踪器通过使用PTRACE_GETREGS请求从tracee获取regs(struct_user_regs)结构。之后,tracer修改tracee的EIP值(当内核切换到tracee时,订单执行将违反所谓的控制流错误CFE)。然后PTRAC E_CONT请求将发送给tracee以继续执行

不幸的是,在修改EPI的tracee之后,由于(分段错误),tracee无法继续执行。 我如何为tracee EIP提供另一个合适的值

这是密码

#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include<sys/user.h>
#include<sys/reg.h>
#include<stdlib.h>
#include<stdio.h>
#include <asm/ptrace-abi.h>

 int main()

 { 

  pid_t child;
  int status;
  int sum=0;
  struct user_regs_struct regs;


    child = fork();
    if(child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);

         printf("hello world 1\n");
         printf("hello world 2\n");
         raise (SIGINT); // just to move control to the tracer 
         printf("hello world 3\n");
         printf("hello world 4\n");
         printf("hello world 5\n");

         exit(EXIT_SUCCESS);
     }
    else {

          wait(NULL);
          ptrace(PTRACE_GETREGS, child,NULL, &regs);
          printf("\n EIP @  0x %#lx\n",regs.eip);
          //get the tracee EIP
          long int new_eip=ptrace(PTRACE_PEEKTEXT, child,regs.eip,NULL);
          //chabge EIP and poke it again
          new_eip += ???; // make change that let to jump to another tracee instruction address (say to print hello world 5)
          ptrace(PTRACE_POKETEXT, child,regs.eip,new_eip);
          ptrace(PTRACE_CONT, child, NULL, NULL);

          }

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main()
{ 
pid_t儿童;
智力状态;
整数和=0;
结构用户\u注册表\u结构注册表;
child=fork();
如果(子项==0){
ptrace(ptrace_TRACEME,0,NULL,NULL);
printf(“hello world 1\n”);
printf(“hello world 2\n”);
raise(SIGINT);//只是将控件移动到跟踪器
printf(“hello world 3\n”);
printf(“hello world 4\n”);
printf(“hello world 5\n”);
退出(退出成功);
}
否则{
等待(空);
ptrace(ptrace_GETREGS、child、NULL和regs);
printf(“\n EIP@0x%#lx\n”,regs.EIP);
//获取跟踪EIP
long int new_eip=ptrace(ptrace_PEEKTEXT,child,regs.eip,NULL);
//再戳一戳
new_eip+=???;//进行更改,允许跳转到另一个tracee指令地址(比如打印hello world 5)
ptrace(ptrace_POKETEXT、child、regs.eip、new_eip);
ptrace(ptrace_CONT,child,NULL,NULL);
}
返回0;
}
有什么想法吗?
谢谢您的帮助。

您不是在修改EIP,而是在EIP的指令值中添加了一些内容,可能会导致地址引用错误。要更改EIP,请使用
PTRACE\u SETREGS

      wait(NULL);
      ptrace(PTRACE_GETREGS, child,NULL, &regs);
      printf("\n EIP @  0x %#lx\n",regs.eip);
      regs.eip += ???;
      ptrace(PTRACE_SETREGS, child, NULL, &regs);
      ptrace(PTRACE_CONT, child, NULL, NULL);

是的,它是完全特定于平台的。我阅读了很多资料,其中描述了ptrace syscall,以及我们如何使用它捕获下一条指令的EIP,该指令将在ptrace向挂起的tracee发送一些请求(如ptrace_CONT)后执行。 我总是看到EIP值是这样的:

 80484a6:
 80484a7:   
 80484ac:   
 80484b2:
 80484b4:
 80484b6:
 80484b8:
我测试了一个简单的代码(只需打印EIP的值和相应的执行指令)。 但结果如下所示:

EIP: b773cbe0 Instruction executed: c3595a5d
EIP: b773cbe1 Instruction executed: ccc3595a
EIP: b773cbe0 Instruction executed: c3595a5d
hello world 5
EIP: b773cbe0 Instruction executed: c3595a5d
EIP: b773cbe1 Instruction executed: ccc3595a
EIP: b773cbe0 Instruction executed: c3595a5d
hello world 6
EIP: b773cbe0 Instruction executed: c3595a5d
EIP: b773cbe1 Instruction executed: ccc3595a
EIP: b773cbe0 Instruction executed: c3595a5d
这是什么(b773cbe0)??!!! 我移动到gdb并使用这个命令行(objdump-da.out)查看转储文件 结果与以前的结果有所不同

 8048864:   8b 6c 24 20             mov    0x20(%esp),%ebp
 8048868:   8d b3 0c ff ff ff       lea    -0xf4(%ebx),%esi
 804886e:   e8 41 fb ff ff          call   80483b4 <_init>
 8048873:   8d 83 08 ff ff ff       lea    -0xf8(%ebx),%eax
 8048879:   29 c6                   sub    %eax,%esi
 804887b:   c1 fe 02                sar    $0x2,%esi
 804887e:   85 f6                   test   %esi,%esi
 8048880:   74 23                   je     80488a5 <__libc_csu_init+0x55>
 8048882:   8d b6 00 00 00 00       lea    0x0(%esi),%esi
 8048888:   83 ec 04                sub    $0x4,%esp
 804888b:   ff 74 24 2c             pushl  0x2c(%esp)
 804888f:   ff 74 24 2c             pushl  0x2c(%esp)
 8048893:   55                      push   %ebp
 8048894:   ff 94 bb 08 ff ff ff    call   *-0xf8(%ebx,%edi,4)
 804889b:   83 c7 01                add    $0x1,%edi
 804889e:   83 c4 10                add    $0x10,%esp
 80488a1:   39 f7                   cmp    %esi,%edi
 80488a3:   75 e3                   jne    8048888 <__libc_csu_init+0x38>
 80488a5:   83 c4 0c                add    $0xc,%esp
 80488a8:   5b                      pop    %ebx
 80488a9:   5e                      pop    %esi
 80488aa:   5f                      pop    %edi
 80488ab:   5d                      pop    %ebp
 80488ac:   c3                      ret    
 80488ad:   8d 76 00                lea    0x0(%esi),%esi
8048864:8b 6c 24 20 mov 0x20(%esp),%ebp
8048868:8d b3 0c ff ff lea-0xf4(%ebx),%esi
804886e:e8 41 fb ff ff呼叫80483b4
8048873:8d 83 08 ff ff lea-0xf8(%ebx),%eax
8048879:29 c6子%eax,%esi
804887b:c1 fe 02 sar$0x2,%esi
804887e:85 f6测试%esi,%esi
8048880:74 23 je 80488a5
8048882:8d b6 00 lea 0x0(%esi),%esi
8048888:83 ec 04子$0x4,%esp
804888b:ff 74 24 2c推送0x2c(%esp)
804888f:ff 74 24 2c推送0x2c(%esp)
8048893:55%推压ebp
8048894:ff 94 bb 08 ff ff ff ff调用*-0xf8(%ebx,%edi,4)
804889b:83 c7 01添加$0x1,%edi
804889e:83 c4 10添加$0x10,%esp
80488a1:39 f7 cmp%esi,%edi
80488a3:75 e3 jne 8048888
80488a5:83 c4 0c添加$0xc,%esp
80488a8:5b流行百分比ebx
80488a9:5e pop%esi
80488aa:5f pop%edi
80488ab:5d pop%ebp
80488ac:c3 ret
80488ad:8D76 00 lea 0x0(%esi),%esi


我真的对此感到困惑。

如果你希望有人知道你做错了什么,你需要显示你的代码。@Barmar,代码已经添加:)通过使用gdb或Qt调试器等调试器,我无法调试tracee。是的,你是对的。但将其添加到EIP以指向下一条或任何指令的合适值是什么。我尝试过:unsignedinstruction=ptrace(ptrace=PEEKTEXT,child,regs.eip.NULL);然后,regs.eip+=sizeof(指令);我还将指令声明为long int,但它也不起作用。请在指令中添加字节数。这取决于CPU体系结构,甚至取决于当前EIP中的指令是什么,如果指令长度不同。@Barmar,这是什么(b773cbe0)?为什么会有不同的结果?