流沙团
IATHOOK详细讲解
2018-2-2 流沙团


0x01 HOOK函数的编写



有一定的格式要求



直接直接hook MessageBoxA



函数格式






int WINAPI NewMessageBox(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
)
{
//拿到原来的MessageBox
typedef int (WINAPI *pfMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT);
pfMessageBox myMessageBox = NULL;
myMessageBox = (pfMessageBox)GetProcAddress(LoadLibrary("User32.DLL"),"MessageBoxA");
//监测数据
OutputDebugStringF("hWnd:%08X,lpText:%s,lpCaption:%s,uType:%d ",hWnd,lpText,lpCaption,uType);

//继续执行MessageBox
myMessageBox(hWnd,"www.gyarmy.com","流沙",uType);

myMessageBox(hWnd,lpText,lpCaption,uType);
return 0;
}






0x02 IAT表的遍历



由于导入表的复杂性, 每次遍历导入表,我都是到处找资料, 导入表, 有一个INT表和一个IAT表, 每次使用,都需要看看一张图



导入表.png







这里主要用来配合理解导入表的结构



需要理解PE的运行载入过程



IAT表是载入PE后进行修复得到的, 我们直接修改 IAT表中的数据即可



代码如下;






BOOL ImportDirectoryHOOK(DWORD imagebase,DWORD pOldAddr,DWORD pNewAddr)
{

PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)imagebase;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)imagebase+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
pDataDirectory = pOptionHeader->DataDirectory;

//确定导入表
IMAGE_DATA_DIRECTORY pImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];

DWORD ImportVirtualAddress = pImportDirectory.VirtualAddress;
PIMAGE_IMPORT_DESCRIPTOR pImp = NULL;
pImp = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)imagebase + ImportVirtualAddress);
PIMAGE_THUNK_DATA pOrgThunk, pFirstThunk;

//遍历IAT表
while (NULL != pImp->FirstThunk) {
pImp->Name += imagebase;
OutputDebugStringF("DLL: %s", pImp->Name);
//FARPROC fpFun;
HINSTANCE hInstance = LoadLibraryA((LPCSTR)pImp->Name);
if (NULL == hInstance) {
OutputDebugStringF("Load library %s failed, error: %d\n", pImp->Name, GetLastError());
return FALSE;
}
pOrgThunk = (PIMAGE_THUNK_DATA)(imagebase + pImp->OriginalFirstThunk);
pFirstThunk = (PIMAGE_THUNK_DATA)(imagebase + pImp->FirstThunk);

while (NULL != *(DWORD *)pFirstThunk) {
if(pOldAddr == *((PDWORD)pFirstThunk))
{
OutputDebugStringF("11111111111");
*((PDWORD)pFirstThunk)= pNewAddr;
break;
}
++pFirstThunk;
++pOrgThunk;
}
FreeLibrary(hInstance);
++pImp;
}
return TRUE;
}






0x03 最后贴上主程序的代码,关键在于思路的理解!







// 20180202_05.cpp : Defines the entry point for the application.


//

#include "stdafx.h"
#include "PEOperate.h"
#include "DebugTool.h"
#include <windows.h>
#include <stdio.h>

BOOL ImportDirectoryHOOK(DWORD imagebase,DWORD pOldAddr,DWORD pNewAddr)
{

PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)imagebase;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)imagebase+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
pDataDirectory = pOptionHeader->DataDirectory;

//确定导入表
IMAGE_DATA_DIRECTORY pImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];

DWORD ImportVirtualAddress = pImportDirectory.VirtualAddress;
PIMAGE_IMPORT_DESCRIPTOR pImp = NULL;
pImp = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)imagebase + ImportVirtualAddress);
PIMAGE_THUNK_DATA pOrgThunk, pFirstThunk;

//遍历IAT表
while (NULL != pImp->FirstThunk) {
pImp->Name += imagebase;
OutputDebugStringF("DLL: %s", pImp->Name);
//FARPROC fpFun;
HINSTANCE hInstance = LoadLibraryA((LPCSTR)pImp->Name);
if (NULL == hInstance) {
OutputDebugStringF("Load library %s failed, error: %d\n", pImp->Name, GetLastError());
return FALSE;
}
pOrgThunk = (PIMAGE_THUNK_DATA)(imagebase + pImp->OriginalFirstThunk);
pFirstThunk = (PIMAGE_THUNK_DATA)(imagebase + pImp->FirstThunk);

while (NULL != *(DWORD *)pFirstThunk) {
if(pOldAddr == *((PDWORD)pFirstThunk))
{
OutputDebugStringF("11111111111");
*((PDWORD)pFirstThunk)= pNewAddr;
break;
}
++pFirstThunk;
++pOrgThunk;
}
FreeLibrary(hInstance);
++pImp;
}
return TRUE;
}

int WINAPI NewMessageBox(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
)
{
//拿到原来的MessageBox
typedef int (WINAPI *pfMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT);
pfMessageBox myMessageBox = NULL;
myMessageBox = (pfMessageBox)GetProcAddress(LoadLibrary("User32.DLL"),"MessageBoxA");
//监测数据
OutputDebugStringF("hWnd:%08X,lpText:%s,lpCaption:%s,uType:%d ",hWnd,lpText,lpCaption,uType);

//继续执行MessageBox
myMessageBox(hWnd,"www.gyarmy.com","流沙",uType);

myMessageBox(hWnd,lpText,lpCaption,uType);
return 0;
}

VOID TestIATHook()
{
//定位MessageBox
typedef int (WINAPI *pfMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT);
pfMessageBox myMessageBox = NULL;
myMessageBox = (pfMessageBox)GetProcAddress(LoadLibrary("User32.DLL"),"MessageBoxA");
OutputDebugStringF("myMessageBox: %08X",myMessageBox);
//myMessageBox(0,"111","222",MB_OK);

DWORD pOldArr = (DWORD)myMessageBox;

//定位导入表
HMODULE hModule = GetModuleHandle(NULL);
DWORD ImageBase = (DWORD)hModule;
DWORD pNewAddr = (DWORD)NewMessageBox;
//对IAT表进行HOOK
ImportDirectoryHOOK(ImageBase,pOldArr,pNewAddr);
}


int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
TestIATHook();
MessageBox(0,0,0,0);
return 0;
}







项目源代码下载地址:



IATHook.rar



发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容