导入表是WindowsPE文件中的一组数据结构,可执行程序(即EXE文件)被加载到地址空间后,每个导入的DLL模块都有一个对应的导入表,PE加载器会根据导入表来加载进程需要的其他DLL模块。
导入表的数据结构如下:
OriginalFirstThunk/Characteristics:指向导入表(INT)的RVA(相对虚拟地址)。INT是一个IMAGE_THUNK_DATA结构的数组,数组中的每个元素指向一个IMAGE_IMPORT_BY_NAME结构,INT以元素0结束。
TimeDateStamp:时间戳,可以忽略。
ForwarderChain:如果没有前向引用(forwarders)的话就是-1.
Name:被导入DLL的名字指针,是一个RVA。
FirstThunk:指向导入表(IAT)的RVA。IAT是一个IMAGE_THUNK_DATA结构的数组。
导入表的数据结构如下:
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
} DUMMYUNIONNAME;
DWORD TimeDateStamp; // 0 if not bound,
// -1 if bound, and real date\time stamp
// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
// O.W. date/time stamp of DLL bound to (Old BIND)
DWORD ForwarderChain; // -1 if no forwarders
DWORD Name;
DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;
OriginalFirstThunk/Characteristics:指向导入表(INT)的RVA(相对虚拟地址)。INT是一个IMAGE_THUNK_DATA结构的数组,数组中的每个元素指向一个IMAGE_IMPORT_BY_NAME结构,INT以元素0结束。
TimeDateStamp:时间戳,可以忽略。
ForwarderChain:如果没有前向引用(forwarders)的话就是-1.
Name:被导入DLL的名字指针,是一个RVA。
FirstThunk:指向导入表(IAT)的RVA。IAT是一个IMAGE_THUNK_DATA结构的数组。
导入表逻辑结构如下:
下面贴出源码:
// INTHook.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<Windows.h>
#include <exception>
#include <iostream>
using namespace std;
BOOL AddImportTable(const WCHAR * wzPEFilePath, char * szInjectDllName, char *szFunctionName);
BOOL AddNewImportDescriptor(const WCHAR * wzPEFilePath, char * szInjectDllName, char *szImportFunctionName);
BOOL AddNewSection(LPCTSTR lpModulePath, DWORD dwNewSectionSize);
DWORD PEAlign(DWORD dwTarNumber, DWORD dwAlignTo);
DWORD RVAToOffset(PIMAGE_NT_HEADERS pImageNTHeader, DWORD dwRVA);
PIMAGE_SECTION_HEADER ImageRVAToSection(PIMAGE_NT_HEADERS pImageNTHeader, DWORD dwRVA);
int main()
{
WCHAR TargetPath[0x20] = {0};
char DllPath[0x20] = "InjectDll.dll";
printf("Please Input Target Full Path:\r\n");
//scanf_s(TargetPath, "%s");
wcin >> TargetPath;
AddImportTable(TargetPath,DllPath, "InjectFunction");
return 0;
}
BOOL AddImportTable(const WCHAR * wzPEFilePath, char * szInjectDllName, char *szFunct