C 2种printfs格式的反汇编代码

C 2种printfs格式的反汇编代码,c,disassembly,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

我正在试图理解用分解代码解释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.
它导致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.
主函数的汇编程序代码转储: 0x0000000000404C4:推送%rbp 0x0000000000404C5:mov%rsp,%rbp 0x0000000000404C8:子$0x10,%rsp 0x00000000004004cc:movq$0x0,-0x8(%rbp) 0x000000000004004D4:mov-0x8(%rbp),%rax 0x0000000000404D8:mov%rax,%rdi 0x0000000000404DB:callq 0x4003b8 0x00000000004004e0:LEVEQ 0x0000000000404E1:retq 汇编程序转储结束。 (gdb)拆卸推杆 函数的汇编代码转储puts@plt: 0x00000000004003b8:jmpq*0x2004aa(%rip)#0x600868 0x00000000004003be:pushq$0x0 0x00000000004003c3:jmpq 0x4003a8 汇编程序转储结束。 你能帮我找出导致seg故障的汇编指令吗

0x00000000004003b8 <+0>:     jmpq   *0x2004aa(%rip)        # 0x600868 <puts@got.plt>
这表示它从动态库调用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
   ......

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

您发布的汇编代码都不相关。区别在于
printf(“%s\n”,p)
被编译成
put(p)
,而
printf(“%s”,p)
实际上调用
printf
printf
%s
本身检查空指针,并将其打印为
(null)
puts
盲目地取消引用它的参数,因此崩溃。我的一个朋友在采访中被问到这一点,他们告诉他在反汇编代码中要超越puts()和printf()。好的,那么找到
printf
puts
的实际代码。您发布的只是一个
jmp
说明。谢谢。但我对反汇编代码不太熟悉,也无法超越这一点,因为当我说反汇编时,这就是我得到的,但不知道如何获得完整的转储。(gdb)函数的汇编代码转储puts@plt:0x0000000000403B8:jmpq*0x2004aa(%rip)#0x600868 0x0000000000403BE:pushq$0x0 0x0000000000403C3:jmpq 0x4003A8我正在按照你提到的做,但我仍然得到相同的汇编代码。让我知道我错过了什么。(gdb)在0x4004cc:file printstr.c的第5行中断printstr.c:5断点6。(gdb)开始。。printstr.c:5(gdb)处的断点6,main()为函数main:0x000000000040404C4:推送%rbp..=>0x00000000004004cc:movq$0x0,-0x8(%rbp)。。(gdb)函数的汇编代码转储puts@plt:0x00000000004003b8:jmpq*0x2004aa(%rip)#0x600868如果不设置断点怎么办-只需打开gdb并运行
start
?确定-最后的解决方案。静态编译它
gcc yourfile.c-static
。然后所有的代码都将在executable.static中运行,但仍然不确定为什么在我执行类似步骤时另一个不工作。
GOT -> Global Offset Table
PLT -> Procedure Linkage Table
(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
   ......
(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>
   ......