Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading MachineCode From File Into Memory and Executing in C -- mprotect Failing

Hi I'm trying to load raw machine code into memory and run it from within a C program, right now when the program executes it breaks when trying to run mprotect on the memory to make it executable. I'm also not entirely sure that if the memory does get set right it will execute. I am currently running this on Ubuntu Linux x86 (Maybe the problem is Ubuntu's over-protection?)

What I currently have is the following:

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

I do get the compiler warning:

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

I've not gotten the program to reach this code yet so I am unable to see if my assembler code is doing what it should.

like image 515
ChartreuseKitsune Avatar asked Mar 13 '10 09:03

ChartreuseKitsune


2 Answers

Ok, here's the answer, according to our discussion in the comments :)

The memory region should be aligned to the system page size. posix_memalign() call is a right way to allocate memory in such case :)

like image 156
Roman Dmitrienko Avatar answered Nov 14 '22 22:11

Roman Dmitrienko


Add an 0xc3 (return instruction) after your 0x90 (noop) bytes. Your program might be crashing because it runs off the end of the NOOPs and either into uninitialized memory, who knows what lurks there, or into the end of the executable page. I can't really tell without looking at what's in the file you're loading.

BTW strace is very useful for these sorts of programs. It would have told you what the error in mprotect was.

like image 44
Bernd Jendrissek Avatar answered Nov 14 '22 23:11

Bernd Jendrissek