查找进程的IATHOOK

// 遍历某一个进程是否有IATHOOK.cpp : 定义控制台应用程序的入口点。
//

include "stdafx.h"

include "windows.h"

include <psapi.h>

DWORD RvaToOffect(PBYTE pPeFile, DWORD Rva)
{
//1 得到区段表的起始位置
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pPeFile;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(
pPeFile + pDos->e_lfanew);

PIMAGE_SECTION_HEADER pSection =
    IMAGE_FIRST_SECTION(pNt);
//2 看一下这个Rva落在了哪一个区段里面
for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++)
{
    //2.1 假如在头部
    if (Rva < pSection->VirtualAddress){
        return Rva;
    }
    //2.2 假如不在头部 
    //2.2.1算一下当前区段的范围
    DWORD dwAlignment =
        pNt->OptionalHeader.SectionAlignment;
    DWORD dwCount = pSection->Misc.VirtualSize / dwAlignment;
    dwCount += (pSection->Misc.VirtualSize%dwAlignment == 0) ? 0 : 1;
    //2.2.2 假如落在了这个区段中
    if (Rva >= pSection->VirtualAddress&&
        Rva < pSection->VirtualAddress + dwCount*dwAlignment)
    {
        return Rva - pSection->VirtualAddress +
            pSection->PointerToRawData;
    }
    pSection++;
}
return 0;

}

//查看某一个模块是否被IATHOOK了
void CheckIAT(HANDLE hProcess,HMODULE hModule)
{
PBYTE pModuleBuf = NULL;
DWORD dwReadModuleSize = 0;
//1 把模块的副本拷贝出来
//1.1读取出DOS头大小,找到PE头
pModuleBuf = new BYTE[sizeof(IMAGE_DOS_HEADER)];
ReadProcessMemory(hProcess, hModule, pModuleBuf, sizeof(IMAGE_DOS_HEADER), &dwReadModuleSize);
//1.2得到PE头后,得到镜像大小
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pModuleBuf;
DWORD dwNewFile = pDos->e_lfanew;
delete[]pModuleBuf;
DWORD dwHeaderSize = dwNewFile + sizeof(IMAGE_NT_HEADERS);
pModuleBuf = new BYTE[dwHeaderSize];
ReadProcessMemory(hProcess, hModule, pModuleBuf, dwHeaderSize, &dwReadModuleSize);
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pModuleBuf + dwNewFile);
//2 找到导入表
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &pNt->OptionalHeader;
PIMAGE_DATA_DIRECTORY pImportDir = pOptionalHeader->DataDirectory+1;
DWORD dwImportVA = (DWORD)((DWORD)hModule + pImportDir->VirtualAddress);
DWORD dwSize = pImportDir->Size;
//3 将导入表读入内存
PBYTE pImportBuf = new BYTE[dwSize];
ReadProcessMemory(hProcess, (LPVOID)dwImportVA, pImportBuf, dwSize, &dwReadModuleSize);
PIMAGE_IMPORT_DESCRIPTOR pImport = PIMAGE_IMPORT_DESCRIPTOR(pImportBuf);
//3 查找导入表中的INT中的函数名称,去此dll文件的导出表中找到函数地址,
//根据函数地址RVA+ImageBase看看是否和IAT中的数据相等
while (pImport->Name != 0)
{
PINT pFunction = nullptr;
//5.1 待检测的IAT与INT
DWORD pIatRVA = (DWORD)(pImport->FirstThunk + (DWORD)hModule);//IAT
DWORD pIntRVA = (DWORD)(pImport->OriginalFirstThunk + (DWORD)hModule);//INT
PIMAGE_THUNK_DATA pIat = (PIMAGE_THUNK_DATA)new BYTE[0x1000];
PIMAGE_THUNK_DATA pInt = (PIMAGE_THUNK_DATA)new BYTE[0x1000];
ReadProcessMemory(hProcess, (LPVOID)pIatRVA, pIat, 0x1000, &dwReadModuleSize);
ReadProcessMemory(hProcess, (LPVOID)pIntRVA, pInt, 0x1000, &dwReadModuleSize);
//5.2 获得此dll的名字
char* pDllnameVA = (char)((DWORD)hModule + pImport->Name);
char
pDllname = new char[MAX_PATH];
ReadProcessMemory(hProcess, (LPVOID)pDllnameVA, pDllname, MAX_PATH, &dwReadModuleSize);
//5.3 将此dll的文件读入内存
HANDLE hDllFile = CreateFileA(
pDllname,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
DWORD dwDllSize = GetFileSize(hDllFile, NULL);
PBYTE pDllbuf = new BYTE[dwDllSize];
DWORD dwReadSize = 0;
ReadFile(hDllFile, pDllbuf, dwDllSize, &dwReadSize, NULL);
//5.4获得此Dll的导出地址表
PIMAGE_DOS_HEADER pDestanceDos = (PIMAGE_DOS_HEADER)pDllbuf;
PIMAGE_NT_HEADERS pDestanceNt = (PIMAGE_NT_HEADERS)(pDllbuf + pDestanceDos->e_lfanew);
PIMAGE_DATA_DIRECTORY pExportDir = &(pDestanceNt->OptionalHeader.DataDirectory[0]);
PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)(RvaToOffect(pDllbuf, pExportDir->VirtualAddress) + pDllbuf);
pFunction = (PINT)(RvaToOffect(pDllbuf, pExport->AddressOfFunctions) + pDllbuf);
//5.5 使用INT得到的此函数的序号,进而得到导出表中函数地址RVA
while (pIat->u1.AddressOfData != 0)
{
//5.5.1得到序号
WORD Order = 0;
if (IMAGE_SNAP_BY_ORDINAL32(pInt->u1.AddressOfData) != 1)
{
char* pFunnameVA = (char)(pInt->u1.ForwarderString + (DWORD)hModule);
char
pFunname = new char[MAX_PATH];
ReadProcessMemory(hProcess, (LPVOID)pFunnameVA, pFunname, MAX_PATH, &dwReadModuleSize);
Order = PIMAGE_IMPORT_BY_NAME(pFunname)->Hint;
delete[]pFunname;
}
else
{
Order = pInt->u1.Ordinal;
}
//5.5.2得到计算出的地址
int ExportFunRva = pFunction[Order];
int ImageBase = (int)hModule;
int FunVA = ExportFunRva + ImageBase;
if (FunVA == pInt->u1.Function)
{
if (IMAGE_SNAP_BY_ORDINAL32(pInt->u1.AddressOfData) != 1)
{
char* pFunnameVA = (char)(pInt->u1.ForwarderString + (DWORD)hModule);
char
pFunname = new char[MAX_PATH];
ReadProcessMemory(hProcess, (LPVOID)pFunnameVA, pFunname, MAX_PATH, &dwReadModuleSize);
printf("%s未被Hook", PIMAGE_IMPORT_BY_NAME(pFunname)->Name);
delete[]pFunname;
}
}
else
{
if (IMAGE_SNAP_BY_ORDINAL32(pInt->u1.AddressOfData) != 1)
{
char* pFunnameVA = (char)(pInt->u1.ForwarderString + (DWORD)hModule);
char
pFunname = new char[MAX_PATH];
ReadProcessMemory(hProcess, (LPVOID)pFunnameVA, pFunname, MAX_PATH, &dwReadModuleSize);
printf("%s被Hook", PIMAGE_IMPORT_BY_NAME(pFunname)->Name);
delete[]pFunname;
}
}
pInt++;
pIat++;
}
pImport++;
}

}

