转移正在运行的进程执行到我们控制的代码。首先是如何放置我们想执行的代码? 那么需要了解进程的布局和执行流。最基本的工具是符号表,符号映射到vma。 objdump --syms ./example | grep main 08048450 g F .text 00000082 main main函数是最好的倾倒区域给任意代码,因为它的代码永远不会再次运行。当然还 有很多区域当作倾倒区域,例如如果程序有帮助函数区域,一般不会使用 然后是如何修改执行过程?这里需要知道ptrace的知识和vm如何遍历可执行文件。 在X86平台,有个vm寄存器用来保存下个指令的vma。一旦一个指令完成,vm处理在 eip(vm寄存器)的指令,并将eip加上当前指令长度。有些其它跳转指令,比如jmp 引起eip被修改到操作数指定的地址。理论上我们放置一些自己的代码在0x08048450, 为了执行我们的代码,通过ptrace的PTRACE_SETREGS和PTRACE_GETREGS函数,他们 允许第三方程序获取和设置另外一个进程的寄存器。这个寄存器包含eip。步骤如下: a。调用PTRACE_GETREGS获取当前的寄存器信息 b。设置其中的eip为我们代码的地址 c。调用PTRACE_SETREGS来设置寄存器 d。继续执行原进程 然后一旦我们的代码执行完毕如何恢复原来的执行?我们需要修改我们的注入代码 可以在最后加入int 0x3,在Linux下引起异常或断点SIGTRAP来激活调试器。如果进程 正在被跟踪,那么它将被wait()捕获。 nop nop nop nop nop nop move $0x1, %eax int $0x3 nop 步骤多了些: a。调用PTRACE_GETREGS b。保存这些寄存器,用于恢复 c。设置eip寄存器到注入代码的地址 d。调用PTRACE_SETREGS修改寄存器 e。继续执行,但是使用wait()函数监视信号,如果wait函数返回信号 aa。调用PTRACE_GETREGS bb。如果eip减去保存的eip等于注入代码大小-1.表示注入代码执行到最后 那么到下一步f cc。否则,继续执行 f。在注入代码完成后,调用PTRACE_SETREGS恢复步骤b保存的值。