書式#include <stdlib.h>に含ま する#include <stdio.hに> する#include <windows.hに> // http://hatriot.github.io/blog/2017/09/19/abusing-delay-load-dll/ / / https://blog.csdn.net/adam001521/article/details/84658708 / * のDataDirectoryのインデックス値 の#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 //エクスポートディレクトリ の#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 //インポートディレクトリ の#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 //基地移転表 #定義IMAGE_DIRECTORY_ENTRY_IAT 12 //インポートアドレステーブル の#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 //遅延ロードインポート記述子 * / / * * DOSヘッダ(ベース)を取得- > NTヘッダの位置 * NTヘッダを取得{ * _IMAGE_FILE_HEADER * IMAGE_OPTIONAL_HEADER:DataDirectoryのアレイ *} *のDataDirectory {RVAサイズ} * * / / * エクスポートテーブル 構造体_IMAGE_EXPORT_DIRECTORY { DWORD特性。 DWORD TimeDateStamp; WORDのMajorVersion。 WORD MinorVersionの; DWORD名; // DLL名 DWORDベース。//序ベース、FUNCをリンク:@(ベース+ unbased序) DWORDのNumberOfFunctions。 DWORD NumberOfNames; // DWORD AddressOfFunctions; //関数のアドレスアレイ DWORDのAddressOfNames。//名前序のと同じ順序で配列、ではなく、機能 DWORD AddressOfNameOrdinals。// unbased序、関数内のインデックス } * / / * インポートアドレステーブルは、ディレクトリに存在しない 構造体_IMAGE_IMPORT_DESCRIPTOR { 組合{ DWORD特徴。// 0ヌル輸入ディスクリプタ終了するための DWORD OriginalFirstThunkを。//名前または序によって } DUMMYUNIONNAME。 DWORD TimeDateStamp; DWORD ForwarderChain; DWORD名; // DLL名 DWORD FirstThunk; // IATにおけるPOSへのポインタ、その値firstThunk-> u1.functionアドレスである } IMAGE_IMPORT_DESCRIPTOR。 構造体_IMAGE_THUNK_DATA32 { 組合{ DWORD ForwarderString。 DWORD機能; // FUNCアドレス(firstthunk、IAT内の一つのアドレス) DWORD序。//序によって DWORDのAddressOfData。// PIMAGE_IMPORT_BY_NAME } U1。 } * / / * 遅延テーブル 構造体_IMAGE_DELAYLOAD_DESCRIPTOR { 組合{ DWORD AllAttributes。 構造体{ DWORD RvaBased:1。//遅延ロードバージョン2 DWORDのReservedAttributes:31; }。 }属性。 DWORD DllNameRVA; ターゲットライブラリの名前に// RVA(ASCII文字列をNULLで終了) DWORD ModuleHandleRVA; // RVA HMODULEキャッシング位置(PHMODULE)に DWORD ImportAddressTableRVA。// RVA IAT(PIMAGE_THUNK_DATA)の開始に DWORD ImportNameTableRVA。//名前テーブル(PIMAGE_THUNK_DATA :: AddressOfData)の開始にRVA DWORD BoundImportAddressTableRVA。//オプションのバウンドIATへのRVA DWORD UnloadInformationTableRVA。//オプションのアンロード先テーブルへのRVA DWORD TimeDateStamp。// 0バインドされていない場合、 } PIMAGE_EXPORT_DIRECTORY pExportTable。* / ボイドのgetTables(チャー *のpDllName) { PIMAGE_DELAYLOAD_DESCRIPTOR pDelayTable; PIMAGE_IMPORT_DESCRIPTOR pIMportTable; HMODULE HMODULE; PDWORD住所、名前、 PWORD序; PIMAGE_DOS_HEADER pImgDos; PIMAGE_NT_HEADERS pImgNt; // スリープ(20 * 1000); HMODULE = LoadLibraryEx(pDllName、NULL、0 ); pImgDos = (PIMAGE_DOS_HEADER)(HMODULE)。 pImgNt =(PIMAGE_NT_HEADERS)((LPBYTE)pImgDos + pImgDos-> e_lfanew)。 // 最初のセクション // PIMAGE_SECTION_HEADER pSech = IMAGE_FIRST_SECTION(pImgNt)。 // インポートテーブル pExportTable =(PIMAGE_EXPORT_DIRECTORY)((LPBYTE)HMODULE + pImgNt->OptionalHeader.DataDirectory [IMAGE_DIRECTORY_ENTRY_EXPORT] .VirtualAddress)。 アドレス =(PDWORD)((LPBYTE)HMODULE + pExportTable-> AddressOfFunctions)。 名前 =(PDWORD)((LPBYTE)HMODULE + pExportTable-> AddressOfNames)。 序 =(PWORD)((LPBYTE)HMODULE + pExportTable-> AddressOfNameOrdinals)。 printf(" %dは名\ nでエクスポートされるエクスポートテーブルにおける%D機能がある"、pExportTable-> NumberOfFunctions、pExportTable-> NumberOfNames)。 用(int型 I = 0 ; I <pExportTable-> NumberOfNames iが++ ) { printf(" %pが序で機能%sのを見つける:%dは\ nを"、(char型 *)HMODULE +名[i]は、(LPBYTE)HMODULE +アドレス[序[I]]、序[i]が+ pExportTable-> ベース); } // エクスポートテーブルの printfの(" ------------------------------------------ ----------------------------------------- \ N " ); pIMportTable =(PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)HMODULE + pImgNt-> OptionalHeader.DataDirectory [IMAGE_DIRECTORY_ENTRY_IMPORT] .VirtualAddress)。 しばらく(!pIMportTable->名前= NULL) { のprintf(" :%sのの\ nのインポートDLL "、(LPBYTE)HMODULE + pIMportTable-> 名); PIMAGE_THUNK_DATA pInfoEntry =(PIMAGE_THUNK_DATA)((LPBYTE)HMODULE + pIMportTable-> OriginalFirstThunk)。 PIMAGE_THUNK_DATA pAddressEntry =(PIMAGE_THUNK_DATA)((LPBYTE)HMODULE + pIMportTable-> FirstThunk)。 一方、(pInfoEntry-> u1.AddressOfData!= NULL) { 場合(pInfoEntry-> u1.Ordinal&IMAGE_ORDINAL_FLAG) { のprintf(" \ tfunc序:%D ADDR:%Pを\ n "、IMAGE_ORDINAL(pInfoEntry-> u1.Ordinal )、pAddressEntry-> u1.Function)。 } 他 { IMAGE_IMPORT_BY_NAME * pImport = PIMAGE_IMPORT_BY_NAME((LPBYTE)HMODULE + pInfoEntry-> u1.AddressOfData)。 printf(" \のtfunc名:%sのADDR:%p個のエントリのADDR%のp \ nを"、pImport->名前、pAddressEntry-> u1.Function、pAddressEntry)。 } pInfoEntry ++ 。 pAddressEntry ++ ; } pIMportTable ++ 。 } // 遅延テーブル のprintf(" ------------------------------------------ ----------------------------------------- \ N " ); pDelayTable =(PIMAGE_DELAYLOAD_DESCRIPTOR)((LPBYTE)pImgDos + pImgNt - > OptionalHeader.DataDirectory [IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT] .VirtualAddress)。 用(!;エントリー・> ImportAddressTableRVA = NULL; IMAGE_DELAYLOAD_DESCRIPTOR *エントリ= pDelayTableエントリ++ ){ CHAR * pDllName =(CHAR *)((LPBYTE)HMODULE +エントリー・> DllNameRVA)。 PIMAGE_THUNK_DATA pInfoEntry =(PIMAGE_THUNK_DATA)((LPBYTE)HMODULE +エントリー・> ImportNameTableRVA)。 PIMAGE_THUNK_DATA pAddressEntry =(PIMAGE_THUNK_DATA)((LPBYTE)HMODULE +エントリー・> ImportAddressTableRVA)。 printf("遅延インポートモジュール:%のSの\ n "pDllName); ながら!(pInfoEntry-> u1.AddressOfData = NULL) { 場合(pInfoEntry-> u1.Ordinal&IMAGE_ORDINAL_FLAG) { のprintf(" \ tfunc序:%D ADDR:% Pする\ n "IMAGE_ORDINAL(pInfoEntry-> u1.Ordinal)、pAddressEntry-> u1.Function); } 他 { IMAGE_IMPORT_BY_NAME * pImport = PIMAGE_IMPORT_BY_NAME((LPBYTE)HMODULE + pInfoEntry-> u1.AddressOfData); のprintf(" \ tfunc名前:%sのADDR:%pが\ nを" 、pImport->名前、pAddressEntry-> u1.Function); } pInfoEntry ++ 。 pAddressEntry ++ ; } } } int型のmain(int型 ARGC、チャー ** ARGV) { のgetTables(ARGV [ 1 ])。 リターン 0 ; }