我正在写一个程序,加载和执行代码从文件。 但我有一个问题:“写”系统调用不起作用。 代码成功加载并执行,但不在屏幕上显示任何文本。
加载代码的程序:
#include < stdio.h > #include < stdlib.h > int main(int argc,char* argv[]) { unsigned int f_size = 0; unsigned char* code_buf = NULL; void (*func_call)(void) = NULL; if(argc < 2) { printf("Usage: %s <FILE>\n",argv[0]); return 1; } FILE* fp = fopen(argv[1],"rb"); if(!fp) { printf("Error while opening this file: %s\n",argv[1]); return 1; } unsigned int fsize = 0; fseek(fp,0,SEEK_END); fsize = ftell(fp); fseek(fp,0,SEEK_SET); if(fsize < 4) { printf("Code size must be > 4 bytes\n"); return 1; } code_buf = (unsigned char*) malloc(sizeof(unsigned char)*fsize); if(fread(code_buf,fsize,1,fp)<1) { printf("Error while reading file: %s\n",argv[1]); free(code_buf); return 1; } func_call = (void (*)(void)) code_buf; printf("[EXEC] Binary is loaded\n" "\tFirst 2 bytes: 0x%x 0x%x\n" "\tLast 2 bytes: 0x%x 0x%x\n", code_buf[0],code_buf[1], code_buf[fsize-2],code_buf[fsize-1]); printf("[EXEC] Starting code...\n"); (*func_call)(); printf("[EXEC] Code executed!\n"); free(code_buf); return 0; }
我试图通过这个程序执行的代码(test.s):
.text movl $4, %eax movl $1, %ebx movl $str, %ecx movl $5, %edx int $0x80 jmp end str: .string "test\n" end: ret
这是我如何编译它:
gcc -c test.s objcopy -O binary test.o test.bin
解决了 ,感谢@Christoph
有工作代码:
.text call start str: .string "test\n" start: movl $4, %eax movl $1, %ebx pop %ecx movl $5, %edx int $0x80 ret
你的方法不能工作:shellcode必须是位置无关的,但你的代码引用绝对地址str
。 无条件跳转也可以是相对的或绝对的:确保你得到相对版本(x86上的操作码EB和E9)。
有关更多信息,请参阅编写可移植Shell代码的技巧 。
你不指定你的CPU的细节,但是你可能会碰到NX位 。 我希望你的代码SEGFAULT,而不是运行完成。
这正是在Intel Xeon E5410上运行的机器(Linux 2.6.32-28-generic#55-Ubuntu SMP Mon Jan 10 23:42:43 UTC 2011 x86_64 GNU / Linux)上发生的情况。
有一件事:你应该打开文件为二进制。
FILE* fp = fopen(argv[1],"rb");
为什么不使用.so文件来动态加载你的代码? 你正在测试一个安全场景还是真的试图动态加载和运行代码?
在这里阅读如何将代码编译为.so,在程序中动态加载它,并执行导出的函数。
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html