将MachineCode从文件加载到内存并执行C – mprotect失败

嗨,我正在尝试将原始机器代码加载到内存中并在C程序中运行它,现在当程序执行时,它试图在内存上运行mprotect以使其可执行时中断。 我也不完全确定如果内存设置正确,它将执行。 我目前在Ubuntu Linux x86上运行它(也许问题是Ubuntu的过度保护?)

我目前拥有以下内容:

#include  #include  #include  int main ( int argc, char **argv ) { FILE *fp; int sz = 0; char *membuf; int output = 0; fp = fopen(argv[1],"rb"); if(fp == NULL) { printf("Failed to open file, aborting!\n"); exit(1); } fseek(fp, 0L, SEEK_END); sz = ftell(fp); fseek(fp, 0L, SEEK_SET); membuf = (char *)malloc(sz*sizeof(char)); if(membuf == NULL) { printf("Failed to allocate memory, aborting!\n"); exit(1); } memset(membuf, 0x90, sz*sizeof(char)); if( mprotect(membuf, sz*sizeof(char), PROT_EXEC | PROT_READ | PROT_WRITE) == -1) { perror("mprotect"); printf("mprotect failed!!! aborting!\n"); exit(1); } if(!(fread(membuf, sz*sizeof(char), 1, fp))) { perror("fread"); printf("Read failed, aborting!\n"); exit(1); } __asm__ ( "call %%eax;" : "=a" (output) : "a" (membuf) ); printf("Output = %x\n", output); return 0; } 

我收到编译器警告:

 /tmp/ccVnhHak.s: Assembler messages: /tmp/ccVnhHak.s:107: Warning: indirect call without `*' 

我没有得到程序来达到这个代码,所以我无法看到我的汇编代码是否正在做它应该做的事情。

好的,这是答案,根据我们在评论中的讨论:)

内存区域应与系统页面大小对齐。 posix_memalign()调用是在这种情况下分配内存的正确方法:)

在0x90(noop)字节后添加0xc3(返回指令)。 你的程序可能会崩溃,因为它运行在NOOP的末尾,并且运行到未初始化的内存,谁知道潜伏在那里,或者进入可执行页面的末尾。 如果不查看您正在加载的文件中的内容,我无法分辨。

BTW strace对于这些类型的程序非常有用。 它会告诉你mprotect中的错误是什么。

使用所有权限PROT_EXEC | PROT_READ | PROT_WRIT也不需要,有点危险。 你一般不需要PROT_WRITE,只需exec和read即可。

一些安全的内核甚至不允许PROT_EXEC | PROT_WRIT。