dll知识点查遗补缺 续
1.导入函数
(1)如果程序静态连接时,声明函数采用了__declspec(dllimport)
调用Foo时,被翻译成call [_imp_Foo]
其中_imp_Foo是idata节里面的数据,dll的loader会修改这个地址里的数值。
_imp_Foo是FirstTrunk值。
一般情况下,VC引入windows.h会采用这种方式。
(2)如果程序静态连接时,没有采用了__declspec(dllimport)
调用Foo时,被翻译成call _Foo
而编译器会自动生成_Foo函数,这只是个躯壳。
_Foo:
jump [_imp_Foo]
(3)采用GetProcAddress方式
这种方式不会有_imp_Foo类似的地址,GetProcAddress返回的就是函数地址,直接call就可以了
2.导出函数
打开PE文件,DOS文件头中的EXEHeaderOffset找到ExeHeader(COFF HEADER),然后跨越COFF Header和Option Header,找到Data_Directory中的ExportTable(RVA,size)。通过这个RVA得到一个数据结构,如下:
(以ntdll.dll为例)
->Export Table
Characteristics: 0x00000000
TimeDateStamp: 0x498C0F8C (GMT: Fri Feb 06 10:23:08 2009)
MajorVersion: 0x0000
MinorVersion: 0x0000 -> 0.00
Name: 0x00006790 ("ntdll.dll")
Base: 0x00000001
NumberOfFunctions: 0x00000524
NumberOfNames: 0x00000524
AddressOfFunctions: 0x00003428
AddressOfNames: 0x000048B8
AddressOfNameOrdinals: 0x00005D48
Base为0x00000001,表示第一个出现的函数标号为1,以后类推。
其中AddressOfNames记指向一个RVA数组,每个RVA指向一个函数字符串。
AddressOfFunctions指向一个RVA数组,每个RVA指向一个函数的RVA。