我正在编写一个程序,用于加载和执行文件中的代码。 但是我遇到了一个问题:“写”系统调用不起作用。 代码成功加载并执行,但屏幕上不显示任何文本。
加载代码的程序:
#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
答案 0 :(得分:9)
您的方法不起作用:shellcode必须与位置无关,但您的代码指的是绝对地址str
。无条件跳转也可以是相对的或绝对的:确保你获得相对的verison(x86上的操作码EB和E9)。
有关详细信息,请参阅The Technique of Writing Portable Shell Code。
答案 1 :(得分:3)
您没有指定CPU的详细信息,但可能与NX bit发生冲突。我希望你的代码能够进入SEGFAULT而不是完成。
这正是在我的盒子上运行的(Linux 2.6.32-28-generic#55-Ubuntu SMP Mon Jan 10 23:42:43 UTC 2011 x86_64 GNU / Linux)在Intel Xeon E5410上运行。
答案 2 :(得分:2)
有一件事:您应该将文件打开为二进制文件。
FILE* fp = fopen(argv[1],"rb");
答案 3 :(得分:1)
为什么不使用.so文件动态加载代码?您是在测试安全方案还是真的尝试动态加载和运行代码?
在这里阅读如何将代码编译为.so,在程序中动态加载它,并从中执行导出的函数。
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html