【问题标题】:Writing to program memory in hex editor and reading programmatically在十六进制编辑器中写入程序存储器并以编程方式读取
【发布时间】:2012-10-31 23:16:52
【问题描述】:

我有 .exe 应用程序和其他一些文件。我想要做的是将这个其他文件写入 .exe 文件的末尾。 .exe 文件应该在它的内存中找到这个文件的地址,从那里读取它并做一些事情。

我能够访问我之前写入内存的文件的地址,但是当我尝试从那里读取时,我得到了拒绝访问异常。我如何从那里阅读?

基本上我只想拥有一个自解压的 PE 文件。是的,我知道,我可以制作自解压存档,但这不是我想要的,因为我需要 .exe 和 .dll,但自解压存档只能是 .exe,所以看起来唯一的方法是让我的应用程序自己- 提取自身。代码如下:

int main(void)
{
    HMODULE hBegin = GetModuleHandle(NULL);

    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hBegin;
    PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((PBYTE)hBegin + dosHeader->e_lfanew);
    PIMAGE_SECTION_HEADER pSectionTable = (PIMAGE_SECTION_HEADER)(ntHeaders + 1);


    // get size of each section
    DWORD dwSize = 0;

    for(int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++)
    {
        dwSize += pSectionTable[i].SizeOfRawData;
    }

    //get size of PE headers
    dwSize += ntHeaders->OptionalHeader.SizeOfHeaders;

    WCHAR lpszSfxPath[MAX_PATH];
        GetModuleFileNameW(NULL, lpszSfxPath, MAX_PATH);
    HANDLE hFile = CreateFileW(lpszSfxPath,
            GENERIC_READ,
            FILE_SHARE_READ,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL);
    SetFilePointer(hFile, dwSize, NULL, FILE_BEGIN);
    BYTE BUF[10];
    if(!ReadFile(hFile,BUF,sizeof(BYTE),NULL,NULL))
        printf("FAIL!\n");

    printf("HELLO WORLD\n");
    getchar();
    return 0;
}

调用 SetFilePointer 后,文件指针指向存储我的打包文件的文件末尾,但我无法从中读取

【问题讨论】:

    标签: c++ windows hex executable exe


    【解决方案1】:

    Microsoft 的 PE 可执行二进制文件包含一个单独的 resources 部分,该部分可以放在文件中 - 例如,资源用于在可执行文件中传送数据。这是您最可能想要放置数据的位置。

    看一看:http://www.devsource.com/c/a/Architecture/Resources-From-PE-I/

    【讨论】:

      【解决方案2】:

      另一种可能的解决方案是在文件的最后存储一个标头结构,其中包含数据开始的文件中的偏移量以及数据的长度。然后你的程序可以很容易地寻找到文​​件的末尾(减去文件头的大小),并读取数据的位置和长度。


      您所做的是获取可执行文件,将其写入第二个文件,可能写入填充,写入数据,写入可能的更多填充,最后写入数据的长度和数据在文件中的位置。

      文件看起来(在磁盘上)类似于:

      +--------------+ |可执行文件 | |程序 | +--------------+ |填充 | +--------------+ |数据 | +--------------+ |填充 | +--------------+ |数据长度 | |数据位置| +--------------+

      现在可执行文件可以将文件作为普通文件以只读方式打开。寻找到末尾减去data lengthdata position fields 的大小(通常是sizeof(DWORD)(乘以2))。读取长度和位置的两个字段。现在您可以寻找数据所在的实际位置(data pos.)并读取data length字节以读取实际数据。

      【讨论】:

      • 问题是我实际上不能使用 ReadFile 函数从文件中读取除“MZ”之外的任何内容
      • 这很好,但看起来我还没有设法解释我希望所有这些东西如何工作。我想创建一个本身包含另一个文件的可执行文件,以便可以运行这个带有文件的 exe,并且它会在执行期间从内存中解压缩第二个文件。你在说的是:拥有exe和文件,exe在执行过程中使用这个文件来创建另一个exe,并在其中注入文件。但我需要单个自打包 exe。
      • 您的意思是您希望可执行文件自行修改?这是不可能的,但这也不是您最初提出的问题。请澄清您的实际问题是什么:当您说您不能从文件中读取除 MZ 之外的任何内容时,您到底是什么意思?尝试时出了什么问题?
      • 我用资源文件解决了这个问题。另一种可能的解决方案是使用 bin2h 实用程序获取 .h 文件,该文件将二进制文件的二进制代码存储在无符号字符数组中。只需简单地创建文件 x.exe 或 x.dll 并将此数组写入其中。无论如何感谢您的帮助:)
      猜你喜欢
      • 2012-02-12
      • 2012-05-07
      • 2020-06-02
      • 2013-02-22
      • 2014-03-30
      • 2018-02-01
      • 2015-12-25
      • 2011-12-19
      • 2011-06-10
      相关资源
      最近更新 更多