C 2种printfs格式的反汇编代码
我正在试图理解用分解代码解释seg故障的原因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
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>
......