int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 30496);
DWORD dwNeed1 = 0;
DWORD dwNeed2 = 0;
EnumProcessModulesEx(hProcess, NULL, 0, &dwNeed1, LIST_MODULES_ALL);
HMODULE* pModule = new HMODULE[dwNeed1];
EnumProcessModulesEx(hProcess, pModule, dwNeed1, &dwNeed2, LIST_MODULES_ALL);
DWORD dwSize = 0;
CHAR buf[MAX_PATH] = {};
PBYTE pModuleBuf = NULL;
DWORD dwReadModuleSize = 0;
int i = 0;
for (; i < dwNeed2; i++)
{

    GetModuleFileNameExA(hProcess, pModule[i], buf, MAX_PATH);
    char* pLow;
    _strlwr_s(pLow = _strdup(buf), strlen(buf) + 1);
    if (strstr(pLow, "user32.dll") != NULL)
    {
        break;
    }
}
CheckIAT(hProcess, pModule[i]);
CloseHandle(hProcess);
return 0;

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • ―――奕城3段棋手必胜秘籍 在围棋的棋盘上,大龙,中龙,小龙,到处飞,成为驯龙高手,何其难也!谁也不敢说“必胜”这...
    Graceland阅读 907评论 1 4
  • 我要说的是目前为止我人生中,22岁,之前发生的故事。我之前有个QQ情侣那个app 故事全在里面,每天做的神经病的好...
    媛哈哈哈哈哈哈阅读 191评论 0 2