Ring3层 HOOK 导入地址表的基本实现
本帖最后由 古月不傲 于 2019-11-28 03:39 编辑#include <iostream>
using namespace std;
#include <Windows.h>
//PE头
class _PE_HEADERS
{
public:
_PE_HEADERS() : m_pDosHeader(NULL), m_pNtHeader(NULL), m_pFileHeader(NULL), m_pOptionalHeader(NULL),
m_pSectionHeader(NULL), m_pDataDirectory(NULL) { }
~_PE_HEADERS(){ }
public:
PIMAGE_DOS_HEADER m_pDosHeader;
PIMAGE_NT_HEADERS m_pNtHeader;
PIMAGE_FILE_HEADER m_pFileHeader;
PIMAGE_OPTIONAL_HEADER m_pOptionalHeader;
PIMAGE_SECTION_HEADER m_pSectionHeader;
PIMAGE_DATA_DIRECTORY m_pDataDirectory;
};
typedef int (WINAPI *PORGFUNCTIONADDRESS)
(_In_opt_ HWND hWnd,
_In_opt_ LPCTSTR lpText,
_In_opt_ LPCTSTR lpCaption,
_In_ UINT uType
);
DWORD g_dwNewFunctionAddress = 0;
DWORD g_dwOldFunctionAddress = 0;
DWORD g_dwOldProtect = 0;
PORGFUNCTIONADDRESS pOldFunctionAddress = NULL;
int WINAPI HookedMessageBox
( _In_opt_ HWND hWnd,
_In_opt_ LPCTSTR lpText,
_In_opt_ LPCTSTR lpCaption,
_In_ UINT uType
)
{
char szBuffer = { 0 };
printf("The has been Hooked that was MessageBoxW!\n");
printf("窗口句柄:%x!\n", (DWORD)hWnd);
WideCharToMultiByte(CP_OEMCP, NULL, lpText, lstrlen(lpText), szBuffer, MAX_PATH, 0, FALSE);
printf("文本:%s!\n", szBuffer);
ZeroMemory(szBuffer, 0);
WideCharToMultiByte(CP_OEMCP, NULL, lpCaption, lstrlen(lpCaption), szBuffer, MAX_PATH, 0, FALSE);
printf("标题:%s!\n", szBuffer);
printf("窗口类型:%x!\n", uType);
return ((PORGFUNCTIONADDRESS(g_dwOldFunctionAddress))(hWnd, lpText, lpCaption, uType));
}
//获取本进程模块
HMODULE GetOwnModule()
{
HMODULE hModule = NULL;
hModule = GetModuleHandle(NULL);
if (hModule == NULL)
{
return NULL;
}
return hModule;
}
//获取原来的函数地址
DWORD GetOldFunctionAddress()
{
HMODULE hModule = NULL;
DWORD dwOldFunctionAddress = 0;
hModule = LoadLibrary(TEXT("user32.dll"));
if (hModule == NULL)
{
return -1;
}
dwOldFunctionAddress = (DWORD)GetProcAddress(hModule, "MessageBoxW");
if (dwOldFunctionAddress == 0)
{
return -2;
}
return dwOldFunctionAddress;
}
//修改IAT表的函数地址
VOID ChangeFunctionAddressOfIAT(HMODULE hModule, DWORD dwNewFunctionAddress, DWORD &dwOldFunctionAddress, BOOL bFlag)
{
_PE_HEADERS *pe = new _PE_HEADERS;
//定位导入表
pe->m_pDosHeader = (PIMAGE_DOS_HEADER)hModule;
pe->m_pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pe->m_pDosHeader + pe->m_pDosHeader->e_lfanew);
pe->m_pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pe->m_pNtHeader + 4);
pe->m_pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pe->m_pFileHeader + sizeof(IMAGE_FILE_HEADER));
pe->m_pDataDirectory = pe->m_pOptionalHeader->DataDirectory;
DWORD dwVitualAddress = (DWORD)pe->m_pDataDirectory.VirtualAddress;
PIMAGE_IMPORT_DESCRIPTOR pImportDirectory = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hModule + dwVitualAddress);
//遍历每个模块的IAT表 找到要HOOK的函数
while (pImportDirectory->FirstThunk != 0)
{
PIMAGE_THUNK_DATA pThunkData = (PIMAGE_THUNK_DATA)((DWORD)hModule + pImportDirectory->FirstThunk);
while (pThunkData->u1.Function)
{
//修改函数地址
if (bFlag)
{
if (dwOldFunctionAddress == pThunkData->u1.Function)
{
DWORD dwOldProtect = 0;
if (!VirtualProtect(pThunkData, 4, PAGE_READWRITE, &dwOldProtect))
{
return;
}
*((DWORD *)pThunkData) = dwNewFunctionAddress;
g_dwOldProtect = dwOldProtect;
break;
}
}
//恢复函数地址
else
{
if (dwNewFunctionAddress == pThunkData->u1.Function)
{
DWORD dwOldProtect = 0;
*((DWORD *)pThunkData) = dwOldFunctionAddress;
VirtualProtect(pThunkData, 4, g_dwOldProtect, &dwOldProtect);
break;
}
}
pThunkData++;
}
pImportDirectory++;
}
g_dwNewFunctionAddress = dwNewFunctionAddress;
g_dwOldFunctionAddress = dwOldFunctionAddress;
delete pe;
pe = NULL;
}
int main(void)
{
HMODULE hModule = NULL;
DWORD dwNewFunctionAddress = 0;
DWORD dwOldFunctionAddress = 0;
hModule = GetOwnModule();
dwOldFunctionAddress = GetOldFunctionAddress();
ChangeFunctionAddressOfIAT(hModule, (DWORD)HookedMessageBox, dwOldFunctionAddress, TRUE);
MessageBox(NULL, TEXT("测试"), TEXT("IATHOOK"), MB_YESNOCANCEL);
ChangeFunctionAddressOfIAT(hModule, (DWORD)HookedMessageBox, dwOldFunctionAddress, FALSE);
MessageBox(NULL, TEXT("测试"), TEXT("IATHOOK"), MB_YESNOCANCEL);
system("pause");
return 0;
} 支持一下。
页:
[1]