第四章:导入表
windos加载器会一并加载导入表中的dll,并修改相应指令调用的函数地址。
IMAGE_NT_HEADERS STRUCT{
Signature DWORD ?
FileHeader IMAGE_FILE_HEADER <>
OptionalHeader IMAGE_OPTIONAL_HEADER32 <>
}IMAGE_NT_HEADERS ENDS
IMAGE_OPTIONAL_HEADER32{
...
...
DataDirectory IMAGE_DATA_DIRECTORY 16 dup(<>) ;0078h //相对IMAGE_NT_HEADERS偏移量
...
}
IMAGE_DATA_DIRECTORY STRUCT{
VirtualAddress DWORD ?
isize DWORD ?
}
导入表: OptionalHeader.DataDirectory[1]
IAT: OptionalHeader.DataDirectory[12]
导入表数据的起始是一组导入表描述符结构,每组20B,全0结尾,所以上面isize都是20B的整数倍。
IMAGE_IMPORT_DESCRIPTOR STRUCT{
union{
Characteristics dd ?
OriginalFirstThunk dd ? ;//桥1 指向_IMAGE_THUNK_DATA数组
}ends
TimeDateStamp dd ?
ForwarderCharin dd ? ;//链表的前一结构
Name1 dd ? ;//指向连接库名字的指针
FirstThunk dd ? ;//桥2
}
OriginalFirstThunk 指向一个数组,数组成员_IMAGE_THUNK_DATA,其实就是DWORD,最高位0,表示导入函数是个数值(RVA),为1,导入函数是符号。
导入函数是个数值(RVA)指向的是IMGE_IMPORT_BY_NAME
IMGE_IMPORT_BY_NAME{
Hint dd ? //dll对每个函数进行编号,这个就是,可以用编号也可以用名字来访问
Name1 db ?
}
双桥结构的导入表在文件中存在两份内容完全相同的地址列表,桥2指向的地址列表叫IAT,桥1的叫INT(Import Name Table)
Borland公司的link.exe只保留桥2. 单桥结构的导入表无法执行绑定导入操作
桥1:(hint - name)
IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[1].OriginalFirstThunk.Hint
IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[1].OriginalFirstThunk.Name1
桥2:
IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[1].FirstThunk IAT中的值(VA)
IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[1].OriginalFirstThunk 与IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[1].FirstThunk IAT中的值 在文件中相同的;
PE加载后进程空间中的 IAT的值 被修改为真实的VA,此时通过(hint - name)的桥断了。
IAT表: 相同链接库的函数的VA放在一起最近DWORD全零结束。
定位IAT表有两种文件,1.直接OptionalHeader.DataDirectory[12] 2.桥2:IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[1].FirstThunk
导入表: OptionalHeader.DataDirectory[1] 仅仅指IMAGE_IMPORT_DESCRIPTOR结构数组。
遍历导入表信息,可以猜测大致功能,应用逆向与病毒分析。
绑定导入机制
WINDOWS加载程序负责IAT的修正工作,加载前提前修正就是绑定。WINDOWS加载程序也会对绑定过的进行验证
IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[11].VirtualAddress
HEX查看
IMAG