看看它加载到内存中的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
可以validation,0的序数被导出。
但是,如果导出目录表的OrdinalBase字段设置为1,那么序数如何小于1?
序号:在这张图片中出口的序号。 该字段指定导出地址表的起始序号。 通常设置为1。
文件说,序号是有偏见的,即:
导出序号表是导出地址表中的一个16位索引数组。 序数偏离导出目录表的序号基地字段。 换句话说,序数基数必须从序数中减去才能得到导出地址表的真实索引。
现在,这意味着一个0的序数会在出口地址表中产生一个-1的索引?
从我的angular度来看,似乎序数是经过预先调整的(即从每一个中减去1),但是“官方”algorithm(在PE-docs中也有说明)失败了:
因此,当search出口名称指针表并且在位置ifind匹配的string时,用于find符号地址的algorithm是:
i = Search_ExportNamePointerTable (ExportName); ordinal = ExportOrdinalTable [i]; SymbolRVA = ExportAddressTable [ordinal - OrdinalBase];
唯一想到的是以下内容:加载程序在将DLL加载到内存中时调整了导出序号表中的序号。
任何人都可以给出解释吗?
这是PE / COFF规范中的一个已知错误。 指定的算法是错误的,应该是
ordinal = ExportOrdinalTable [i] + OrdinalBase;
不
ordinal = ExportOrdinalTable [i];
因为序数表实际上包含不偏倚的序数。