2

さて、.exe アプリケーションとその他のファイルがあります。私がしたいのは、この他のファイルを .exe ファイルの最後に書き込むことです。.exe ファイルは、メモリ内でこのファイルのアドレスを見つけ、そこから読み取り、何らかの処理を行う必要があります。

以前にメモリに書き込んだファイルのアドレスに到達できましたが、そこから読み込もうとすると、アクセス拒否例外が発生します。そこからどう読むか。

基本的に、1 つの自己解凍 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 ファイル ポインターを呼び出した後、パックされたファイルが格納されているファイルの末尾の直後を指しますが、そこから読み取ることができません。

4

2 に答える 2

5

Microsoft の PE 実行可能バイナリ ファイルには、ファイル内に配置できるリソース用の個別のセクションが含まれています。たとえば、リソースは実行可能ファイル内のデータを出荷するために使用されます。これは、おそらくデータを配置したい場所です。

見てみましょう: http://www.devsource.com/c/a/Architecture/Resources-From-PE-I/

于 2012-11-12T14:25:33.053 に答える
1

考えられる他の解決策は、データが始まるファイルへのオフセットとデータの長さを含むヘッダー構造をファイルの最後に格納することです。その後、プログラムはファイルの末尾 (ヘッダーのサイズを引いたもの) まで簡単にシークし、データの位置と長さを読み取ることができます。


実行可能ファイルを取得し、それを 2 番目のファイルに書き込み、場合によってはパディングを書き込み、データを書き込み、可能な場合はさらにパディングを書き込み、最後にデータの長さとファイル内のデータの位置を書き込みます。

ファイルは (ディスク上で) 次のようになります。

+-------------+
| | 実行可能 |
| | プログラム |
+-------------+
| | パディング |
+-------------+
| | データ | データ
+-------------+
| | パディング |
+-------------+
| | データ長 |
| | データ位置 | |
+-------------+

これで、実行可能ファイルは通常のファイルとして読み取り専用で開くことができます。data lengthandのサイズを引いた最後までシークしますdata position fields(通常はsizeof(DWORD)(2 倍))。長さと位置の 2 つのフィールドを読み取ります。これで、データが存在する実際の位置 ( data pos.) をシークし、data lengthバイトを読み取って実際のデータを読み取ることができます。

于 2012-11-12T14:21:09.037 に答える