简体   繁体   English

C:从ram运行已编译的函数

[英]C : running a compiled function from ram

I'm working on a project that i need to load a simple exe file to a buffer and then call the entry point of the exe file from within the ram . 我正在一个项目中,我需要将一个简单的exe文件加载到缓冲区,然后从ram内调用exe文件的入口点。

i know that i can't load and run a very complicated exe file with a lot of dependencies from buffer but i think its possible to call an independent function of the exe (PE) file (like an empty main). 我知道我无法加载并运行一个非常复杂的exe文件,该文件具有很多来自缓冲区的依赖关系,但我认为可以调用exe (PE)文件的独立功能(例如一个空的main)。

to do so,i have to find the entry point address of exe file (its offset) and then cast that address (which is now loaded in a buffer) to a pointer-to-function and then call that, it probably would call the function loaded in ram but i don't know how to find the address . 为此,我必须找到exe文件的入口地址(其偏移量),然后将该地址(现在已加载到缓冲区中)转换为指向函数的指针,然后调用该函数,它可能会调用加载在ram中的函数,但我不知道如何找到地址。

this is what I've done so far : 到目前为止,这是我所做的:

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

i think it's pretty much clear from the code what im trying to do . 我认为从代码中可以很清楚地知道我要做什么。

here is a link that tries to do the same thing for meterpreter (the idea is the same): 这是一个尝试为meterpreter做相同事情的链接(想法是相同的):

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

i'd appreciate any help . 我将不胜感激。

Thanks 谢谢

Chances are you are probably tring to solve the wrong problem. 您可能很想解决错误的问题。 If you are using an operating system (say Windows or Linux), then the simplest thing to do is just call the system function, ie 如果您使用的是操作系统(例如Windows或Linux),那么最简单的方法就是调用system函数,即

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

That will run the exe. 这将运行exe。

Note that pretty much every exe that is built to run on a OS is NOT trivial to just load into memory and run. 请注意,几乎所有为在OS上运行而构建的exe都不是简单的加载到内存并运行。 That is because the start-up code for any C program does NOT start with main() like you might think. 那是因为任何C程序的启动代码都不会像您想象的那样以main()开头。 It starts at a deeper level, that involves loading runtime libraries, allocating memory and eventually the run time will call main() . 它从更深的层次开始,涉及加载运行时库,分配内存,最终运行时将调用main()

That said, if you are not dealing with a real exe file (exe files are PE format on Windows and ELF on Linux), but instead it is a hand compiled binary image, then what you are doing will work, assuming the code was compile with PIC options to make the code relocatable, the code does not depend on the C runtime libary or any dynamically loaded library and the entry point is the first address of the binary file. 就是说,如果您不处理真正的exe文件(exe文件在Windows上是PE格式 ,在Linux上是ELF),但是它是一个手工编译的二进制映像,那么假设代码已编译,那么您正在执行的操作就可以了如果使用PIC选项使代码可重定位,则代码不依赖于C运行时库或任何动态加载的库,并且入口点是二进制文件的第一个地址。 However, I can tell you, no one does it like this. 但是,我可以告诉你,没有人会这样。

An "exe" file is more appropriate called Portable Executable . “ exe”文件更合适,称为Portable Executable The entry point (please note that this most probably not main() ) is in the OpationalHeader as the attribute AddressOfEntryPoint. 入口点(请注意,这很可能不是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();

The chances that the application you want to execute works without fixed relocations or imports are basically infinitesimal -- so you should use an existing solution. 您想要执行的应用程序在没有固定重定位或导入的情况下运行的机会基本上是无限的,因此您应该使用现有的解决方案。

Also keep in min that most PC running now have Data Execution Prevention enabled, so you should allocate with VirtualAllocate() 另外,请记住,大多数现在运行的PC都启用了数据执行保护 ,因此您应该分配VirtualAllocate()

You could consider using a dynamic library if you want to load a function dynamically. 如果要动态加载函数,可以考虑使用动态库。 You'll need to build a .so file instead of a exe file. 您需要构建.so文件而不是exe文件。 On Linux, this is the dlopen and dlsym API. 在Linux上,这是dlopendlsym API。

http://man7.org/linux/man-pages/man3/dlopen.3.html http://man7.org/linux/man-pages/man3/dlopen.3.html

http://man7.org/linux/man-pages/man3/dlsym.3.html http://man7.org/linux/man-pages/man3/dlsym.3.html

On Windows, you'll want LoadLibrary ... 在Windows上,您需要LoadLibrary ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM