我正在阅读Jon Erickson的“Hacking:剥削艺术”,并在我的Kali Linux系统(64位)中按照本书中的示例进行了阅读。
我写了一个简单的C程序:
#include<stdio.h>
int main()
{
int i;
for(i=0;i<10;i++)
{
printf("Hello");
}
}
使用objdump和gdb检查可执行文件后,我发现了一些奇怪的东西。
如图所示,主要功能在“0x000000000000063a”。
但是gdb“run”命令之后的断点信息,似乎程序停在63e而不是63a。
另一个特殊的事情是指令指针(rip)中的值是0x55555555463e。
不应该是0x000000000000063a吗?
那些5
来自哪里?
答案 0 :(得分:1)
如果您没有设置星号,GDB会为函数的有用代码设置断点。它省略了函数的所有准备(序幕)。为清楚起见,请尝试调试以下代码:
#include <stdio.h>
int main()
{
int i=10;
i++;
return 0;
}
Gdb会话:
(gdb) b main
Breakpoint 1 at 0x80483e1
(gdb) b *main
Breakpoint 2 at 0x80483db
(gdb) r
Starting program: /home/src/main
Breakpoint 2, 0x080483db in main ()
(gdb) disas
Dump of assembler code for function main:
=> 0x080483db <+0>: push ebp
0x080483dc <+1>: mov ebp,esp
0x080483de <+3>: sub esp,0x10
0x080483e1 <+6>: mov DWORD PTR [ebp-0x4],0xa
0x080483e8 <+13>: add DWORD PTR [ebp-0x4],0x1
0x080483ec <+17>: mov eax,0x0
0x080483f1 <+22>: leave
0x080483f2 <+23>: ret
End of assembler dump.
(gdb) c
Continuing.
Breakpoint 1, 0x080483e1 in main ()
(gdb) disas
Dump of assembler code for function main:
0x080483db <+0>: push ebp
0x080483dc <+1>: mov ebp,esp
0x080483de <+3>: sub esp,0x10
=> 0x080483e1 <+6>: mov DWORD PTR [ebp-0x4],0xa
0x080483e8 <+13>: add DWORD PTR [ebp-0x4],0x1
0x080483ec <+17>: mov eax,0x0
0x080483f1 <+22>: leave
0x080483f2 <+23>: ret
End of assembler dump.
在这种情况下,准备执行该函数的有用代码是:
0x080483db <+0>: push ebp
0x080483dc <+1>: mov ebp,esp
0x080483de <+3>: sub esp,0x10
main
中的第一条指令:
int i=10;
编译成:
mov DWORD PTR [ebp-0x4],0xa
当我们给出命令b main
但是如果我们使用带星号(指针)b *main
的命令,我们在函数的实际地址上设置一个断点(在序言的第一条指令上)。
在OP情况下,如果我们将断点设置为break *main
然后设置run
,则指令指针寄存器(rip
)将具有值0x55555555463a