秦二世之后谁谁是皇帝:幽默人讲解R3通过IAT修改HOOK目标进程API
来源:百度文库 编辑:中财网 时间:2024/05/11 00:59:20
大家好,我们又见面啦,今天我将为各位讲述一个新故事,那就是IAT HOOK。再观看这个故事之前,需要观众确定具备两个基本能力:
1.对简单的数据结构在内存中的样子能有个宏观的理解。
2.理解运行在windows环境程序的工作原理。
导入地址表(IAT):Import Address Table 由于导入函数就是被程序调用但其执行代码又不在程序中的函数,这些函数的代码位于一个或者多个DLL 中.当PE 文件被装入内存的时候,Windows 装载器才将DLL 装入,并将调用导入函数的指令和函数实际所处的地址联系起来(动态连接),这操作就需要导入表完成.其中导入地址表就指示函数实际地址。
比如我们想对目标程序的PeekMessage这个API函数进行HOOK,那么只需要找到他的IAT表,并把这个API的实际地址修改,这就完成了一个API HOOK。按常理,想执行此过程需要对PE格式有一定的理解,但是我认为并没有这个必要,毕竟这是一个很简单的工作。接下来我将用我的方法带领大家来实现它,那就是角色扮演。
首先幻想自己是30年代,蓝衣社的一名特务。今天接到上级的任务,去某地杀掉一名为敌对势力工作的人,然后经过易容,伪装成他来执行潜伏。那么目标是谁呢?他又住在哪里呢?拿起MSDN情报科送来的文件看看吧,目标叫PeekMessage,是姓“USER32.dll”家族的成员,它住在:
xxx.exe市
IMAGE_DOS_HEADER区
IMAGE_OPTIONAL_HEADER街
IMAGE_IMPORT_DESCRIPTOR小区
还有一张目标的相片
BOOL PeekMessage
(LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg
)
资料就这么多啦,但是并没有说明目标住在几号楼几层几号啊。不过没有关系我们是特务嘛。这难不倒我们的,Let's begin
坐着蓝衣社为我们准备的专机SetWindowsHookEx把我们(DLL)注入到xxx.exe市,哈哈~下了飞机来到一个陌生的城市真是俩眼一摸黑呀,怎么找我们的目的地呢?最简单的办法:打车,于是我们拦了一辆GetModuleHandle(NULL)牌的出租车,谁知道一上车。司机看到我给他的地址后告诉我要去的地方需要过海,没办法直接到,只能先送我到IMAGE_DOS_HEADER区,然后再换船过海才行。听得我晕头转向的,没办法,走吧。。。闲来打量一下这个城市,满眼尽是一些由0和1搭建黑白2色的高楼大厦,颜色和款式是多么的单调枯燥哇,算了,还是闭目养神吧。不一会我们来到了IMAGE_DOS_HEADER区的水路码头,该下车换乘船过海啦。于是买了(ModuleAddress+ImageDosHearderPointer->e_lfanew+24)号渡轮的船票,继续这次无聊的旅程。晕船从头吐到尾,好不容易熬到了地方,原来一出了码头就来到了IMAGE_OPTIONAL_HEADER街,抬头一望在我们12点钟方向,有个小巴站台,走过去这么一看才知道原来坐
ModuleAddress+ImageOptionalHeaderPointer->DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress线小巴,可以直达我们的终点:IMAGE_IMPORT_DESCRIPTOR小区。二话不说,走着您嘚~~~~~马上要到目的地啦。趁坐小巴的这段时间我们先来整理下思绪,因为不知道具体的楼号和门牌号,所以我们要先想个什么办法,于是找同车的一位美丽小姐打听得知,IMAGE_IMPORT_DESCRIPTOR小区的每座楼都是同一样式的,那就是ImageImportDescriptorPointer->FirstThunk风格,又知道一楼大厅有个收信箱,上面登记着住户的姓名。有了这些线索我们就下车一栋楼,一栋楼的找吧,虽然这个方案毫无创意,但是记得有位大师曾经说过:往往通过复杂的数据结构和华丽的算法并不是解决问题的好方法,因为它加大了维护和调试的难度。所以我们就用这种直接而有效的土办法来老老实实的找吧:先逐楼搜索
while(ImageImportDescriptorPointer->FirstThunk!=0),然后找到一楼大厅的收信箱
TargetName=(LPCTSTR)((DWORD)ModuleAddress+ImageImportDescriptorPointer->Name),再逐户的查找姓“USER32.dll”的家族
if(TargetName.Compare(_T("USER32.dll"))==0),没过多久我们终于找到了,登记簿上写明了具体的门牌号,哈哈~这表示我们离成功只有一步之遥,于是迫不及待的走进ModuleAddress+ImageImportDescriptorPointer->FirstThunk号电梯,走向“USER32.dll”家,来到门口,我停住啦,静静地站在那里平复一下心绪,10秒后我飞起一脚踹开了大门走了进去,映入眼帘的是:坐在屋里男女老少,大大小小10几口子,全部一脸惊愕的盯着我这位不速之客。我拿出相片while(ImageThunkDataPointer->u1.Function)迅速搜索,
FunctionAddress=(PDWORD)&(ImageThunkDataPointer->u1.Function)定位目标,
if(*FunctionAddress==(DWORD)PeekMessageAddress)经过一轮的搜索,我找到了目标,他正傻傻的坐在角落里的电脑桌前,我走到它面前
VirtualQuery(FunctionAddress, &InforMation, sizeof(InforMation))细细的打量着他:凌乱的头发如同杂草,一架高度数眼镜戴在苍白消瘦的脸颊上,驼背,纤细却小腹异常隆起的身材,套着10几年前流行的服饰,HOHO~做技术典型的形象,我冷漠的从怀中掏出了枪:
VirtualProtect(FunctionAddress, sizeof(DWORD),PAGE_READWRITE,&BeforeProtect)顶在目标的眉心。此时此刻,在场的所有人都清楚了我的来意。死亡的恐惧笼罩在每个人的心头,我不在多做停留,无情的勾动了扳机,这就是一个特务的专业操守。嘿嘿
::WriteProcessMemory((HANDLE)-1,FunctionAddress,&FunctionOfSelf,sizeof(DWORD), NULL)目标应声倒地。在手枪的淫威下,其他人也只好无奈的接受这痛苦的事实,我也就成功的完成了此次任务。开始潜伏。
接下来换种语言再来讲述一下这个故事:C++
#include
#include "DialogMain.h"
typedef BOOL (WINAPI* PEEKMESSAGE)(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);
PEEKMESSAGE FakePeekMessage=(PEEKMESSAGE)PeekMessage;
BOOL WINAPI MinePeekMessage(LPMSG lpMsg,HWND hWnd, UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg)
{
AfxMessageBox(_T("你TM是不是调用我啦?"));
return ((PEEKMESSAGE)FakePeekMessage)(lpMsg,hWnd,wMsgFilterMin,wMsgFilterMax,wRemoveMsg);
}
BOOL CDialogMain::ImportAddressTableHook(HMODULE ModuleAddress,LPCTSTR Library,LPCVOID TargetAddress,LPCVOID ReplaceAddress)
{
IMAGE_DOS_HEADER* ImageDosHearderPointer=NULL;
IMAGE_OPTIONAL_HEADER* ImageOptionalHeaderPointer=NULL;
IMAGE_IMPORT_DESCRIPTOR* ImageImportDescriptorPointer=NULL;
IMAGE_THUNK_DATA* ImageThunkDataPointer=NULL;
CString TargetName;
DWORD Value=0;
LPDWORD FunctionAddress=NULL;
MEMORY_BASIC_INFORMATION InforMation;
DWORD BeforeProtect=0;
ImageDosHearderPointer=(IMAGE_DOS_HEADER*)ModuleAddress;
ImageOptionalHeaderPointer=(IMAGE_OPTIONAL_HEADER*)((DWORD)ModuleAddress+ImageDosHearderPointer->e_lfanew+24);
ImageImportDescriptorPointer=(IMAGE_IMPORT_DESCRIPTOR*)
((DWORD)ModuleAddress+ImageOptionalHeaderPointer->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
while(ImageImportDescriptorPointer->FirstThunk!=0)
{
TargetName=(LPCTSTR)((DWORD)ModuleAddress+ImageImportDescriptorPointer->Name);
if(TargetName.Compare(Library)==0)
{
Value=(DWORD)ModuleAddress+ImageImportDescriptorPointer->FirstThunk;
break;
}
ImageImportDescriptorPointer++;
}
if (Value==0)
{
AfxMessageBox(_T("获取导入地址表失败!"));
return FALSE;
}
else
{
ImageThunkDataPointer=(IMAGE_THUNK_DATA*)Value;
while(ImageThunkDataPointer->u1.Function)
{
FunctionAddress=(LPDWORD)&(ImageThunkDataPointer->u1.Function);
if(*FunctionAddress==(DWORD)TargetAddress)
{
DebugInfo.Format(_T("%x"),*FunctionAddress);
EditHeroBlood.SetWindowText(DebugInfo);
VirtualQuery(FunctionAddress,&InforMation,sizeof(InforMation));
VirtualProtect(FunctionAddress, sizeof(DWORD),PAGE_READWRITE,&BeforeProtect);
if (::WriteProcessMemory((HANDLE)-1,FunctionAddress,&ReplaceAddress,sizeof(DWORD),NULL)==FALSE)
{
AfxMessageBox(_T("修改导入地址表失败!"));
return FALSE;
}
else
{
VirtualProtect(FunctionAddress,sizeof(DWORD),BeforeProtect,0);
return TRUE;
}
}
ImageThunkDataPointer++;
}
}
return FALSE;
}
我再换一种语言来讲述:
大家都知道其实我上述我说地名都是一些结构体,而Windows就是靠无数个这样的结构体连接搭建起来的,你中有我,我中有你,这就好比一个生物由无数个细胞组成的一样。因为今天我们不是讲述windows体系,所以我也不做过多解释。
那么通过IAT修改来实现API HOOK的实现原理是什么呢?关键就在于如何在茫茫的内存中找到我们的目标,听起来好像很恐怖,像大海捞针,其实没那么难,因为windows就是通过那些结构体把数据在内存中全部线形连接起来啦。这就像玩大富翁,或者一种挖宝藏游戏,从起点出发走几步就会得到一个提示,告诉我们下一步该怎么走。现在我就带领大家来玩一次这种游戏
先来说明游戏规则
WORD=2步
DWORD=4步
指针=进入下一房间
数组=翻卡片得到答案
RVA=地图宝箱
IMAGE_DOS_HEADER STRUCT
{
这里就是我们的起点,可以通过GetModuleHandle(NULL)获得,比如起点地址是0x00000000,我们得到的第一个提示
(ModuleAddress+ImageDosHearderPointer->e_lfanew+24),怎么理解这个提示呢?就是从起点开始走36步,找到一个叫e_lfanew的门(因为它是指针,所以他就是通往下一个房间的大门),然后推门进去后再走24步,我们就找到了第二个将要给我们提示的地方
e_magic WORD
e_cblp WORD
e_cp WORD
e_crlc WORD
e_cparhdr WORD
e_minalloc WORD
e_maxalloc WORD
e_ss WORD
e_sp WORD
e_csum WORD
e_ip WORD
e_cs WORD
e_lfarlc WORD
e_ovno WORD
e_res WORD
e_oemid WORD
e_oeminfo WORD
e_res2 WORD
e_lfanew DWORD
}
IMAGE_DOS_HEADER ENDS
typedef struct _IMAGE_OPTIONAL_HEADER
{
我们通过上一个提示来到了这个房间,同样我们得到了又一个提示
ModuleAddress+ImageOptionalHeaderPointer->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
理解下这个提示。这代表我们从起点走到e_lfanew大门进入这个房间再走96步找到DataDirectory开始翻卡片(他是一个结构体形数组),来找答案,而答案就在第IMAGE_DIRECTORY_ENTRY_IMPORT(表示1,也就是DataDirectory[1])张卡片内
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
}
IMAGE_OPTIONAL_HEADER,
IMAGE_IMPORT_DESCRIPTOR STRUCT
{
通过上面的提示,我们来到了这个房间,那么下一个提示是什么呢?那就是while(ImageImportDescriptorPointer->FirstThunk!=0),再来理解下这个提示。它是说让我们找到FirstThunk这个地图宝箱(RAV)在里面找到我们需要的地图才能找到下一个房间,那我们就一张一张的翻看吧
我们要找的地图名就是“USER32.dll”
union
Characteristics
OriginalFirstThunk
ends
TimeDateStamp
ForwarderChain
Name1
FirstThunk
}
IMAGE_IMPORT_DESCRIPTOR ENDS
有了地图我们就来到了下一个房间
IMAGE_THUNK_DATA32 STRUCT
哈哈。这就使传说中的IAT表啦,就差一步就找到宝藏啦。我们看一下这次的提示while(ImageThunkDataPointer->u1.Function),它是说让后找到u1.Function这个卡片商来得到宝藏位置的答案,只是这次我们不知道第几张卡片里有我们要的答案。没办法挨个翻吧。指导找到
PeekMessage
union u1
ForwarderString
Function
Ordinal
AddressOfData
ends
IMAGE_THUNK_DATA32 ENDS
找到后,还用我教吗?关闭他的保护属性,然后改写他的地址吧。。。
【小结】
这里我钩了一个目标程序接收消息的函数PeekMessage,然后把它传进来的参数输出出来。看看他会不会自己给自己发消息。HOHO。。挺无聊的
但是如果你想钩点别的。比如目标程序的socket,哈哈~那你觉得这像什么呢?
1.对简单的数据结构在内存中的样子能有个宏观的理解。
2.理解运行在windows环境程序的工作原理。
导入地址表(IAT):Import Address Table 由于导入函数就是被程序调用但其执行代码又不在程序中的函数,这些函数的代码位于一个或者多个DLL 中.当PE 文件被装入内存的时候,Windows 装载器才将DLL 装入,并将调用导入函数的指令和函数实际所处的地址联系起来(动态连接),这操作就需要导入表完成.其中导入地址表就指示函数实际地址。
比如我们想对目标程序的PeekMessage这个API函数进行HOOK,那么只需要找到他的IAT表,并把这个API的实际地址修改,这就完成了一个API HOOK。按常理,想执行此过程需要对PE格式有一定的理解,但是我认为并没有这个必要,毕竟这是一个很简单的工作。接下来我将用我的方法带领大家来实现它,那就是角色扮演。
首先幻想自己是30年代,蓝衣社的一名特务。今天接到上级的任务,去某地杀掉一名为敌对势力工作的人,然后经过易容,伪装成他来执行潜伏。那么目标是谁呢?他又住在哪里呢?拿起MSDN情报科送来的文件看看吧,目标叫PeekMessage,是姓“USER32.dll”家族的成员,它住在:
xxx.exe市
IMAGE_DOS_HEADER区
IMAGE_OPTIONAL_HEADER街
IMAGE_IMPORT_DESCRIPTOR小区
还有一张目标的相片
BOOL PeekMessage
(LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg
)
资料就这么多啦,但是并没有说明目标住在几号楼几层几号啊。不过没有关系我们是特务嘛。这难不倒我们的,Let's begin
坐着蓝衣社为我们准备的专机SetWindowsHookEx把我们(DLL)注入到xxx.exe市,哈哈~下了飞机来到一个陌生的城市真是俩眼一摸黑呀,怎么找我们的目的地呢?最简单的办法:打车,于是我们拦了一辆GetModuleHandle(NULL)牌的出租车,谁知道一上车。司机看到我给他的地址后告诉我要去的地方需要过海,没办法直接到,只能先送我到IMAGE_DOS_HEADER区,然后再换船过海才行。听得我晕头转向的,没办法,走吧。。。闲来打量一下这个城市,满眼尽是一些由0和1搭建黑白2色的高楼大厦,颜色和款式是多么的单调枯燥哇,算了,还是闭目养神吧。不一会我们来到了IMAGE_DOS_HEADER区的水路码头,该下车换乘船过海啦。于是买了(ModuleAddress+ImageDosHearderPointer->e_lfanew+24)号渡轮的船票,继续这次无聊的旅程。晕船从头吐到尾,好不容易熬到了地方,原来一出了码头就来到了IMAGE_OPTIONAL_HEADER街,抬头一望在我们12点钟方向,有个小巴站台,走过去这么一看才知道原来坐
ModuleAddress+ImageOptionalHeaderPointer->DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress线小巴,可以直达我们的终点:IMAGE_IMPORT_DESCRIPTOR小区。二话不说,走着您嘚~~~~~马上要到目的地啦。趁坐小巴的这段时间我们先来整理下思绪,因为不知道具体的楼号和门牌号,所以我们要先想个什么办法,于是找同车的一位美丽小姐打听得知,IMAGE_IMPORT_DESCRIPTOR小区的每座楼都是同一样式的,那就是ImageImportDescriptorPointer->FirstThunk风格,又知道一楼大厅有个收信箱,上面登记着住户的姓名。有了这些线索我们就下车一栋楼,一栋楼的找吧,虽然这个方案毫无创意,但是记得有位大师曾经说过:往往通过复杂的数据结构和华丽的算法并不是解决问题的好方法,因为它加大了维护和调试的难度。所以我们就用这种直接而有效的土办法来老老实实的找吧:先逐楼搜索
while(ImageImportDescriptorPointer->FirstThunk!=0),然后找到一楼大厅的收信箱
TargetName=(LPCTSTR)((DWORD)ModuleAddress+ImageImportDescriptorPointer->Name),再逐户的查找姓“USER32.dll”的家族
if(TargetName.Compare(_T("USER32.dll"))==0),没过多久我们终于找到了,登记簿上写明了具体的门牌号,哈哈~这表示我们离成功只有一步之遥,于是迫不及待的走进ModuleAddress+ImageImportDescriptorPointer->FirstThunk号电梯,走向“USER32.dll”家,来到门口,我停住啦,静静地站在那里平复一下心绪,10秒后我飞起一脚踹开了大门走了进去,映入眼帘的是:坐在屋里男女老少,大大小小10几口子,全部一脸惊愕的盯着我这位不速之客。我拿出相片while(ImageThunkDataPointer->u1.Function)迅速搜索,
FunctionAddress=(PDWORD)&(ImageThunkDataPointer->u1.Function)定位目标,
if(*FunctionAddress==(DWORD)PeekMessageAddress)经过一轮的搜索,我找到了目标,他正傻傻的坐在角落里的电脑桌前,我走到它面前
VirtualQuery(FunctionAddress, &InforMation, sizeof(InforMation))细细的打量着他:凌乱的头发如同杂草,一架高度数眼镜戴在苍白消瘦的脸颊上,驼背,纤细却小腹异常隆起的身材,套着10几年前流行的服饰,HOHO~做技术典型的形象,我冷漠的从怀中掏出了枪:
VirtualProtect(FunctionAddress, sizeof(DWORD),PAGE_READWRITE,&BeforeProtect)顶在目标的眉心。此时此刻,在场的所有人都清楚了我的来意。死亡的恐惧笼罩在每个人的心头,我不在多做停留,无情的勾动了扳机,这就是一个特务的专业操守。嘿嘿
::WriteProcessMemory((HANDLE)-1,FunctionAddress,&FunctionOfSelf,sizeof(DWORD), NULL)目标应声倒地。在手枪的淫威下,其他人也只好无奈的接受这痛苦的事实,我也就成功的完成了此次任务。开始潜伏。
接下来换种语言再来讲述一下这个故事:C++
#include
#include "DialogMain.h"
typedef BOOL (WINAPI* PEEKMESSAGE)(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);
PEEKMESSAGE FakePeekMessage=(PEEKMESSAGE)PeekMessage;
BOOL WINAPI MinePeekMessage(LPMSG lpMsg,HWND hWnd, UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg)
{
AfxMessageBox(_T("你TM是不是调用我啦?"));
return ((PEEKMESSAGE)FakePeekMessage)(lpMsg,hWnd,wMsgFilterMin,wMsgFilterMax,wRemoveMsg);
}
BOOL CDialogMain::ImportAddressTableHook(HMODULE ModuleAddress,LPCTSTR Library,LPCVOID TargetAddress,LPCVOID ReplaceAddress)
{
IMAGE_DOS_HEADER* ImageDosHearderPointer=NULL;
IMAGE_OPTIONAL_HEADER* ImageOptionalHeaderPointer=NULL;
IMAGE_IMPORT_DESCRIPTOR* ImageImportDescriptorPointer=NULL;
IMAGE_THUNK_DATA* ImageThunkDataPointer=NULL;
CString TargetName;
DWORD Value=0;
LPDWORD FunctionAddress=NULL;
MEMORY_BASIC_INFORMATION InforMation;
DWORD BeforeProtect=0;
ImageDosHearderPointer=(IMAGE_DOS_HEADER*)ModuleAddress;
ImageOptionalHeaderPointer=(IMAGE_OPTIONAL_HEADER*)((DWORD)ModuleAddress+ImageDosHearderPointer->e_lfanew+24);
ImageImportDescriptorPointer=(IMAGE_IMPORT_DESCRIPTOR*)
((DWORD)ModuleAddress+ImageOptionalHeaderPointer->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
while(ImageImportDescriptorPointer->FirstThunk!=0)
{
TargetName=(LPCTSTR)((DWORD)ModuleAddress+ImageImportDescriptorPointer->Name);
if(TargetName.Compare(Library)==0)
{
Value=(DWORD)ModuleAddress+ImageImportDescriptorPointer->FirstThunk;
break;
}
ImageImportDescriptorPointer++;
}
if (Value==0)
{
AfxMessageBox(_T("获取导入地址表失败!"));
return FALSE;
}
else
{
ImageThunkDataPointer=(IMAGE_THUNK_DATA*)Value;
while(ImageThunkDataPointer->u1.Function)
{
FunctionAddress=(LPDWORD)&(ImageThunkDataPointer->u1.Function);
if(*FunctionAddress==(DWORD)TargetAddress)
{
DebugInfo.Format(_T("%x"),*FunctionAddress);
EditHeroBlood.SetWindowText(DebugInfo);
VirtualQuery(FunctionAddress,&InforMation,sizeof(InforMation));
VirtualProtect(FunctionAddress, sizeof(DWORD),PAGE_READWRITE,&BeforeProtect);
if (::WriteProcessMemory((HANDLE)-1,FunctionAddress,&ReplaceAddress,sizeof(DWORD),NULL)==FALSE)
{
AfxMessageBox(_T("修改导入地址表失败!"));
return FALSE;
}
else
{
VirtualProtect(FunctionAddress,sizeof(DWORD),BeforeProtect,0);
return TRUE;
}
}
ImageThunkDataPointer++;
}
}
return FALSE;
}
我再换一种语言来讲述:
大家都知道其实我上述我说地名都是一些结构体,而Windows就是靠无数个这样的结构体连接搭建起来的,你中有我,我中有你,这就好比一个生物由无数个细胞组成的一样。因为今天我们不是讲述windows体系,所以我也不做过多解释。
那么通过IAT修改来实现API HOOK的实现原理是什么呢?关键就在于如何在茫茫的内存中找到我们的目标,听起来好像很恐怖,像大海捞针,其实没那么难,因为windows就是通过那些结构体把数据在内存中全部线形连接起来啦。这就像玩大富翁,或者一种挖宝藏游戏,从起点出发走几步就会得到一个提示,告诉我们下一步该怎么走。现在我就带领大家来玩一次这种游戏
先来说明游戏规则
WORD=2步
DWORD=4步
指针=进入下一房间
数组=翻卡片得到答案
RVA=地图宝箱
IMAGE_DOS_HEADER STRUCT
{
这里就是我们的起点,可以通过GetModuleHandle(NULL)获得,比如起点地址是0x00000000,我们得到的第一个提示
(ModuleAddress+ImageDosHearderPointer->e_lfanew+24),怎么理解这个提示呢?就是从起点开始走36步,找到一个叫e_lfanew的门(因为它是指针,所以他就是通往下一个房间的大门),然后推门进去后再走24步,我们就找到了第二个将要给我们提示的地方
e_magic WORD
e_cblp WORD
e_cp WORD
e_crlc WORD
e_cparhdr WORD
e_minalloc WORD
e_maxalloc WORD
e_ss WORD
e_sp WORD
e_csum WORD
e_ip WORD
e_cs WORD
e_lfarlc WORD
e_ovno WORD
e_res WORD
e_oemid WORD
e_oeminfo WORD
e_res2 WORD
e_lfanew DWORD
}
IMAGE_DOS_HEADER ENDS
typedef struct _IMAGE_OPTIONAL_HEADER
{
我们通过上一个提示来到了这个房间,同样我们得到了又一个提示
ModuleAddress+ImageOptionalHeaderPointer->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
理解下这个提示。这代表我们从起点走到e_lfanew大门进入这个房间再走96步找到DataDirectory开始翻卡片(他是一个结构体形数组),来找答案,而答案就在第IMAGE_DIRECTORY_ENTRY_IMPORT(表示1,也就是DataDirectory[1])张卡片内
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
}
IMAGE_OPTIONAL_HEADER,
IMAGE_IMPORT_DESCRIPTOR STRUCT
{
通过上面的提示,我们来到了这个房间,那么下一个提示是什么呢?那就是while(ImageImportDescriptorPointer->FirstThunk!=0),再来理解下这个提示。它是说让我们找到FirstThunk这个地图宝箱(RAV)在里面找到我们需要的地图才能找到下一个房间,那我们就一张一张的翻看吧
我们要找的地图名就是“USER32.dll”
union
Characteristics
OriginalFirstThunk
ends
TimeDateStamp
ForwarderChain
Name1
FirstThunk
}
IMAGE_IMPORT_DESCRIPTOR ENDS
有了地图我们就来到了下一个房间
IMAGE_THUNK_DATA32 STRUCT
哈哈。这就使传说中的IAT表啦,就差一步就找到宝藏啦。我们看一下这次的提示while(ImageThunkDataPointer->u1.Function),它是说让后找到u1.Function这个卡片商来得到宝藏位置的答案,只是这次我们不知道第几张卡片里有我们要的答案。没办法挨个翻吧。指导找到
PeekMessage
union u1
ForwarderString
Function
Ordinal
AddressOfData
ends
IMAGE_THUNK_DATA32 ENDS
找到后,还用我教吗?关闭他的保护属性,然后改写他的地址吧。。。
【小结】
这里我钩了一个目标程序接收消息的函数PeekMessage,然后把它传进来的参数输出出来。看看他会不会自己给自己发消息。HOHO。。挺无聊的
但是如果你想钩点别的。比如目标程序的socket,哈哈~那你觉得这像什么呢?
关于windows核心编程中IAT修改的那段代码
iat表是什么? iat代表什么意思?
射击时,人眼通过枪的准星去瞄准目标,是因为? 射击时,人眼通过枪的准星去瞄准目标,因为?
什么是IE seach hook hi jaker 修改搜索结果的恶意程序
射击时,人眼通过枪的准星去瞄准目标的原因
求助通过修改注册表
通过视频学跳交谊舞有没有详细讲解的?
如何通过记事本修改注册表?
怎样通过注册表修改桌面背景
通过修改注册表显示任务栏
如何通过修改驱动使
怎么通过管理员权限修改时间?
请问IAT纸笔测验是怎么回事,谢谢!!!!
魔兽争霸快捷键如何修改请详细讲解谢谢
人活着的目标!!!!!
目标!!
教育目标的实现,是通过什么体现的?
求教高手!通过3389远程登录目标WIN2000 机子
如何通过扫描得到目标机器信息且分析信息
如何通过扫描得到目标机器信息且分析信息
如何通过扫描得到目标机器信息且分析信息
为什么人会幽默?
QA Hook 是什么意思?
my HOOK ------什么意思