2017-01-02 49 views
-1

我工作的一个项目,我需要一个简单的exe文件加载到一个缓冲区,然后从RAM中调用exe文件的入口点运行的编译功能。C:从RAM

我知道我无法加载并运行一个非常复杂的exe文件,但缓冲区有很多依赖关系,但我认为它有可能调用exe (PE)文件的独立函数(如空主)。我必须找到exe文件的入口点地址(它的偏移量),然后将该地址(现在加载到缓冲区中)转换为指向函数的指针,然后调用它,它可能会调用在RAM中加载的函数,但我不知道如何找到地址。

这是我迄今所做的:

int main(){ 

    void (* function)(); 
    unsigned char* buffer; 
    FILE* fp; 
    size_t size; 
    char* path = "address of the file"; 
    fp = fopen(path, "rb"); 
    fseek(fp, 0, SEEK_END); 
    size = ftell(fp);   /*calc the size needed*/ 
    fseek(fp, 0, SEEK_SET); 
    buffer = (unsigned char *) malloc(size); 
    fclose(fp); 

    /*problem : i have to sum the buffer address with that offset here*/ 
    function = (void (*)())(buffer); 

    function(); 

    return 0; 
} 

我认为这是非常清楚的代码什么即时尝试做。

这里是试图做同样的事情meterpreter(的想法是一样的)链接:

https://github.com/rsmudge/metasploit-loader/blob/master/src/main.c

我会很感激的任何帮助。

谢谢

+0

见http://stackoverflow.com/questions/8723039/c-how-to-run-an -exe-file-which-contents-are-stored-in-a-char-array以及本文https://www.blackhat.com/presentations/bh-usa-07/Harbour/Whitepaper/bh-usa -07-harbor-WP.pdf以及http://stackoverflow.com/questions/35538​​75/load-an-exe-file-and-run-it-from-memory –

+1

@RichardChambers - 这两个SO答案都是对于C#不是C –

回答

3

的 “exe” 文件是比较合适的叫Portable Executable。入口点(请注意,这很可能不是main())是OpationalHeader作为属性AddressOfEntryPoint。

PIMAGE_DOS_HEADER dos; 
PIMAGE_NT_HEADERS pe; 
void (* function)(); 

dos = (PIMAGE_DOS_HEADER)data; 
if (dos->e_magic != IMAGE_DOS_SIGNATURE) { 
    return NULL; 
} 

pe = (PIMAGE_NT_HEADERS)&((const unsigned char *)(buffer))[dos->e_lfanew]; 
if (pe->Signature != IMAGE_NT_SIGNATURE) { 
    return NULL; 
} 

function = pe->OptionalHeader.AddressOfEntryPoint + buffer; 
function(); 

你想要的应用程序没有固定的搬迁或进口执行工作的几率基本上无穷小 - 所以你应该使用现有的解决方案。

也请分钟,大多数PC现在运行启用Data Execution Prevention,所以你应该VirtualAllocate()

4

你很可能正在解决错误的问题。如果您正在使用的操作系统(比如Windows或Linux),那么最简单的事情做的仅仅是调用system功能,即

char* path = "address of the file"; 
system(path); 

将运行exe文件。

需要注意的是,几乎每一个被建在一个操作系统上运行的exe是不平凡的,只是加载到内存并运行。这是因为任何C程序的启动代码都不会像您想象的那样以main()开头。它开始在更深的层次,这涉及加载运行库,分配内存,并最终在运行时将调用main()。这就是说,如果你没有处理一个真正的EXE文件(EXE文件在Windows上是PE format,在Linux上是ELF),但是它是一个手工编译的二进制图像,那么你正在做的工作,假设代码是用PIC选项编译使代码重定位,代码不依赖于C运行时libary或任何动态加载库和入口点是二进制文件的第一个地址。但是,我可以告诉你,没有人这样做。

+0

我知道我在做什么是错误的。我的最终目标是能够从套接字接收一个exe文件并从缓冲区中直接运行它。以上仅为例子。但无论如何,请你提供关于最后一段的更多细节?!如果我用PIC选项编译我的代码,我应该如何找到入口点地址?谢谢。 –

+0

为什么不把exe文件保存到'/ tmp'并在其上调用'system()'? –

+0

我不想在硬盘上留下任何痕迹。我不希望我的客户因某些原因拥有可执行文件。 –