PE导出目录表的OrdinalBase字段被忽略了吗?

| 以我和其他人的经验(http://webster.cs.ucr.edu/Page_TechDocs/pe.txt),PE/COFF规范文档错误地声称序表中包含的导出地址表索引是相对的到序数基数,甚至给出了错误的示例(第5.3节)。实际上,对于序数基= 1的正常情况,序表中的索引是地址表中基于0的索引。 我的问题是,您是否曾经观察到二进制序数不等于1的二进制数?我想知道这是否是一个错误的错误,或者是否从未将Ordinal Base应用于Ordinal Table条目。     
已邀请:
这是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。     
这不是一个一次性的错误,并且序数基数不应用于序数表条目,而是应用于序数本身的计算。是的,Microsoft PE规范(http://msdn.microsoft.com/zh-cn/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
...这就是我得到的:
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
    
不,PE导出目录表的OrdinalBase字段不会被忽略! 上面提供的示例(mfc42.dll)是一个很好的示例(因为其序数基数不是1)。 这里有两个关于此问题的评论: 。就顺序字段而言,“转储”工具的输出是正确的。它显示Base字段为5。这意味着,按名称从mfc42.dll导入导出的函数时,导出地址表中的计算偏移量将为x-5。 Microsoft规范5.3节是正确的。 。就提示而言,转储工具的输出不正确。导出表没有提示字段,只有导入表具有提示字段。 实际上,检索地址表的索引时,序数基数未应用在序数表BUT中!     

要回复问题请先登录注册