《Windows核心编程系列》谈谈修改导入段拦截API
作者:网络转载 发布时间:[ 2012/9/7 10:02:18 ] 推荐标签:
IMAGE_IMPORT_DESCRIPTOR 结构是导入段的基本结构,导入段是由此类型组成的数组构成,每个DLL对应数组中的一项。数组的后一项为NULL。每一项中有两个关键成员,指出IMAGEA_THUNK_DATA类型的数组的偏移量,这两个数组分别列出了从此DLL导入的函数名称,以及它它们在本进程地址空间的RVA。
以下是其定义:
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics;
DWORD OriginalFirstThunk;// 指向一个 IMAGE_THUNK_DATA 结构数组的RVA
}
DWORD TimeDateStamp;// 文件生成的时间
DWORD ForwarderChain;// 这个数据一般为0,可以不关心
DWORD Name; // RVA,指向DLL名字的指针,ASCII字符串
DWORD FirstThunk; //指向一个 IMAGE_THUNK_DATA 结构数组的RVA,这个数据与IAT所指向的地址一致
}IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR
OriginalFirstThunk 和FirstThunk是此结构中的关键成员。它们指出这两个IMAGE_THUNK_DATA类型的数组。
Name 是指向DLL名称的指针。
pImport指向模块的导入段,可以使用它来访问IMAGE_IMPORT_DESCRIPTOR结构的每一个成员。
注意:以上所有偏移量都是相对于模块基地址的,因此在实际使用中一定要加上模块的地址。
OriginalFirstThunk指向NAT,NAT列出了从该DLL导入的所有导入函数的名称。
FirstThunk 指向IAT,IAT列出了与NAT相对应的导入函数的地址。
看此结构定义:
typedef struct _IMAGE_THUNK_DATA32 {
union {
PBYTE ForwarderString;
PDWORD Function;
DWORD Ordinal;
PIMAGE_IMPORT_BY_NAME AddressOfData;
} u1;
} IMAGE_THUNK_DATA32;
上述代码中,外层循环while(pImport->FirstThunk)用于遍历所有DLL,内层循环用于遍历查找每个DLL中的导入函数名称。我们以查找MessageBoxA函数为例来做介绍。此处我们通过对NAT进行扫描,将其与我们给出的字符串类型的函数名MessageBoxA进行比较。注意要使用大小写不敏感的函数:
int WINAPI lstrcmpi(
__in LPCTSTR lpString1,
__in LPCTSTR lpString2
);
这是一种方法,另一种方法是比较函数地址。我们可以对IAT进行扫描,将得到的地址与我们给出的函数地址进行比较。这两种方法是经常使用的方法。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11