Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.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
ptrace显示的与objdump不同_C_Objdump_Ptrace - Fatal编程技术网

ptrace显示的与objdump不同

ptrace显示的与objdump不同,c,objdump,ptrace,C,Objdump,Ptrace,我正在编写一个C程序,它使用ptrace显示指令。代码如下: #include<stdio.h> #include <stdint.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include <sys/ptrace.h> #include <sys/user.h> #include <sys/types.h> #i

我正在编写一个C程序,它使用ptrace显示指令。代码如下:

#include<stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <string.h>

void run_target()
{
    ptrace(PTRACE_TRACEME, 0, 0, 0);
    execl("./test", "test", NULL);
}

void debugger(pid_t pid)
{
    int status;
    wait(&status);

    while(WIFSTOPPED(status))
    {
        struct user_regs_struct regs;
        ptrace(PTRACE_GETREGS, pid, 0, &regs);
        long instruction = ptrace(PTRACE_PEEKTEXT, pid, regs.rip, 0);
        ptrace(PTRACE_SINGLESTEP, pid, 0, 0);

        //EDITED SO IT PRINTS ONLY LINES I WANT
        if(((regs.rip >> (8*5)) & 0xFF) != 0x7f)    //i noticed all the junk lines that shouldnt be there, their regs.rip began with 7f
            printf("%llx %16lx\n", regs.rip, instruction);

        wait(&status);
    }
}

int main()
{
    pid_t pid;
    pid = fork();

    if(pid == 0)
    {
        run_target();
    }
    else
    {
        debugger(pid);
    }

    return 0;
}
而objdump-d看起来像这样:

000000000000064a <main>:
64a:    55                      push   %rbp
64b:    48 89 e5                mov    %rsp,%rbp
64e:    48 8d 3d af 00 00 00    lea    0xaf(%rip),%rdi        # 704 <_IO_stdin_used+0x4>
655:    b8 00 00 00 00          mov    $0x0,%eax
65a:    e8 c1 fe ff ff          callq  520 <printf@plt>
65f:    48 8d 3d a5 00 00 00    lea    0xa5(%rip),%rdi        # 70b <_IO_stdin_used+0xb>
666:    b8 00 00 00 00          mov    $0x0,%eax
66b:    e8 b0 fe ff ff          callq  520 <printf@plt>
670:    b8 00 00 00 00          mov    $0x0,%eax
675:    5d                      pop    %rbp
676:    c3                      retq   
677:    66 0f 1f 84 00 00 00    nopw   0x0(%rax,%rax,1)
67e:    00 00 
这一点实际上是正确的:

55dfb208464e b8000000af3d8d48
那么,我在objdump中是否缺少了一些东西,或者我的代码中是否缺少了一些东西,使得它显示的rip比它应该显示的更多

编辑:添加了整个代码

编辑:编辑了printf,现在它打印了它应该打印的行,但它仍然在开始添加随机十六进制 应该是什么

64a: 55
是什么

56160a60a64a 9f3d8d48e5894855

我理解为什么指令不一样,这不是我的问题,我的问题是为什么regs.rip不是64a,而是64a。每次我重新运行程序时,开始处的随机十六进制都是不同的。

您的程序正常运行,您只需按照结果中正确的顺序查看正确的位置

具有该测试定义:

#include <stdio.h>
int main()
{
  puts("hello");
  puts("world");
  return 0;
}
如果我在结果中运行您的程序,我发现代码具有相同的objdump地址和相同的指令代码,因此init部分etc然后main(从第81208行开始!):

我在英特尔i7上运行,指令字节的读取顺序必须与objdump显示的顺序相反,例如,第一条指令是55,然后是48 89 e5,然后是bf d4 05 40 00,然后是e8 cc fe ff ff等

当然,在您的情况下,这就像在调试器中执行“步骤”而不是“下一步”,因此在callq上输入put,而objdump反汇编。在到达地址400534之前,地址40052f后面有60084行,因此需要60084指令来执行
put(“hello”)


当然,可以仅从main的开头打印,例如使用objdump的惰性方式:


要做更多的工作,您必须知道每个指令调用/jmp/conditional jmp/return的代码和长度。注意,代码操作可以是1或2个字节。

