Skip to content

Cutter assumes an OrdinalBase of 1, even though it should be 2 #3568

@SemsYapar

Description

@SemsYapar

Environment information

  • Operating System: Windows 11
  • Cutter version: 2.4.1-HEAD-a5f88d1
  • Rizin version: rizin 0.8.1 @ windows-x86-64 commit: c009cb739ca4fd289e634c2bea432d1e7bcd3676
  • Obtained from:
    • Built from source
    • Downloaded release from Cutter website or GitHub
    • Distribution repository
  • File format: Windows PE

Bug Description
When resolving ordinals in the Import Table, Cutter seems to assume a hardcoded OrdinalBase of 1, even though the actual OrdinalBase is 2 in the specific DLL (OLEAUT32.dll) I am analyzing.

To Reproduce
Inspect the Import Table of a program that imports functions from OLEAUT32.dll by ordinal (where functions are stored by their ordinal numbers instead of names).

Example Analysis:
In the .idata section at address 0x006986d4, the value is .dword 0x8000008d.

The raw ordinal value is 0x8d (141).

In this specific version of OLEAUT32.dll, the OrdinalBase is 0x2.

Therefore, the actual OrdinalIndex should be: 0x8d - 0x2 = 0x8b (139).

If we look up the key corresponding to OrdinalIndex 0x8b in the OrdinalNameTable of OLEAUT32.dll, we find it points to the 116th entry. Checking the ExportNameTable[116] reveals the function name: "VarAdd".

Verification with Binary Ninja:
To verify my manual calculation, I checked the same address in Binary Ninja, which correctly identifies the function:
006986d4 HRESULT (__stdcall* const OLEAUT32:VarAdd)(...) = VarAdd

Cutter's Incorrect Result:
However, Cutter interprets this address as:
;-- VarAnd:

Root Cause Analysis:
Cutter appears to be incorrectly assuming an OrdinalBase of 1. Let's test this hypothesis:

If OrdinalBase is assumed to be 1: 0x8d - 0x1 = 0x8c (140).

The key for 0x8c in the OrdinalNameTable points to index 117.

ExportNameTable[117] in this DLL is "VarAnd".

This confirms that Cutter is incorrectly resolving the import because it fails to respect the actual OrdinalBase defined in the DLL's Export Directory.

Screenshots
BinaryNinja ss:
Image

Cutter ss:
Image

Another example comparing Binary Ninja and Cutter within the disassembler view:
Cutter:
Image

BinaryNinja:

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    rizinNeeds changes into rizin codebase.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions