根据我和其他人的经验(http://webster.cs.ucr.edu/Page_TechDocs/pe.txt),PE/COFF规范文档错误地声称序数表中包含的导出地址表索引是相对于序数基数的,甚至给出了一个不正确的例子(5.3节)。实际上,对于Ordinal Base = 1的正常情况,Ordinal Table中的索引是地址表中基于0的索引。我在VS Studio生成的PE库和Kernel32.dll等系统库中看到了这一点。
我的问题是,你有没有观察到二进制的序数基不等于1?我想知道这是off-by-one错误,还是Ordinal Base从未应用于Ordinal Table条目。
发布于 2011-04-14 03:24:40
这是mfc42.dll 6.06.8064.0版本的转储文件。
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file mfc42.dll
File Type: DLL
Section contains the following exports for MFC42.dll
00000000 characteristics
4D79A4A3 time date stamp Fri Mar 11 05:27:15 2011
0.00 version
5 ordinal base
6939 number of functions
6 number of names
ordinal hint RVA name
5 0 0000ED7C ?classCCachedDataPathProperty@CCachedDataPathProperty@@2UCRuntimeClass@@B
6 1 0000ED44 ?classCDataPathProperty@CDataPathProperty@@2UCRuntimeClass@@B
7 2 000DEEAC DllCanUnloadNow
8 3 000DEE6C DllGetClassObject
9 4 000DED0A DllRegisterServer
10 5 000DEEDE DllUnregisterServer
256 0004F84F [NONAME]
[...]
6943 0003B412 [NONAME]下面是它在二进制文件中的样子:
;
; Export directory for MFC42.dll
;
dd 0 ; Characteristics
dd 4D79A4A3h ; TimeDateStamp: Fri Mar 11 05:27:15 2011
dw 0 ; MajorVersion
dw 0 ; MinorVersion
dd rva aMfc42_dll ; Name
dd 5 ; Base
dd 1B1Bh ; NumberOfFunctions
dd 6 ; NumberOfNames
dd rva functbl ; AddressOfFunctions
dd rva nametbl ; AddressOfNames
dd rva nameordtbl ; AddressOfNameOrdinals
;
; Export Address Table for MFC42.dll
;
functbl dd rva ?classCCachedDataPathProperty@CCachedDataPathProperty@@2UCRuntimeClass@@B; 0
dd rva ?classCDataPathProperty@CDataPathProperty@@2UCRuntimeClass@@B; 1
dd rva DllCanUnloadNow ; 2
dd rva DllGetClassObject; 3
dd rva DllRegisterServer; 4
dd rva DllUnregisterServer; 5
dd 0F5h dup(rva __ImageBase); 6
dd rva ??0_AFX_CHECKLIST_STATE@@QAE@XZ; 251
[...]
;
; Export Names Table for MFC42.dll
;
nametbl dd rva a?classccachedd, rva a?classcdatapat, rva aDllcanunloadno
dd rva aDllgetclassobj, rva aDllregisterser, rva aDllunregisters
;
; Export Ordinals Table for MFC42.dll
;
nameordtbl dw 0, 1, 2, 3, 4, 5是的,看起来您是对的,序数表中的索引是基于0的。
发布于 2013-12-08 19:43:14
这不是off-by-one错误,Ordinal Base不是应用于Ordinal Table条目,而是应用于序数本身的计算。是的,微软的PE规范(http://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx,第5.3.4节)是错误的。以下是应该如何进行计算:
i = Search_ExportNamePointerTable(ExportName);
ordinal = ExportOrdinalTable[i] + OrdinalBase; // The "+ OrdinalBase" is missing in the official PE specification
SymbolRVA = ExportAddressTable[ordinal - OrdinalBase];或者,用一种不同的方式表达:
i = Search_ExportNamePointerTable(ExportName);
offset = ExportOrdinalTable[i];
SymbolRVA = ExportAddressTable[offset];
ordinal = OrdinalBase + offset;如果我转储我的mfc42.dll...
dumpbin mfc42.dll /exports |more...this是我得到的:
Microsoft (R) COFF/PE Dumper Version 12.00.20827.3
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file mfc42.dll
File Type: DLL
Section contains the following exports for MFC42.dll
00000000 characteristics
4D798B26 time date stamp Fri Mar 11 03:38:30 2011
0.00 version
5 ordinal base
6888 number of functions
8 number of names
ordinal hint RVA name
1452 0 000EF5D8 ?AfxFreeLibrary@@YAHPEAUHINSTANCE__@@@Z
1494 1 000EF5A4 ?AfxLoadLibrary@@YAPEAUHINSTANCE__@@PEBD@Z
1497 2 000F8344 ?AfxLockGlobals@@YAXH@Z
1587 3 000F83DC ?AfxUnlockGlobals@@YAXH@Z
7 4 000FC83C DllCanUnloadNow
8 5 000FC7E0 DllGetClassObject
9 6 000FC870 DllRegisterServer
10 7 000FC87C DllUnregisterServer
5 0001C910 [NONAME]
6 0001C8E8 [NONAME]
256 0005DEC0 [NONAME]
257 000423C0 [NONAME]
258 00042400 [NONAME]
259 00042440 [NONAME]
[...]上面的第7个函数(例如)是DllRegisterServer,它对应于下面的十六进制转储mfc42.dll中导出序数表中的第7个单词(0x0004)。首先是A7 05。
59 CC 12 00 6B CC 12 00 A7 05 D1 05 D4 05 2E 06
02 00 03 00 04 00 05 00 4D 46 43 34 32 2E 64 6C计算:
i = Search_ExportNamePointerTable("DllRegisterServer") = 7 - 1 = 6 // zero-based
offset = ExportOrdinalTable[6] = 4
SymbolRVA = ExportAddressTable[4] = ...
ordinal = OrdinalBase + offset = 5 + 4 = 9发布于 2012-06-20 22:17:38
否,PE导出目录表的OrdinalBase字段未被忽略!
上面提供的示例(mfc42.dll)是一个很好的示例(因为它的Ordinal Base不是1)。
以下是关于这个问题的两点意见:
。就序数字段而言,转储工具的输出是正确的。它显示Base字段是5。这意味着,当按名称从mfc42.dll导入导出函数时,Export Address Table中计算的偏移量将是x-5。Microsoft规范5.3节是正确的。
。就提示而言,转储工具的输出不正确。导出表没有提示字段,只有导入表有提示字段。
事实上,序数基数不是在序数表中应用的,而是在检索地址表的索引时应用的!
https://stackoverflow.com/questions/5653316
复制相似问题