MInor:suggest
printf(“%llx%16lx\n”,regs.rip,instruction)用于更好的指令对齐。@bruno yes我在同一个程序上同时执行objdump和ptrace(其中只有2个printf)@bruno ptrace_TRACEME和ptrace_SINGLESTEP都返回0,ptrace_peek text返回instruction@bruno如果我在打印时没有放入%llx,然后编译器警告我should@qlabfgerkaSmurf您看到的输出是有意义的,我可能有一个答案,但为了确保我需要额外的信息。显示您在子项中的确切操作(即C代码)。添加a是最好的主意,否则回答只是令人不快的猜测。另外,请说明您使用的是哪个发行版(
lsb_release-a
)和您的libc版本(
apt cache policy libc6
)。我写了同样的答案,但您先得到了答案,做得很好;)@bruno也许我没有理解你说的意思,我对答案并不完全满意,你在我的程序中添加了很多代码,我并不想在其中包含这些代码,例如打开一个文件,因为在孩子中只有execl应该可以做到这一点。我仍然不太明白为什么在我的机器上运行程序时,指令64a显示为64a。我最后一次更改是为了回答你的评论,后来你删除了它。“打开文件”:它不是文件,
fopen
popen
不是一回事。“指令64a”:64e不是指令。
56160a60a64a 9f3d8d48e5894855
#include <stdio.h>
int main()
{
  puts("hello");
  puts("world");
  return 0;
}
0000000000400526 <main>:
  400526:   55                      push   %rbp
  400527:   48 89 e5                mov    %rsp,%rbp
  40052a:   bf d4 05 40 00          mov    $0x4005d4,%edi
  40052f:   e8 cc fe ff ff          callq  400400 <puts@plt>
  400534:   bf da 05 40 00          mov    $0x4005da,%edi
  400539:   e8 c2 fe ff ff          callq  400400 <puts@plt>
  40053e:   b8 00 00 00 00          mov    $0x0,%eax
  400543:   5d                      pop    %rbp
  400544:   c3                      retq   
  400545:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  40054c:   00 00 00 
  40054f:   90                      nop
400526 4005d4bfe5894855
400527   4005d4bfe58948
40052a fecce8004005d4bf
40052f  5dabffffffecce8
400400   6800200c1225ff
400406 ffe0e90000000068
40040b  a25ffffffffe0e9
4003f0 25ff00200c1235ff
4003f6 1f0f00200c1425ff
...
void debugger(pid_t pid)
{
  FILE * fp = popen("objdump -d ./test | grep \"<main>:\"", "r");

  if (fp == NULL) {
    puts("cannot get main address");
  }
  else {
    char line[256];

    if (fgets(line, sizeof(line), fp) == NULL) {
      puts("no address !");
      pclose(fp);
    }
    else {
      unsigned long long main_addr;

      pclose(fp);
      errno = 0;
      main_addr = strtoull(line, NULL, 16);

      if (errno != 0)
        puts("invalid address");
      else {
        int found = 0;
        int status;

        while(wait(&status), WIFSTOPPED(status))
        {
          struct user_regs_struct regs;

          ptrace(PTRACE_GETREGS, pid, 0, &regs);

          if (found |= (regs.rip == main_addr)) {
            long instruction = ptrace(PTRACE_PEEKTEXT, pid, regs.rip, 0);

            printf("%llx %16lx\n", regs.rip, instruction);
          }

          ptrace(PTRACE_SINGLESTEP, pid, 0, 0);
        }
      }
    }
  }
}
void debugger(pid_t pid)
{
  FILE * fp = popen("objdump -d ./test | grep \"<main>:\"", "r");

  if (fp == NULL) {
    puts("cannot get main address");
  }
  else {
    char line[256];

    if (fgets(line, sizeof(line), fp) == NULL) {
      puts("no address !");
      pclose(fp);
    }
    else {
      unsigned long long main_addr;

      pclose(fp);
      errno = 0;
      main_addr = strtoull(line, NULL, 16);

      if (errno != 0)
        puts("invalid address");
      else {
        int found = 0;
        int status;
        unsigned long prev_instr;
        long long prev_addr = -1;

        while(wait(&status), WIFSTOPPED(status))
        {
          struct user_regs_struct regs;

          ptrace(PTRACE_GETREGS, pid, 0, &regs);

          if (found |= (regs.rip == main_addr)) {
            unsigned long instruction =
              (unsigned long) ptrace(PTRACE_PEEKTEXT, pid, regs.rip, 0);

            if (prev_addr != -1) {
              /* longest instruction has 15 bytes on x86 */
              int len = ((regs.rip > prev_addr) && ((regs.rip - prev_addr) <= 15))
                ? regs.rip - prev_addr : 100;

              printf("%llx ", prev_addr);
              while (prev_instr && len--) {
                printf("%02x ", (unsigned) (prev_instr & 0xff));
                prev_instr /= 256;
              }
              if (len > 15)
                puts(" (?)");
              else
                putchar('\n');
            }
            prev_instr = instruction;
            prev_addr = regs.rip;
          }

          ptrace(PTRACE_SINGLESTEP, pid, 0, 0);
        }
      }
    }
  }
}
400526 55 
400527 48 89 e5 
40052a bf d4 05 40 00 
40052f e8 cc fe ff ff bf da 05  (?)
400400 ff 25 12 0c 20 00 
400406 68 00 00 00 00 
40040b e9 e0 ff ff ff ff 25 0a  (?)
4003f0 ff 35 12 0c 20 00 
4003f6 ff 25 14 0c 20 00 0f 1f  (?)
7fe20cc1fe10 53 
7fe20cc1fe11 48 89 e3 
7fe20cc1fe14 48 83 e4 c0 
7fe20cc1fe18 48 2b 25 31 df 20 00 
7fe20cc1fe1f 48 89 04 24 
7fe20cc1fe23 48 89 4c 24 08 
...