【发布时间】:2019-12-30 20:22:47
【问题描述】:
我想将流程重定向到本地函数,然后使用 shellcode 返回到原始函数。
我定义了两个简单的函数并使用 objdump 来获取它们的汇编代码:
// unsigned char *g_code = "\x55\x48\x89\xe5\xb8\x2a\x00\x00\x00\x5d\xc3";
int g() {
return 42;
}
// unsigned char *f_code_original = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\xb8\x2a\x00\x00\x00\xc9\xc3";
int f() {
int x = g();
return 42;
}
在另一个文件中,我有一个函数,我想在 f 的两个指令之间调用:
void redirect() {
FILE *out = fopen("redirect.txt", "w");
fprintf(out, "REDIRECT WORKED");
fclose(out);
}
为此,我使用以下代码,使用 -fPIC -fno-stack-protector -z execstack 编译:
void f_func() {
unsigned char *f_code_original = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\xb8\x2a\x00\x00\x00\xc9\xc3";
unsigned char f_code_modified[] = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\xfb\xfe\xff\xff\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\x8b\x45\xfc\xc9\xc3";
int value = 0;
int (*f)() = (int (*)())f_code_modified;
value = f();
printf("%d\n", value);
}
如果我使用 f 的原始代码(我从 objdump 得到它),它就可以工作。 我想修改它以调用我的重定向函数,然后恢复当前执行。
汇编代码(用于 f_code_modified):
0: 55 push ebp
1: 48 dec eax
2: 89 e5 mov ebp,esp
4: 48 dec eax
5: 83 ec 10 sub esp,0x10
8: b8 00 00 00 00 mov eax,0x0 <==
d: e8 fb fe ff ff call 0xffffff0d <==
12: b8 00 00 00 00 mov eax,0x0
17: e8 00 00 00 00 call 0x1c
1c: 89 45 fc mov DWORD PTR [ebp-0x4],eax
1f: 8b 45 fc mov eax,DWORD PTR [ebp-0x4]
22: c9 leave
23: c3 ret
如果我直接从 main (int x = g(); redirect(); return 42;) 进行调用,这看起来很相似,但我认为调用指令在 d: e8 .. .. .. ..是相对于当前指令指针的。
如果我这样运行程序,它会出现分段错误。
问题:有没有办法可以在运行时找到当前指令指针,然后把shellcode写成\xe8\x??\x??\x??\x??调用函数重定向?我需要修改什么?我已经尝试过使用 -fPIC 并获取重定向地址(使用 &),但它不起作用。
【问题讨论】:
-
在您的情况下,
call指令使用相对于其位置的相对偏移量。当您将这段代码移动到不同的位置时,它会开始跳转到错误的位置。因此,您的呼叫需要一个带有绝对地址的不同形式。 -
尝试调试...或尝试使用二进制忍者的shellcode编译器插件
-
当然,你可以将目标函数的absolute地址嵌入到shellcode中。喜欢
mov eax, 0x12345678;call eax.
标签: c assembly code-injection shellcode