当我在main函数中执行shellcode时,它工作正常。但是,当我通过main调用的其他函数执行它时,会导致分段错误。据我所知,函数调用应该影响堆栈,而shellcode应该在堆中。我的代码有问题吗?
shellcode是由matesploit生成的,我使用qemu-arm运行该程序。
代码是:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
// msfvenom -p linux/armle/exec CMD=/bin/pwd -f c
unsigned char buf[] =
"\x01\x30\x8f\xe2\x13\xff\x2f\xe1\x78\x46\x0a\x30\x01\x90\x01"
"\xa9\x92\x1a\x0b\x27\x01\xdf\x2f\x62\x69\x6e\x2f\x70\x77\x64";
void runShellCode(){
unsigned char *pShellCode = (unsigned char *)calloc(1, 4096);
memcpy(pShellCode, buf, sizeof(buf));
(*(void(*)()) pShellCode)();
}
int main(int argc, char *argv[])
{
// uncomment these lines it will work perfectly fine
// unsigned char *pShellCode = (unsigned char *)calloc(1, 4096);
// memcpy(pShellCode, buf, sizeof(buf));
// (*(void(*)()) pShellCode)();
runShellCode();
return 0;
}
要编译和运行的cmd:
arm-linux-gnueabi-gcc test.c -o test_arm -static
qemu-arm test_arm
shellcode的反汇编代码(这是不正确的,因此我将其删除)
使用mmap()方法更新代码。但是,如果main()的参数为void
,则可以正常工作。当参数为int argc, char *argv[]
时,将导致SEGV。
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <sys/mman.h>
// msfvenom -p linux/armle/exec CMD=/bin/pwd -f c
unsigned char buf[] =
"\x01\x30\x8f\xe2\x13\xff\x2f\xe1\x78\x46\x0a\x30\x01\x90\x01"
"\xa9\x92\x1a\x0b\x27\x01\xdf\x2f\x62\x69\x6e\x2f\x70\x77\x64";
int main(int argc, char *argv[])
//int main(void)
{
unsigned char *pShellCode = (unsigned char *)calloc(1, 4096);
memcpy(pShellCode, buf, sizeof(buf));
void (*sc) () = NULL;
sc = mmap (0, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
memcpy (sc, pShellCode, 4096);
__builtin___clear_cache (sc, sc + sizeof(sc));
sc();
return 0;
}
答案 0 :(得分:0)
发布的代码导致:
untitled1.c:14:7: warning: ISO C forbids conversion of object pointer to function pointer type [-Wpedantic]
特定于Linux / Unix:
You need a memory page with `write execute` permissions.
See `mmap(2)` and `mprotect(2)`.
特定于Windows:
`VirtualAlloc()` function to reserve memory
`VirtualProtect()` function to mark as executable
applying, for instance, the `PAGE_EXECUTE_READ` flag.
you can cast the pointer to the allocated memory
to an appropriate function pointer type
and just call the function.
`VirtualFree()` function to clean up afterwards
关于您的“编辑”部分:
修改后的代码在通过编译器运行时会导致:
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:18:8: warning: ISO C forbids assignment between function pointer and ‘void *’ [-Wpedantic]
sc = mmap (0, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
^
untitled1.c:19:13: warning: ISO C forbids passing argument 1 of ‘memcpy’ between function pointer and ‘void *’ [-Wpedantic]
memcpy (sc, pShellCode, 4096);
^~
In file included from /usr/include/memory.h:29:0,
from untitled1.c:3:
/usr/include/string.h:42:14: note: expected ‘void * restrict’ but argument is of type ‘void (*)()’
extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
^~~~~~
untitled1.c:20:37: warning: pointer to a function used in arithmetic [-Wpointer-arith]
__builtin___clear_cache (sc, sc + sizeof(sc));
^
untitled1.c:20:30: warning: ISO C forbids passing argument 1 of ‘__builtin___clear_cache’ between function pointer and ‘void *’ [-Wpedantic]
__builtin___clear_cache (sc, sc + sizeof(sc));
^~
untitled1.c:20:30: note: expected ‘void *’ but argument is of type ‘void (*)()’
untitled1.c:20:34: warning: ISO C forbids passing argument 2 of ‘__builtin___clear_cache’ between function pointer and ‘void *’ [-Wpedantic]
__builtin___clear_cache (sc, sc + sizeof(sc));
^~
untitled1.c:20:34: note: expected ‘void *’ but argument is of type ‘void (*)()’
untitled1.c:11:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
int main(int argc, char *argv[])
^~~~
untitled1.c:11:26: warning: unused parameter ‘argv’ [-Wunused-parameter]
int main(int argc, char *argv[])
^~~~
Compilation finished successfully.
即使编译器输出:编译成功完成这并不意味着结果代码是正确的。这是什么意思是编译器为每个“警告”替换了一些“变通方法”。这并不意味着结果就是您想要的。
请阅读executable data,以获取有关如何执行数据的一些想法。