// IatApiHook.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
BOOL TestFunctionInIAT( HMODULE hModule, ULONG FunctionAddress )
{
BOOL bReturn = FALSE;
unsigned char *pBaseAddr = reinterpret_cast<unsigned char *>(hModule);
// 擷取DOS header 的位置
PIMAGE_DOS_HEADER pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(pBaseAddr);
// 擷取NTImage header 的位置
PIMAGE_NT_HEADERS pNtHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(
pBaseAddr + pDosHeader->e_lfanew );
// 擷取 PE option header的位置
PIMAGE_OPTIONAL_HEADER pPEOptionHeader = &pNtHeader->OptionalHeader;
// 擷取匯入表的目錄結構
PIMAGE_DATA_DIRECTORY pIATDataDirectory = &(pPEOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);
// 擷取匯入表 descriptor
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(
pBaseAddr + pIATDataDirectory->VirtualAddress );
// 從pImportDescriptor 開始是一堆匯入表,一張接著一張,直到
// 匯入表的名字為空白為止,其實就是對應Windows 的一個dll,有幾張表,就表示
// 該模組依賴幾個dll 的匯出函數, Name 欄位是dll的名稱的相對虛擬位址
while ( pImportDescriptor->Name != 0 )
{
// thunk data 就是表示匯入dll 中函數描述
PIMAGE_THUNK_DATA pThunkData = reinterpret_cast<PIMAGE_THUNK_DATA>(
pBaseAddr + pImportDescriptor->FirstThunk);
while( pThunkData->u1.Function != 0 )
{
ULONG *ppfn = ( ULONG *)&pThunkData->u1.Function;
if ( *ppfn == FunctionAddress )
{
bReturn = TRUE;
break;
}
++pThunkData;
}
++pImportDescriptor;
}
return bReturn;
}
PROC g_CreateFunc = NULL;
typedef BOOL (WINAPI *PCreateProcessW)(
__in_opt LPCWSTR lpApplicationName,
__inout_opt LPWSTR lpCommandLine,
__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in BOOL bInheritHandles,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCWSTR lpCurrentDirectory,
__in LPSTARTUPINFOW lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInformation);
BOOL WINAPI MyCreateProcessW(
__in_opt LPCWSTR lpApplicationName,
__inout_opt LPWSTR lpCommandLine,
__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in BOOL bInheritHandles,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCWSTR lpCurrentDirectory,
__in LPSTARTUPINFOW lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInformation)
{
MessageBoxW(NULL, lpCommandLine, L"CreateProcessW", MB_OK);
return ((PCreateProcessW)g_CreateFunc)(
lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
}
PROC install_api_hook(
HMODULE hHookModule,
const char * szDllName,
PROC pfnHookFunAddr,
PROC pfnNewFundAddr
)
{
PROC pOrigFunc = NULL;
unsigned char *pBaseAddr =
reinterpret_cast<unsigned char *>(hHookModule);
PIMAGE_DOS_HEADER pDosHeader =
reinterpret_cast<PIMAGE_DOS_HEADER>(pBaseAddr);
PIMAGE_NT_HEADERS pNtHeader =
reinterpret_cast<PIMAGE_NT_HEADERS>(
pBaseAddr + pDosHeader->e_lfanew );
PIMAGE_OPTIONAL_HEADER pPEOptionHeader =
&pNtHeader->OptionalHeader;
PIMAGE_DATA_DIRECTORY pIATDataDirectory =
&(pPEOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor =
reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(
pBaseAddr + pIATDataDirectory->VirtualAddress );
for ( ; pImportDescriptor->Name; pImportDescriptor++ )
{
const char* pszModName =
reinterpret_cast<const char*>(
pBaseAddr + pImportDescriptor->Name);
if ( 0 == lstrcmpiA( pszModName, szDllName ) )
{
break;
}
}
if ( 0 == pImportDescriptor->Name )
{
return pOrigFunc;
}
PIMAGE_THUNK_DATA pThunkData =
reinterpret_cast<PIMAGE_THUNK_DATA>(
pBaseAddr + pImportDescriptor->FirstThunk);
while( pThunkData->u1.Function != 0 )
{
PROC *ppFunc = reinterpret_cast<PROC*>(
&pThunkData->u1.Function);
if ( *ppFunc == pfnHookFunAddr )
{
DWORD dwOldProtect = 0;
VirtualProtect( ppFunc, sizeof(PROC), PAGE_READWRITE, &dwOldProtect );
pOrigFunc = *ppFunc;
CopyMemory(ppFunc, &pfnNewFundAddr, sizeof(PROC));
// SIZE_T stMemorySize = 0;
// WriteProcessMemory(
// GetCurrentProcess(),
// ppFunc,
// &uNewFundAddr,
// sizeof(*ppFunc),
// &stMemorySize);
VirtualProtect( ppFunc, sizeof(PROC), dwOldProtect, 0 );
break;
}
pThunkData++;
}
return pOrigFunc;
}
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hModule = NULL;
GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)TestFunctionInIAT,
&hModule);
BOOL bReturn = TestFunctionInIAT( hModule , (ULONG_PTR)CreateProcessW );
if ( bReturn )
{
printf("Found address CreateProcessW!\n");
}
else
{
printf("found failed!\n");
}
g_CreateFunc = install_api_hook(hModule, "kernel32.dll", (PROC)CreateProcessW, (PROC)MyCreateProcessW);
wchar_t szProcessName[] = L"notepad.exe";
STARTUPINFO si = {sizeof(si)};
PROCESS_INFORMATION pi;
CreateProcessW(NULL,
szProcessName,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi);
return 0;
}