我有以下程序:
void main1() {
((void(*)(void)) (0xabcdefabcdef)) ();
}
我用以下命令创建它:
clang -fno-stack-protector -c -static -nostdlib -fpic -fpie -O0 -fno-asynchronous-unwind-tables main.c -o shellcode.o
ld shellcode.o -o shellcode -S -static -dylib -e main1 -order_file order.txt
gobjcopy -O binary --only-section=.text shellcode shellcode.output
程序集如下所示:
//
// ram
// ram: 00000000-00000011
//
**************************************************************
* FUNCTION *
**************************************************************
undefined FUN_00000000()
undefined AL:1 <RETURN>
FUN_00000000
00000000 55 PUSH RBP
00000001 48 89 e5 MOV RBP,RSP
00000004 48 b8 ef MOV RAX,0xabcdefabcdef
cd ab ef
cd ab 00 00
0000000e ff d0 CALL RAX
00000010 5d POP RBP
00000011 c3 RET
由于不需要{@ {1}},PUSH RBP
和MOV RBP,RSP
指令,我该如何对其进行删除?
如果我用以下代码行汇编程序,就可以做到这一点:
POP RBP
以及以下构建命令:
.globl start
start:
movq $0xabcdefabcdef, %rax
call *%rax
ret
和生成的程序集:
clang -static -nostdlib main.S -o crashme.o
gobjcopy -O binary --only-section=.text crashme.o crashme.output
但是我更愿意编写C代码而不是汇编代码。
答案 0 :(得分:3)
您忘记启用优化。任何优化级别(例如-O3
都会启用-fomit-frame-pointer
。
尽管如此,它也会将尾调用最优化为jmp
而不是call
/ ret
。如果出于某种原因需要避免这种情况,也许可以在默认的-fomit-frame-pointer
上使用-O0
。
对于shellcode,您可能希望-Os
针对代码大小进行优化。甚至c的-Oz
;这样做的副作用是,通过使用0
/ push imm8
而不是pop reg
在寄存器中放置较小的常量,可以避免机器代码中的某些mov reg, imm32
字节。>