直接执行二进制资源

时间:2010-08-20 07:51:50

标签: c resources executable portability

lpBuffer是指向(二进制)资源的第一个字节的指针。如何直接执行它而不将其转储到临时文件中?

HMODULE hLibrary;
HRSRC hResource;
HGLOBAL hResourceLoaded;
LPBYTE lpBuffer;

hLibrary = LoadLibrary("C:\\xyz.exe");
if (NULL != hLibrary)
{
    hResource = FindResource(hLibrary, MAKEINTRESOURCE(104), RT_RCDATA);
    if (NULL != hResource)
    {
        hResourceLoaded = LoadResource(hLibrary, hResource);
        if (NULL != hResourceLoaded)        
        {
            lpBuffer = (LPBYTE) LockResource(hResourceLoaded);            
            if (NULL != lpBuffer)            
            {                
                // do something with lpBuffer here            
            }
        }    
    }
    FreeLibrary(hLibrary);
}

3 个答案:

答案 0 :(得分:2)

Windows中没有内置的功能;你唯一的选择是CreateProcess,它带有一个EXE文件。

可以自己解析可执行文件格式。您将有效地重新创建LoadLibrary函数的功能。

以下是如何加载DLL并在其中调用函数的说明:http://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/。要使其适用于您的EXE,您将遵循相同的重定位和导入步骤。一旦你完成了,你就打电话给EXE的入口点。 (该教程解释了如何调用DLL的导出函数。)

根据EXE中的内容,您可能无法将其直接加载到现有流程中。例如,您自己的EXE执行各种Win32和C初始化代码,嵌入式EXE可能会尝试再次执行相同的初始化。如果这成为一个问题,你可以选择将嵌入式EXE放在自己的进程中;然后,您将回到创建临时文件并调用CreateProcess

答案 1 :(得分:1)

如果资源是PE文件,则无法使用AFAIK。如果它是一个简单的编译过程,请尝试Tim的技巧。

修改Tim的答案更新后,它是最完整的答案。

答案 2 :(得分:0)

以下是您必须让操作系统处理此问题的各种原因:

  • EXE不能简单地加载到内存中,然后立即执行。 必须在执行开始之前执行某些任务,例如在内存中布置段(包括设置堆栈),然后将机器指令中的内存引用调整到特定的内存位置(也称为重定位) ,(甚至可能动态加载DLL)等。

  • 这些天的EXE文件格式实际上是众多格式,您必须知道并相应地处理这些格式。它可能包含DOS的可执行代码(具有MZ / ZM标头),适用于Windows(PE - 可移植可执行文件),或适用于.NET(也是PE

  • 新处理器有无执行位(谷歌例如NX bit,它基本上禁止执行驻留在数据段中的代码。也就是说,如果你加载你的二进制资源(包含代码)进入内存,它将驻留在数据段中。如果您的处理器具有NX位功能,并且操作系统使用它,则不允许执行此代码。

出于所有这些原因(可能更多),最好让操作系统处理您的EXE文件。 在NX机制(或类似机制)的情况下,您没有其他选择,因为只有操作系统可以设置代码段。因此您可以摆脱上面指出的前两个问题通过选择功能较弱的可执行格式(如.com),但您无法摆脱在用户空间中运行的正在运行的程序中的NX机制。