以十六进制编辑器写入程序存储器并以编程方式读取

时间:2012-11-12 14:15:49

标签: c++ windows hex executable exe

我有.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文件指针点之后,但是我无法从其中读取

2 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:1)

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


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

该文件将在(在磁盘上)看起来像:

+-------------+
| Executable  |
| Program     |
+-------------+
| Padding     |
+-------------+
| Data        |
+-------------+
| Padding     |
+-------------+
| Data length |
| Data pos.   |
+-------------+

现在,可执行文件可以将文件作为常规文件打开,只读。求最后减去data lengthdata position fields的大小(通常是sizeof(DWORD)(第二次))。阅读两个字段的长度和位置。现在,您可以查找数据的实际位置(data pos.)并读取data length个字节来读取实际数据。