为了以后的叙述方便还给树的每一个节点起了名字,第一层的叫11,第二层的叫21,22,23,24,第三层的叫31,32,33,34,35,36,37,38,39,310,311,312。
在资源节开始处,是一个directory结构,这个结构中指明了紧跟在它后面的一个directory_entry结构数组中的元素的个数。这个directory结构之后,紧跟着的就是那个directory_entry结构数组。他们一起组成了11。就如图4.1中所示。其他的每个节点,21,22..31,32..312,都是这样,每个 directory结构后面紧跟directory_entry 结构数组。11中的directory_entry结构数组中的每一个元素,都存有到下一层某个节点的偏移。也就是通过directory_entry结构数组的每个元素可以找到21,22,23,24。其他的节点中情况也是一样。图中看不到的一点是,所有的节点之间都是紧紧的挨在一起存放的,11之后紧跟着的是21,21之后紧跟着的是22,22之后紧跟着的是23。依此类推。directory_entry结构数组中的每一个元素除了有到下一层某节点的偏移,(是下一层的节点,还是已经到了最终的data_entry,后面详细叙述)还有一个Name或者Id字段(是Name还是Id后面详细叙述),根据不同的层,代表的含义也不一样。第一层的每个directory_entry的这个值,代表类型。比如11的第一个directory_entry的Id值为3,3代表icon,从这个directory_entry往下的都是都是图标了(关于不同类型值的定义,后面详细叙述)。第二层每个directory_entry的这个值代表Name,第三层代表Language。11,21,31的左边那个data_entry,的三个值分别为3,1,409(都是16进制),就是说是一个图标类型,Name为1h,Language为409h的资源。
下面我们来通过telnet.exe中资源节的具体内容来看,用开始讲到的寻找资源节在文件中位置的方法,我们找到了资源节在文件中的位置为00013600h。
我们为了看起来清楚,每一行是一个结构,并且每个结构的不同成员用 / 分开,例如,
一个directory结构 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 04 00
可以看到结构成员,Characteristics为0,TimeDateStamp为0,MajorVersion为4,(如果你不明白为什么是0004而不是0400的话,请看 《JIURL PE 格式学习总结(一)》中关于 big-endian和little-endian的介绍),MinorVersion为0,NumberOfNamedEntries为0,NumberOfIdEntries为4。
一个directory_entry结构 03 00 00 00 / 30 00 00 80
可以看到结构成员,第一个字段的第一个字节00h的二进制为00000000,最高位为0,所以低两个字节中的值为Id,Id为3。第二个字段的第一个字节80h(如果你不明白为什么第一个字节是80h而不是30h的话,请看 《JIURL PE 格式学习总结(一)》中关于 big-endian和little-endian的介绍)的二进制为10000000,最高位为1 所以说明还有下一层,还没有到叶子,所以第二字段代表到下一层某个节点的偏移 OffsetToData 值为30。
一个data_entry结构 E0 23 03 00 / 30 01 00 00 / E4 04 00 00 / 00 00 00 00
可以看到结构成员,OffsetToData为323E0h(这是一个内存中的RVA,要转化成文件中的位置,需要用这个值减去资源节的开始RVA,资源节的开始RVA可以由Optional Header中的DataDirectory数组中的第三项中的VirtualAddress的值得到。或者节表中,资源节那项中的VirtualAddress的值得到。相减之后,就可以得到相对于资源节开始的偏移。再加上资源节在文件中的开始位置,节表中资源节那项中的PointerToRawData的值,就是资源在文件中的位置。),Size为130h,CodePage为4E4h,Reserved为0。
下面就是telnet.exe中的内容,可以用16进制编辑器打开附带的telnet.exe对照着看。
00013600h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 04 00
(directory结构,16字节长。图4.1中11中的directory。0个NamedEntries,4个IdEntries。)
00013610h: 03 00 00 00 / 30 00 00 80
(directory_entry结构,8字节长。图4.1中11中的directory_entry数组第一个元素。第一个字段高位为0,说明第一个字段表示id,由于是第一层,所以类型id为3。第二个字段高位为1,说明还有下一层,第二字段中的低31位为到图4.1中21的偏移,30+00013600h=00013630h。)
00013618h: 06 00 00 00 / 50 00 00 80
00013620h: 0E 00 00 00 / A0 00 00 80
00013628h: 10 00 00 00 / B8 00 00 80
00013630h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 02 00 (directory21)
00013640h: 01 00 00 00 / D0 00 00 80 (d0+00013600h=000136d0h。)
00013648h: 02 00 00 00 / F0 00 00 80
00013650h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 08 00 (directory22)
00013660h: 08 00 00 00 / 10 01 00 80
00013668h: 09 00 00 00 / 30 01 00 80
00013670h: 0C 00 00 00 / 50 01 00 80
00013678h: 0D 00 00 00 / 70 01 00 80
00013680h: 10 00 00 00 / 90 01 00 80
00013688h: 11 00 00 00 / B0 01 00 80
00013690h: 12 00 00 00 / D0 01 00 80
00013698h: 39 00 00 00 / F0 01 00 80
000136a0h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 01 00 / 00 00
(directory结构,16字节长。图4.1中23。1个NamedEntries,0个IdEntries。)
000136b0h: D0 03 00 80 / 10 02 00 80
(directory结构中已经表明这是一个NamedEntries,第一个字段中的高位为1,说明第一个字段中的值为一个指向IMAGE_RESOURCE_DIR_STRING结构的偏移,3D0+00013600h=000139D0h。)
000136b8h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 01 00 (directory24)
000136c8h: 01 00 00 00 / 30 02 00 80
000136d0h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 02 00 (directory31)
000136e0h: 09 04 00 00 / 50 02 00 00
(directory_entry结构,8字节长。第一个字段高位为0,说明第一个字段表示id,由于是第三层,所以Language id为409h。第二个字段高位为0,说明已经是叶子了,第二字段中的低31位为到一个data_entry结构的偏移,250+00013600h=00013850h。)
000136e8h: 04 08 00 00 / 60 02 00 00
000136f0h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 02 00 (directory32)
00013700h: 09 04 00 00 / 70 02 00 00
00013708h: 04 08 00 00 / 80 02 00 00
00013710h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 02 00 (directory33)
00013720h: 09 04 00 00 / 90 02 00 00
00013728h: 04 08 00 00 / A0 02 00 00
00013730h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 02 00 (directory34)
00013740h: 09 04 00 00 / B0 02 00 00
00013748h: 04 08 00 00 / C0 02 00 00
00013750h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 02 00 (directory35)
00013760h: 09 04 00 00 / D0 02 00 00
00013768h: 04 08 00 00 / E0 02 00 00
00013770h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 02 00 (directory36)
00013780h: 09 04 00 00 / F0 02 00 00
00013788h: 04 08 00 00 / 00 03 00 00
00013790h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 02 00 (directory37)
000137a0h: 09 04 00 00 / 10 03 00 00
000137a8h: 04 08 00 00 / 20 03 00 00
000137b0h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 02 00 (directory38)
000137c0h: 09 04 00 00 / 30 03 00 00
000137c8h: 04 08 00 00 / 40 03 00 00
000137d0h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 02 00 (directory39)
000137e0h: 09 04 00 00 / 50 03 00 00
000137e8h: 04 08 00 00 / 60 03 00 00
000137f0h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 02 00 (directory310)
00013800h: 09 04 00 00 / 70 03 00 00
00013808h: 04 08 00 00 / 80 03 00 00
00013810h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 02 00 (directory311)
00013820h: 09 04 00 00 / 90 03 00 00
00013828h: 04 08 00 00 / A0 03 00 00
00013830h: 00 00 00 00 / 00 00 00 00 / 04 00 / 00 00 / 00 00 / 02 00 (directory312)
00013840h: 09 04 00 00 / B0 03 00 00
00013848h: 04 08 00 00 / C0 03 00 00
00013850h: E0 23 03 00 / 30 01 00 00 / E4 04 00 00 / 00 00 00 00
(data_entry结构,16字节长,存有一个资源的RVA和大小。资源节开始处的RVA为32000。先算出该资源相对于资源开始处的偏移323E0-32000=3E0h。再用偏移加上资源节开始处的文件偏移13600得到该资源在文件中的位置,3E0+13600=139E0h。)
上一页 1 2 3 4 下一页