我们先假设。FAC这里是文件偏移地址。(程序在没有运行的时候,没有导入dbg的时候,程序本身这个地址存放的内容。)运行起来后(dbg到oep的时候)fac的位置就是4031AC
也就是说。本身FAC是60330000,变成了电脑messageboxa的起始位置。501ADC76
那么他是怎么获取messageboxa的地址呢?因为fac存放的就是messageboxa的字符串名字。因为这个60330000是一个偏移地址。(这里要倒着读。3360是一个偏移地址)这里,基址(装载基址)+偏移地址(RVA,相对偏移地址)就是这个api函数的名称。
我们定位一下这个地址。403360(这里注意了。00就是结尾。)
第一阶段总结
FAC = 60 33 00 00 = MessageBoxA (函数名称字符串)
FAC = 50 1A DC 76 = MessageBoxA (函数入口点位置)(注意,每次开机关机都会导致这个地址改变)
我们再看程序PE结构。
首先我们来到程序PE里面看到IAT的地址是3000(偏移地址)
大小是670
那么他就是从403000开始,到403670结束的。
然后,我们去到403000,这里。五个dword就是一个iid
- 模块名:指向被导入的DLL的名称。
- 函数名或序号:指向被导入的函数,可能以名称的形式存在,也可能是函数在DLL中的序号。
- 其他信息:可能包括一些额外的标志位或指针,用于处理导入过程中的其他需求。
认识IID
具体的结构体称为 IMAGE_IMPORT_DESCRIPTOR
。虽然IID的详细结构可能会因操作系统版本和其它因素有所变化,但一般来说,每个IID通常由多个字段组成。以下是一个典型的 IMAGE_IMPORT_DESCRIPTOR
结构及其主要字段的解释:
1. Characteristics (通常是 4 字节)
- 描述:此字段通常用于标识模块的特性,也可能是保留字段,在某些情况下,它可以用于标识模组的序号。
- 作用:有时可能包含DLL的特定信息。
2. TimeDateStamp (时间戳,通常是 4 字节)
- 描述:表示该模块的时间戳,通常是指DLL文件的最后修改时间。
- 作用:用于版本控制和验证,以确保加载的DLL是最新的。
3. ForwarderChain (转发链,通常是 4 字节)
- 描述:指向转发函数的链表。如果该DLL需要从另一个DLL转发函数,这里会指向相应的DLL的导入描述符。
- 作用:处理函数转发,确保函数调用能正确解析。
4. Name (名称,通常是 4 字节)
- 描述:指向一个字符串的指针,该字符串是DLL的名称(例如 “kernel32.dll”)。
- 作用:告诉加载器要导入哪个DLL。
5. ImportAddressTable (导入地址表,通常是 4 字节)
- 描述:指向导入地址表的指针,包含了需要导入的函数的地址或者名称。
- 作用:在程序运行时,加载器会使用这个表来解析和填充实际的函数地址。
总结
这些字段共同工作,使得操作系统能够在运行时动态链接所需的DLL和函数。每个字段都在导入过程中起着重要的作用,确保程序能够正确地访问外部库提供的功能。注意,具体实现可能会有所不同,且有些字段在某些情况下可能会被留空或不使用。
IID总结
我们关注IID,只需要关心第四个的名字和第五个的导入表地址。(第四个和第五个都是偏移地址。)
第四个是存放的dll名称的偏移地址,也就是字符串。
第五个是函数的地址(我们加上基址过去后,得到的一个dword就是函数地址字符串的位置)然后以一个dword为一个周期。程序开始获取这个dll的所有函数的地址。直到出现00000000结束。
暂无评论内容