5

こんにちは、生のマシンコードをメモリにロードして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;
}

コンパイラの警告が表示されます:

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

プログラムがこのコードに到達していないので、アセンブラ コードが正常に動作しているかどうかを確認できません。

4

3 に答える 3

4

わかりました、コメントでの議論によると、これが答えです:)

メモリ領域は、システム ページ サイズに合わせる必要があります。posix_memalign() 呼び出しは、そのような場合にメモリを割り当てる正しい方法です:)

于 2010-03-13T10:16:39.467 に答える
1

すべての権限を使用 PROT_EXEC | PROT_READ | PROT_WRIT も不要で、ちょっと危険です。通常、PROT_WRITE は必要ありません。exec と read だけで十分です。

保護されたカーネルの中には、PROT_EXEC | を許可しないものもあります。PROT_WRIT。

于 2010-08-09T19:18:28.027 に答える