首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否忽略PE导出目录表的OrdinalBase字段?

是否忽略PE导出目录表的OrdinalBase字段?
EN

Stack Overflow用户
提问于 2011-04-14 01:43:07
回答 3查看 2K关注 0票数 7

根据我和其他人的经验(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条目。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-04-14 03:24:40

这是mfc42.dll 6.06.8064.0版本的转储文件。

代码语言:javascript
复制
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]

下面是它在二进制文件中的样子:

代码语言:javascript
复制
;
; 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的

票数 4
EN

Stack Overflow用户

发布于 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节)是错误的。以下是应该如何进行计算:

代码语言:javascript
复制
i = Search_ExportNamePointerTable(ExportName);
ordinal = ExportOrdinalTable[i] + OrdinalBase;  // The "+ OrdinalBase" is missing in the official PE specification
SymbolRVA = ExportAddressTable[ordinal - OrdinalBase];

或者,用一种不同的方式表达:

代码语言:javascript
复制
i = Search_ExportNamePointerTable(ExportName);
offset = ExportOrdinalTable[i];
SymbolRVA = ExportAddressTable[offset];
ordinal = OrdinalBase + offset;

如果我转储我的mfc42.dll...

代码语言:javascript
复制
dumpbin mfc42.dll /exports |more

...this是我得到的:

代码语言:javascript
复制
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

代码语言:javascript
复制
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

计算:

代码语言:javascript
复制
i = Search_ExportNamePointerTable("DllRegisterServer") = 7 - 1 = 6  // zero-based
offset = ExportOrdinalTable[6] = 4
SymbolRVA = ExportAddressTable[4] = ...
ordinal = OrdinalBase + offset = 5 + 4 = 9
票数 3
EN

Stack Overflow用户

发布于 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节是正确的。

。就提示而言,转储工具的输出不正确。导出表没有提示字段,只有导入表有提示字段。

事实上,序数基数不是在序数表中应用的,而是在检索地址表的索引时应用的!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5653316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档