您能否向我推荐 Shellcoder 手册中提到的操作系统,因为我在运行其中提到的 ELF 文件时经常遇到问题(请参阅下面的错误)。我知道为了克服这些错误,我必须输入命令或参数,但我也这样做了,但在汇编级别上我仍然没有得到与书中相同的输出。
我正在运行一个文件来演示ubuntu 4.15.0-106-通用(我正在使用的测试环境)并且汇编级别的很多东西都是不同的。
下面的差异将帮助您理解我的问题。下面的代码来自本书重点介绍的int 0x80 instruction
。
代码:
main()
{
exit(0);
}
这是书中的o/p:
[slap@0day root] gdb exit
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are welcome to change it and/or distribute copies of it under certain
conditions. Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for
details.
This GDB was configured as “i386-redhat-linux-gnu”...
(gdb) disas _exit
Dump of assembler code for function _exit:
0x0804d9bc <_exit+0>: mov 0x4(%esp,1),%ebx
0x0804d9c0 <_exit+4>: mov $0xfc,%eax
0x0804d9c5 <_exit+9>: int $0x80
0x0804d9c7 <_exit+11>: mov $0x1,%eax
0x0804d9cc <_exit+16>: int $0x80
0x0804d9ce <_exit+18>: hlt
0x0804d9cf <_exit+19>: nop
End of assembler dump.
这是我的测试环境中的o/p(ubuntu 4.15.0-106-generic 16.04.1):
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5)7.11.1
This GDB was configured as "i686-linux-gnu"
gdb-peda$ disas exit
Dump of assembler code for function exit@plt:
0x080482e0 <+0>: jmp DWORD PTR ds:0x804a00c
0x080482e6 <+6>: push 0x0
0x080482eb <+11>: jmp 0x80482d0
End of assembler dump.
int 0x80
正如您所看到的,与书中不同的是,没有关于测试环境的说明。
错误:
检测到堆栈崩溃--- 为了克服这个错误,我使用了(-fno-stack-protector),它仅有时有效。
或者
还分段错误(核心转储)--- 当书中甚至没有提到它时,我收到此错误,我知道它是我正在使用的 Linux 版本,必须针对书中的内容进行修补。
那么你能给我推荐书中提到的环境/操作系统吗?或者有什么方法可以编译书中提到的二进制文件以在我的测试环境(Linux 4.15.0-106-generic #107~16.04.1-Ubuntu)上运行?
编辑:
用于编译 elf 文件的命令:
gcc -m32 -fno-stack-protector exit.c -o exit
也尝试过这个,
gcc -static -m32 -fno-stack-protector exit.c -o exit
添加-static
在汇编中给出了这个:
gdb-peda$ disas exit
Dump of assembler code for function exit:
0x0804e440 <+0>: sub esp,0x10
0x0804e443 <+3>: push 0x1
0x0804e445 <+5>: push 0x80eb070
0x0804e44a <+10>: push DWORD PTR [esp+0x1c]
0x0804e44e <+14>: call 0x804e320 <__run_exit_handlers>
End of assembler dump.
答案1
在本书的输出中,您显示了它们的反汇编_exit
:
This GDB was configured as “i386-redhat-linux-gnu”... (gdb) disas _exit
但在你的实验中,你反汇编了exit
(注意缺少的前导下划线):
This GDB was configured as "i686-linux-gnu" gdb-peda$ disas exit
这是两个独立的函数,因此请确保您使用的是_exit
.这个答案解释了两者之间的区别:https://unix.stackexchange.com/a/5375/90691
另外,在你的输出中我注意到exit@plt
; “plt”代表“过程链接表”,它是解析动态链接符号的一部分。如果您使用 进行编译-static
,这将导致编译器静态链接(而不是动态链接)您的程序,因此您最终不会得到该级别的间接寻址。这个答案提供了更详细的解释:https://unix.stackexchange.com/a/256852/90691
如果您不使用-static
书中的程序进行编译并尝试反汇编该程序,您可能会看到:
(gdb) disassemble _exit
No symbol "_exit" in current context.
那是因为您的程序中没有任何内容引用该符号_exit
。编译-static
可能会解决该问题。如果没有,您可以修改程序以调用_exit
而不是exit
.
最后,i386-redhat-linux-gnu
VS i686-linux-gnu
。前者适用于 386 处理器;后者适用于 686 处理器。两者都是 32 位,所以如果幸运的话,您应该可以使用 686 工具链。