C PE文件的内存映射IAT中u1.AddressOfData开头的2个字节是什么?

C PE文件的内存映射IAT中u1.AddressOfData开头的2个字节是什么?,c,windows,winapi,portable-executable,C,Windows,Winapi,Portable Executable,因此,为了解析PE进程内存中的IAT表并获得导入函数的名称,我们必须迭代每个模块的函数,对于每个模块,使用thunkData->u1.AddressOfData+2获得函数名称字符串的开头(我不想开始解释这些指针是什么,因为我假设任何知道答案的人都知道这一点。u1是Windows的预定义结构,其中始终包含AddressOfData) 因此,基本上对于IAT中的每个函数,我们必须使用u1.AddressOfData+2来获取字符串开头的地址,但我不知道它的开头2个字节是什么?Microsoft文档

因此,为了解析PE进程内存中的IAT表并获得导入函数的名称,我们必须迭代每个模块的函数,对于每个模块,使用thunkData->u1.AddressOfData+2获得函数名称字符串的开头(我不想开始解释这些指针是什么,因为我假设任何知道答案的人都知道这一点。u1是Windows的预定义结构,其中始终包含AddressOfData)

因此,基本上对于IAT中的每个函数,我们必须使用u1.AddressOfData+2来获取字符串开头的地址,但我不知道它的开头2个字节是什么?Microsoft文档没有解释这一点:

(查找延迟导入名称表)

我试着调试它,看看它们开头的值是什么,它们是0x8600和0xe700,所以通常是1字节的数据和1字节的00


那么这是什么?

图像数据结构中,如果函数地址尚未解析且函数未按顺序捕捉-
数据的地址
指向
PIMAGE\u按名称导入
(在winnt.h和/或ntimage.h中可以看到)

名称前的前2个字节-这是AddressOfNames-exported names表(查找
IMAGE\u EXPORT\u DIRECTORY
)中的提示索引。此名称表按名称按字母顺序排序,用于快速二进制搜索功能。提示用于快速检查,然后放入二进制搜索。如何使用它我们可以在wrk src代码中查看

    //
    // Lookup Name in NameTable
    //

    NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);
    NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);

    //
    // Before dropping into binary search, see if
    // the hint index results in a successful
    // match. If the hint index is zero, then
    // drop into binary search.
    //

    HintIndex = ((PIMAGE_IMPORT_BY_NAME)NameThunk->u1.AddressOfData)->Hint;
    if ((ULONG)HintIndex < ExportDirectory->NumberOfNames &&
        !strcmp((PSZ)((PIMAGE_IMPORT_BY_NAME)NameThunk->u1.AddressOfData)->Name,
         (PSZ)((PCHAR)DllBase + NameTableBase[HintIndex]))) {
        OrdinalNumber = NameOrdinalTableBase[HintIndex];

    }
    else {

        //
        // Lookup the import name in the name table using a binary search.
        //
//
//名称表中的查找名称
//
NameTableBase=(PULONG)((PCHAR)DllBase+(ULONG)ExportDirectory->AddressOfNames);
NameOrdinalTableBase=(PUSHORT)((PCHAR)DllBase+(ULONG)ExportDirectory->AddressOfNameOrdinals);
//
//在进入二进制搜索之前,请查看
//提示索引将导致成功的
//匹配。如果提示索引为零,则
//进入二进制搜索。
//
HintIndex=((PIMAGE\u IMPORT\u BY\u NAME)NameThunk->u1.AddressOfData)->提示;
如果((ULONG)HintIndexNumberOfNames&&
!strcmp((PSZ)((PIMAGE\u IMPORT\u BY\u NAME)NAME thunk->u1.AddressOfData)->NAME,
(PSZ)((PCHAR)DllBase+NameTableBase[HintIndex])){
OrdinalNumber=NameOrdinalTableBase[HintIndex];
}
否则{
//
//使用二进制搜索在名称表中查找导入名称。
//

但是,此索引通常只能在系统映像中有效。如果我们自己构建映像-在best cast中,此提示只能对一个windows版本有效(我们从lib文件中得到提示)-当创建新版本windows时-通常添加新的导出api,因为表按字母顺序排序-索引为[can]已更改

这是按名称导入的图像
-第一个
单词
(2字节)是
提示
(导入模块的导出表中的提示索引)。确实,这已经过时。提示几乎总是包含错误的值。因此,提示是加载此函数的模块的导出表的索引。为什么它总是包含错误的值,这是否意味着这2个字节没有用处,从未使用过?是的,此字节没有用处。需要查找当前加载程序实现-可能使用,可能使用不是。从何处得到提示?从构建pe时使用的库中。系统映像真的更新了(移动到下一个windows版本时的最小值是多少),导出表更改,索引更改。在实践中提示通常是错误的。但是这不会导致错误-这只是快速检查,如果未命中-转到二进制搜索以更正索引name@Anders-你是说wrk代码?microsoft自行打开此代码src@Anders-我真的不知道这一切是怎么正式合法的,也许你更清楚这一点。简单地说,呵呵w我知道-wrk是合法的开放源代码,不像win2000 src代码,它是泄漏的。我想你应该有一些特殊的许可证,你不能像那样把它放在GitHub上。@Anders-所以我需要删除链接,但留下了代码片段?:“…可以通过MSDNAA订户下载获得(参与部门的管理员可以访问)或者通过教员连接门户(需要登录)发送给合格的学术教员或工作人员。“所以,是的,我会删除该链接。我不知道代码。
    //
    // Lookup Name in NameTable
    //

    NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);
    NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);

    //
    // Before dropping into binary search, see if
    // the hint index results in a successful
    // match. If the hint index is zero, then
    // drop into binary search.
    //

    HintIndex = ((PIMAGE_IMPORT_BY_NAME)NameThunk->u1.AddressOfData)->Hint;
    if ((ULONG)HintIndex < ExportDirectory->NumberOfNames &&
        !strcmp((PSZ)((PIMAGE_IMPORT_BY_NAME)NameThunk->u1.AddressOfData)->Name,
         (PSZ)((PCHAR)DllBase + NameTableBase[HintIndex]))) {
        OrdinalNumber = NameOrdinalTableBase[HintIndex];

    }
    else {

        //
        // Lookup the import name in the name table using a binary search.
        //