查看加载到内存中的 kernel32.dll,我看到以下导出序数表:
(gdb) x /400hd $eax
0x776334b0 <Wow64Transition+71576>: 3 4 5 6 7 8 9 10
0x776334c0 <Wow64Transition+71592>: 11 12 13 14 15 16 17 18
0x776334d0 <Wow64Transition+71608>: 19 20 21 22 23 24 25 26
0x776334e0 <Wow64Transition+71624>: 27 28 29 30 31 32 33 34
0x776334f0 <Wow64Transition+71640>: 35 36 37 38 39 40 41 42
0x77633500 <Wow64Transition+71656>: 43 44 45 46 47 48 49 50
0x77633510 <Wow64Transition+71672>: 51 52 53 54 55 56 57 58
0x77633520 <Wow64Transition+71688>: 59 60 61 62 63 64 65 66
0x77633530 <Wow64Transition+71704>: 67 68 69 70 0 71 72 73
0x77633540 <Wow64Transition+71720>: 74 75 76 77 78 79 80 81
0x77633550 <Wow64Transition+71736>: 82 83 84 85 86 87 88 89
0x77633560 <Wow64Transition+71752>: 90 91 92 93 94 95 96 97
可以验证的是,导出了序数 0。
但是假设导出目录表的 OrdinalBase 字段设置为 1,序数怎么可能小于 1?:
Ordinal Base:此中导出的起始序号
图像。该字段指定导出的起始序号
地址表。通常设置为 1。
该文档说序数是有偏见的,即:
导出序数表是导出中的 16 位索引数组
地址表。序数因序数基字段而产生偏差
导出目录表。换句话说,序数基数必须是
从序数中减去以获得导出中的真实索引
地址表。
现在,这意味着序数 0 会在导出地址表中产生索引 -1?
从我的角度来看,序数似乎是预先调整的(即从每个序数中减去 1),但随后“官方”算法(也在 PE 文档中说明)失败了:
因此,当搜索导出名称指针表并找到匹配的
字符串在位置 i 找到,查找符号的算法
地址是:
i = Search_ExportNamePointerTable (ExportName);
ordinal =
ExportOrdinalTable [i];
SymbolRVA = ExportAddressTable [ordinal - OrdinalBase];
我想到的唯一想法如下:加载程序在将 DLL 加载到内存中时调整了导出序数表中的序数。
谁能给出解释吗?
这是 PE/COFF 规范中的一个已知错误。指定的算法是完全错误的,应该是
ordinal = ExportOrdinalTable [i] + OrdinalBase;
not
ordinal = ExportOrdinalTable [i];
因为序数表实际上包含unbiased序数词。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)