Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将MachineCode从文件加载到内存并在C中执行--mprotect失败_C_Memory_Machine Code_Mprotect - Fatal编程技术网

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

将MachineCode从文件加载到内存并在C中执行--mprotect失败,c,memory,machine-code,mprotect,C,Memory,Machine Code,Mprotect,嗨,我正在尝试将原始机器代码加载到内存中,并从C程序中运行它,现在当程序执行时,它在内存中运行mprotect使其可执行时中断。我也不完全确定,如果内存设置正确,它是否会执行。我目前正在Ubuntu Linux x86上运行这个程序(可能问题是Ubuntu的过度保护?) 我目前的情况如下: #include <memory.h> #include <sys/mman.h> #include <stdio.h> int main ( int argc, cha

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

我目前的情况如下:

#include <memory.h>
#include <sys/mman.h>
#include <stdio.h>

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;
}

我还没有让程序访问此代码,因此我无法查看我的汇编代码是否正在执行它应该执行的操作。

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

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

在0x90(noop)字节后添加0xc3(返回指令)。您的程序可能会崩溃,因为它运行在NOOPs的末尾,或者进入未初始化的内存(谁知道那里隐藏着什么),或者进入可执行页面的末尾。如果不看你正在加载的文件,我真的说不出来


顺便说一句,strace对于这类程序非常有用。它会告诉你mprotect中的错误是什么。

使用所有perms PROT_EXEC | PROT_READ | PROT_write也不需要,而且有点危险。 一般来说,您不需要PROT_WRITE,只需要exec和read就足够了


一些安全内核甚至不允许PROT_EXEC | PROT_write

抱歉,这是针对x86 Linux特别是Ubuntu的。(我想Ubuntu的过度保护可能与此有关)这是什么样的失败?您是否尝试过在gdb下运行它并观察接下来会发生什么?它得到的失败是mprotect返回-1表示失败。我目前不确定如何从mprotect获取特定的错误代码,以便找到错误。显然,errno设置了它,但我不知道我需要如何访问它。
如果(mprotect(membuf,sz*sizeof(char),PROT|u EXEC | PROT|u READ | PROT|u WRITE)=-1{perror(“mprotect”)}
您可以使用perror()作为快速获取错误描述的方法,因此它必须以我假设的页面大小的倍数进行分配,而不是从一个文件的纵向,如果我得到它的权利,只有地址是对齐的,而不是大小。大小是以字节为单位的(根据人),好的,似乎已经通过了mprotect错误。使用:membuf=(char)memalign(pagesize,szsizeof(char));现在mprotect不再失败了,有没有关于代码为什么会产生segfault的猜测,gdb在中显示0x0804b004??(). 我正在向它传递一个包含有效字节码的文件,而不是一个ELF@Chartreuse:您需要在GDB中执行单个指令步骤
si
。从外观上看,您通过了第一条指令,因为地址不是以
0
结尾。您可能没有希望获得符号,因此它将是
??()
,但这并不是很糟糕。在尝试加载目标代码之前,请在其他地方调试它,仔细检查您的环境,如果遇到问题,请提出新问题。
/tmp/ccVnhHak.s: Assembler messages:
/tmp/ccVnhHak.s:107: Warning: indirect call without `*'