Address offame ordinals Address ofnames RVA of Name 1 Index of Name RVA of Name 2 Index of name 2 RVA of Name 3 <→> Index of name 3 RVA of Name 4 Index of name 4 RVA of Name n Index of Name N
AddressOfNames AddressOfNameOrdinals | | RVA of Name 1 <--> Index of Name 1 RVA of Name 2 <--> Index of Name 2 RVA of Name 3 <--> Index of Name 3 RVA of Name 4 <--> Index of Name 4 ... ... ... RVA of Name N <--> Index of Name N
IMAGE EXPORT DIRECTORY+Filename.dll 函数入口地址RVA|无名函数(序号x) Name 函数入口地址 RVA MyFun1函数(序号x+1) nBase(假设值x) Numberoffunctions a函数入口地址 RVA MyFun2函数(序号x+a)< Numberofnames b函数入口地址RVA| My Fun3函数(序号x+b) Addressoffuncitons Addressofnames AddressofNameOrdinalsh-R+Mhun4……>1 MyFun2< RVA MyFun3< <
... Name nBase(假设值x) NumberOfFunctions NumberOfNames AddressOfFuncitons AddressOfNames AddressOfNameOrdinals IMAGE_EXPORT_DIRECTORY Filename.dll 函数入口地址RVA 函数入口地址RVA ... 函数入口地址RVA 函数入口地址RVA ... 0 1 a b RVA RVA ... RVA ... MyFun1 MyFun2 ... MyFun3 ... 1 a ... b ... 无名函数(序号x) MyFun1函数(序号x+1) MyFun2函数(序号x+a) MyFun3函数(序号x+b)
根据引出函数名,怎样来获取其地址呢 ·1定位到 PE header。 ·2从数据目录读取引出表的虚拟地址 3定位引出表获取名字数目( Numberofnames) ·4.并行遍历 Address OfNames和 Address OfName Ordinals指向的数组 匹配名字。如果在 AddressofNames指向的数组中找到匹配名字,从 Address ofName Ordinals指向的数组中提取索引值。 例如,若发现匹配名字的RVA存放在 AddressofNames数组的第77个元 素,那就提取 AddressofNameOrdinals数组的第77个元素作为索引值 如果遍历完№ umberofNames个元素,说明当前模块没有所要的名字 ·5.从 Address ofName Ordinals数组提取的数值作为 Address ofFunctions数组的索引。也就是说,如果值是5,就必须读 取 Addressof" Functions数组的第5个元素,此值就是所要函数的RVA
根据引出函数名,怎样来获取其地址呢? • 1.定位到PE header。 • 2.从数据目录读取引出表的虚拟地址。 • 3.定位引出表获取名字数目(NumberOfNames)。 • 4.并行遍历AddressOfNames和AddressOfNameOrdinals指向的数组 匹配名字。如果在AddressOfNames 指向的数组中找到匹配名字,从 AddressOfNameOrdinals 指向的数组中提取索引值。 – 例如,若发现匹配名字的RVA存放在AddressOfNames 数组的第77个元 素,那就提取AddressOfNameOrdinals数组的第77个元素作为索引值。 如果遍历完NumberOfNames 个元素,说明当前模块没有所要的名字。 • 5.从AddressOfNameOrdinals数组提取的数值作为 AddressOfFunctions数组的索引。也就是说,如果值是5,就必须读 取AddressOfFunctions数组的第5个元素,此值就是所要函数的RVA
IMAGE EXPORT DIRECTORY结构的 nBase成员 nBase是一个基数。(引出序数- nBase)就是 函数地址数组的索引值了 ·如果程序员在def文件中设定起始序数号为200, 这意味着 AddressofFunctions数组至少有200个 元素。即使这前面200个元素并没使用,但它们 必须存在。 ·有了 nbase,就节约了200个空元素。注意 nBase 并不影响 Addressofnameordinals数组的值
IMAGE_EXPORT_DIRECTORY结构的 nBase成员 • nBase是一个基数。(引出序数- nBase)就是 函数地址数组的索引值了。 • 如果程序员在def文件中设定起始序数号为200, 这意味着AddressOfFunctions数组至少有200个 元素。即使这前面200个元素并没使用,但它们 必须存在。 • 有了nBase,就节约了200个空元素。注意nBase 并不影响AddressOfNameOrdinals数组的值
根据函数序数获取函数地址的步骤 ·1.定位到 PE header。 ·2从数据目录读取引出表的虚拟地址 3定位引出表获取 nBase值。 4减掉 nBase值得到指向 Addressof" Functions数 组的索引。 ·5将该值与 Numberoffunctions作比较,大于等 于后者则序数无效。 ·6通过上面的索引就可以获取 AddressofFunctions数组中的RVA了
根据函数序数获取函数地址的步骤 • 1.定位到PE header。 • 2.从数据目录读取引出表的虚拟地址。 • 3.定位引出表获取nBase值。 • 4.减掉nBase值得到指向AddressOfFunctions 数 组的索引。 • 5.将该值与NumberOfFunctions作比较,大于等 于后者则序数无效。 • 6.通过上面的索引就可以获取 AddressOfFunctions 数组中的RVA了