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。

posted @ 2009-12-13 23:41  Fan Zhang  阅读(194)  评论(0)    收藏  举报