binaryninja-api icon indicating copy to clipboard operation
binaryninja-api copied to clipboard

`TypeMapping.get()` method fails to retrieve system types when the type name contains `::`

Open kiddo-pwn opened this issue 8 months ago • 8 comments

Version and Platform (required):

  • Binary Ninja Version: 5.1.7512-test
  • Edition: Ultimate
  • OS: MacOS
  • OS Version:15.4.1
  • CPU Architecture: M4 Max

Bug Description: TypeMapping.get() method fails to retrieve system types when the type name contains :: (double colons), while direct dictionary access works correctly. User-defined types with :: in their names can be retrieved normally with get().

Steps To Reproduce:

  1. Open any binary with C++ symbols that creates types with namespace qualifiers
  2. Access the Python console
  3. Verify type exists: type bv.types to search for example std::string exists
  4. Try to get the type: bv.types.get('std::string') returns None
  5. With non-namespaced type works correctly

Expected Behavior: bv.types.get('std::string') should return the same result as bv.types['std::string'] for system types containing ::.

Screenshots/Video Recording:

>>> bv.types
<TypeMapping 132 symbols: {... , 'std::string': <type: immutable:StructureTypeClass 'class std::string'>, ...>
>>> bv.types.get("std::string")
>>> bv.types['std::string']
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Applications/Binary Ninja.app/Contents/MacOS/plugins/../../Resources/python/binaryninja/binaryview.py", line 2062, in __getitem__
    raise KeyError(key)
KeyError: 'std::string'

kiddo-pwn avatar Jun 01 '25 13:06 kiddo-pwn

As a temporary workaround, I used below script:

def search_types(name: str):
    for t in bv.types:
        if t[0] == name:
            return t[1]
    return None

kiddo-pwn avatar Jun 01 '25 13:06 kiddo-pwn

Does it fail if you pass the string with backticks around it?

https://docs.binary.ninja/guide/types/type.html?h=escape#special-characters

psifertex avatar Jun 01 '25 14:06 psifertex

In my case, yes.

>>> search_types("std::string")
<type: immutable:StructureTypeClass 'class std::string'>
>>> bv.types.get("std::string")
>>> bv.types.get("`std::string`")
>>> bv.types["std::string"]
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Applications/Binary Ninja.app/Contents/MacOS/plugins/../../Resources/python/binaryninja/binaryview.py", line 2062, in __getitem__
    raise KeyError(key)
KeyError: 'std::string'
>>> bv.types["`std::string`"]
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Applications/Binary Ninja.app/Contents/MacOS/plugins/../../Resources/python/binaryninja/binaryview.py", line 2062, in __getitem__
    raise KeyError(key)
KeyError: '`std::string`'

kiddo-pwn avatar Jun 01 '25 14:06 kiddo-pwn

this might be silly but try "class std::string"?

Ninja3047 avatar Jun 01 '25 14:06 Ninja3047

Good idea but it also failed in my side ;)

https://api.binary.ninja/_modules/binaryninja/binaryview.html#TypeMapping

After digging into this, I discovered that BinaryView also fails to retrieve system types containing ::.

>>> bv.types.get("class std::string")
>>> bv.types.get("class `std::string`")
>>> bv.get_type_by_name("std::string")
>>> bv.get_type_by_name("`std::string`")

kiddo-pwn avatar Jun 01 '25 14:06 kiddo-pwn

it might be only searching for the mangled form of the name if I manually make a std::string type it works as expected

Ninja3047 avatar Jun 01 '25 15:06 Ninja3047

Aha, this could be a mangling issue.

The current implementation creates an inconsistency: while I can obtain demangled names through direct references (like search_types) or by browsing bv.types, the get() method fails to retrieve the same types:

>>> bv.types
<TypeMapping 132 symbols: {..., 'std::string': <type: immutable:StructureTypeClass 'class std::string'>, ...}>
>>> bv.types.get("std::string")  # Returns None

I think this inconsistency makes the API less intuitive for users - types are visible but not retrievable through the standard methods. Would there be room for improvement in the type retrieval mechanism?

kiddo-pwn avatar Jun 01 '25 16:06 kiddo-pwn

This is an issue with our QualifiedName API. The demangler can produce names with multiple sections where the :: is actually a joining token and not part of the name proper. We should update these APIs to also support looking up qualified names with multiple parts (or just bite the bullet and remove that abstraction entirely). CC Vector35/binaryninja#422

>>> bv.types["std::string"]
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/glennsmith/Desktop/Binjas/Binary Ninja Dev.app/Contents/MacOS/plugins/../../Resources/python/binaryninja/binaryview.py", line 2062, in __getitem__
    raise KeyError(key)
KeyError: 'std::string'
>>> bv.types[["std", "string"]]
<type: immutable:StructureTypeClass 'class std::string'>

CouleeApps avatar Jun 02 '25 20:06 CouleeApps