只是试图获取下面代码的 <__execve> 的汇编指令,因为我想构建 shell 生成操作码列表:
#include <stdio.h>
int main()
{
char *happy[2];
happy[0] = "/bin/sh";
happy[1] = NULL;
execve (happy[0], happy, NULL);
}
Objdump 给了我这个:
8053a20: 53 push %ebx
8053a21: 8b 54 24 10 mov 0x10(%esp),%edx
8053a25: 8b 4c 24 0c mov 0xc(%esp),%ecx
8053a29: 8b 5c 24 08 mov 0x8(%esp),%ebx
8053a2d: b8 0b 00 00 00 mov $0xb,%eax
8053a32: ff 15 a4 d5 0e 08 call *0x80ed5a4
8053a38: 3d 00 f0 ff ff cmp $0xfffff000,%eax
8053a3d: 77 02 ja 8053a41 <__execve+0x21>
8053a3f: 5b pop %ebx
8053a40: c3 ret
8053a41: c7 c2 e8 ff ff ff mov $0xffffffe8,%edx
8053a47: f7 d8 neg %eax
8053a49: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx
8053a50: 89 04 11 mov %eax,(%ecx,%edx,1)
8053a53: 83 c8 ff or $0xffffffff,%eax
8053a56: 5b pop %ebx
8053a57: c3 ret
8053a58: 90 nop
8053a59: 90 nop
8053a5a: 90 nop
从我读过的几篇文章来看,应该有一个整数0x80上面输出中的某处。为什么没有一个呢?
3.2 内核中是否有关于系统调用如何工作的重大变化,这些变化可能会影响 3-4 年前写的书中介绍的 shellcode 构建算法(特定寄存器加载等)?上面的转储看起来与“Shellcoders Handbook”或“Smash the Stack”中提供的输出非常不同
谢谢!
答案1
系统调用的实现很大程度上依赖于硬件 - 请参阅维基百科文章系统调用以及关于内核陷阱。在现代 x86 上,它似乎int 0x80
已被放弃,取而代之的是较新的SYSENTER
等人前一段时间。
对我来说 __execve 看起来像这样:
000000000040f7c0 <__execve>:
40f7c0: b8 3b 00 00 00 mov $0x3b,%eax
40f7c5: 0f 05 syscall
40f7c7: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax
40f7cd: 77 02 ja 40f7d1 <__execve+0x11>
40f7cf: f3 c3 repz retq
40f7d1: 48 c7 c2 c0 ff ff ff mov $0xffffffffffffffc0,%rdx
40f7d8: f7 d8 neg %eax
40f7da: 64 89 02 mov %eax,%fs:(%rdx)
40f7dd: 48 83 c8 ff or $0xffffffffffffffff,%rax
40f7e1: c3 retq
40f7e2: 66 90 xchg %ax,%ax
40f7e4: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
40f7eb: 00 00 00
40f7ee: 66 90 xchg %ax,%ax
注意syscall
开头的。该函数的确切形式取决于编译标志和编译代码的体系结构 - 请参阅gcc
选项-mtune
和-march
。
编辑:其他有趣的链接: