反汇编2种printfs格式的代码

时间:2017-03-17 22:50:35

标签: c disassembly

我试图通过解密代码来理解seg错误的推理。

Case 1.
char *p = NULL;
printf("%s", p);
O/p: No crash. it give me null. Further looking at disassemble code, it shows this one.


Dump of assembler code for function printf@plt:
        0x00000000004003b8 <+0>:     jmpq   *0x2004aa(%rip)        # 0x600868 <printf@got.plt>
        0x00000000004003be <+6>:     pushq  $0x0
        0x00000000004003c3 <+11>:    jmpq   0x4003a8
    End of assembler dump.

虽然我正在努力进一步超越这一点,但不知道如何转向下一组说明以及它究竟是什么。

案例2。

int
main()
{
    char *p = NULL;
    printf("%s\n", p);
}

导致seg错误。 反汇编代码:

Dump of assembler code for function main:

0x00000000004004c4 <+0>:     push   %rbp
0x00000000004004c5 <+1>:     mov    %rsp,%rbp
0x00000000004004c8 <+4>:     sub    $0x10,%rsp
0x00000000004004cc <+8>:     movq   $0x0,-0x8(%rbp)
0x00000000004004d4 <+16>:    mov    -0x8(%rbp),%rax
0x00000000004004d8 <+20>:    mov    %rax,%rdi
0x00000000004004db <+23>:    callq  0x4003b8 <puts@plt>
0x00000000004004e0 <+28>:    leaveq
0x00000000004004e1 <+29>:    retq
End of assembler dump.
(gdb) disassemble puts
Dump of assembler code for function puts@plt:
    0x00000000004003b8 <+0>:     jmpq   *0x2004aa(%rip)        # 0x600868 <puts@got.plt>
    0x00000000004003be <+6>:     pushq  $0x0
    0x00000000004003c3 <+11>:    jmpq   0x4003a8
End of assembler dump.

请你帮我确定哪些汇编指令导致seg故障?

1 个答案:

答案 0 :(得分:1)

0x00000000004003b8 <+0>:     jmpq   *0x2004aa(%rip)        # 0x600868 <puts@got.plt>

这里有两个重要的代码字:

GOT -> Global Offset Table
PLT -> Procedure Linkage Table

这表示它从动态库调用puts。仅在拆卸时才知道put的地址。必须运行程序才能允许库函数的动态链接器绑定地址到PLT插槽。

您需要的是:

(gdb) start
Temporary breakpoint 1 at 0x40053e: file c.c, line 9.
Starting program: /home/josef/DEVEL/test/test/a.out 

Temporary breakpoint 1, main () at c.c:9
9           char *p = NULL;
(gdb) disassemble main
Dump of assembler code for function main:
   0x0000000000400536 <+0>:     push   %rbp
   0x0000000000400537 <+1>:     mov    %rsp,%rbp
   0x000000000040053a <+4>:     sub    $0x10,%rsp
=> 0x000000000040053e <+8>:     movq   $0x0,-0x8(%rbp)
   0x0000000000400546 <+16>:    mov    -0x8(%rbp),%rax
   0x000000000040054a <+20>:    mov    %rax,%rdi
   0x000000000040054d <+23>:    callq  0x400410 <puts@plt>
   0x0000000000400552 <+28>:    leaveq 
   0x0000000000400553 <+29>:    retq   
End of assembler dump.
(gdb) disassemble puts
Dump of assembler code for function _IO_puts:
   0x00007ffff7a84d60 <+0>:     push   %r12
   0x00007ffff7a84d62 <+2>:     mov    %rdi,%r12
   0x00007ffff7a84d65 <+5>:     push   %rbp
   0x00007ffff7a84d66 <+6>:     push   %rbx
   0x00007ffff7a84d67 <+7>:     callq  0x7ffff7a9d9b0 <strlen>
   0x00007ffff7a84d6c <+12>:    mov    0x34fafd(%rip),%rbx        # 0x7ffff7dd4870 <stdout>
   0x00007ffff7a84d73 <+19>:    mov    %rax,%rbp
   0x00007ffff7a84d76 <+22>:    mov    (%rbx),%eax
   0x00007ffff7a84d78 <+24>:    mov    %rbx,%rdi
   0x00007ffff7a84d7b <+27>:    and    $0x8000,%eax
   0x00007ffff7a84d80 <+32>:    jne    0x7ffff7a84ddf <_IO_puts+127>
   0x00007ffff7a84d82 <+34>:    mov    0x88(%rbx),%r8
   ......

现在你看到puts内的内容了。您可以继续前进并反汇编strlen

(gdb) disassemble strlen
Dump of assembler code for function strlen:
   0x00007ffff7a9d9b0 <+0>:     pxor   %xmm8,%xmm8
   0x00007ffff7a9d9b5 <+5>:     pxor   %xmm9,%xmm9
   0x00007ffff7a9d9ba <+10>:    pxor   %xmm10,%xmm10
   0x00007ffff7a9d9bf <+15>:    pxor   %xmm11,%xmm11
   0x00007ffff7a9d9c4 <+20>:    mov    %rdi,%rax
   0x00007ffff7a9d9c7 <+23>:    mov    %rdi,%rcx
   0x00007ffff7a9d9ca <+26>:    and    $0xfff,%rcx
   0x00007ffff7a9d9d1 <+33>:    cmp    $0xfcf,%rcx
   0x00007ffff7a9d9d8 <+40>:    ja     0x7ffff7a9da40 <strlen+144>
   0x00007ffff7a9d9da <+42>:    movdqu (%rax),%xmm12
   0x00007ffff7a9d9df <+47>:    pcmpeqb %xmm8,%xmm12
   0x00007ffff7a9d9e4 <+52>:    pmovmskb %xmm12,%edx
   0x00007ffff7a9d9e9 <+57>:    test   %edx,%edx
   0x00007ffff7a9d9eb <+59>:    je     0x7ffff7a9d9f1 <strlen+65>
   ......

分析所有代码祝你好运:)