【发布时间】:2020-04-10 16:34:26
【问题描述】:
我正在为 uni 做一个共享的内存分配,我已经“借用”和“按摩”了一些我在我在这里和其他地方读过的帖子中看到的 shellcode。我已经能够构建一个在我的 MacBook (Mojave) 上运行的示例,并且几乎可以满足我的需求。
但是,由于我没有在 OS 环境(本例中为 MacOS)中进行汇编编程的经验,并且由于我不完全理解下面的汇编,因此我需要一些帮助来克服我的最后一个问题。
在我的 C 样板包装器中,我有一个循环定期调用我的 shellcode,但该循环只执行一次迭代。这使我得出结论,第二个syscall(在下面的代码中)正在执行exit 0,从而终止了进程。
如何将程序集修改为 return 而不是 exit?
注意如果被问到,我可以发布有关我正在使用的包装器代码和工具的更多信息。
bits 64
Section .text
global start
start:
jmp short MESSAGE ;00000000 EB24 jmp short 0x26
GOBACK:
mov eax, 0x2000004 ;00000002 B804000002 mov eax,0x2000004 ; write
mov edi, 0x1 ;00000007 BF01000000 mov edi,0x1
lea rsi, [rel msg] ;0000000C 488D3518000000 lea rsi,[rel 0x2b]
mov edx, 0xf ;00000013 BA0F000000 mov edx,0xf
syscall ;00000018 0F05 syscall
mov eax,0x2000001 ;0000001A B801000002 mov eax,0x2000001 ;exit
mov edi,0x0 ;0000001F BF00000000 mov edi,0x0
syscall ;00000024 0F05 syscall
MESSAGE:
call GOBACK
msg: db "Hello, world!", 0dh, 0ah
.len: equ $ - msg
这是我的 C 样板代码,其中包括上面的 shellcode。
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
const char shellcode[] = "\xeb\x24\xb8\x04\x00\x00\x02\xbf\x01\x00\x00\x00\x48\x8d\x35\x18\x00\x00\x00\xba\x0f\x00\x00\x00\x0f\x05\xb8\x01\x00\x00\x02\xbf\x00\x00\x00\x00\x0f\x05\xe8\xd7\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x77\x6f\x72\x6c\x64\x21\x0d\x0a";
int main(int argc, char **argv)
{
void *mem = mmap(0, sizeof(shellcode), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
memcpy(mem, shellcode, sizeof(shellcode));
mprotect(mem, sizeof(shellcode), PROT_READ|PROT_WRITE|PROT_EXEC);
for (int i = 0; i < 10; i++) {
int (*func)();
func = (int (*)())mem;
(int)(*func)();
sleep(5);
}
munmap(mem, sizeof(shellcode));
return 0;
}
【问题讨论】:
-
你知道你想
return吗? -
如果你想从中
ret,你只是在用机器代码而不是asm编写一个函数。如果您将此代码作为缓冲区溢出的一部分注入,这将不会起作用,因为它不会在堆栈上使用返回地址调用(除非您的有效负载包含额外的返回地址)。 -
@PeterCordes,是的,我明白你的意思。只是我有一段时间没有做任何汇编级编码,我不确定是否需要系统调用才能返回。
-
查看编译器为整个函数生成的代码。这就是
ret指令的用途! How to remove "noise" from GCC/clang assembly output?(使用系统调用来修改你自己线程的架构状态,比如设置程序计数器 (RIP),会非常慢。)
标签: c macos assembly shellcode