diff options
| author | Mark Rowe <mark@vector35.com> | 2026-02-13 18:33:54 -0800 |
|---|---|---|
| committer | Mark Rowe <mark@vector35.com> | 2026-02-13 19:42:13 -0800 |
| commit | c9dbb48365bf1a0c5c06daa2234e21e64d9bc2f7 (patch) | |
| tree | dd476df611f5d74590d48afb869896670a8f560c /view | |
| parent | e2feac85c58785640a2760f137a44c08ef953931 (diff) | |
[DSC] Correctly mark symbols as having local, global, or weak binding
Diffstat (limited to 'view')
| -rw-r--r-- | view/sharedcache/api/python/generator.cpp | 18 | ||||
| -rw-r--r-- | view/sharedcache/api/python/sharedcache.py | 3 | ||||
| -rw-r--r-- | view/sharedcache/api/python/sharedcache_enums.py | 7 | ||||
| -rw-r--r-- | view/sharedcache/api/sharedcache.cpp | 3 | ||||
| -rw-r--r-- | view/sharedcache/api/sharedcacheapi.h | 1 | ||||
| -rw-r--r-- | view/sharedcache/api/sharedcachecore.h | 20 | ||||
| -rw-r--r-- | view/sharedcache/core/MachO.cpp | 24 | ||||
| -rw-r--r-- | view/sharedcache/core/MachO.h | 3 | ||||
| -rw-r--r-- | view/sharedcache/core/MachOProcessor.cpp | 2 | ||||
| -rw-r--r-- | view/sharedcache/core/SharedCache.cpp | 2 | ||||
| -rw-r--r-- | view/sharedcache/core/SharedCache.h | 5 | ||||
| -rw-r--r-- | view/sharedcache/core/ffi.cpp | 2 |
12 files changed, 70 insertions, 20 deletions
diff --git a/view/sharedcache/api/python/generator.cpp b/view/sharedcache/api/python/generator.cpp index 81463b51..062f2e27 100644 --- a/view/sharedcache/api/python/generator.cpp +++ b/view/sharedcache/api/python/generator.cpp @@ -331,7 +331,23 @@ int main(int argc, char* argv[]) continue; } - fprintf(out, "%sEnum = ctypes.c_int\n", name.c_str()); + const char* ctypesType = nullptr; + switch (i.second->GetWidth()) + { + case 1: + ctypesType = i.second->IsSigned() ? "ctypes.c_int8" : "ctypes.c_uint8"; + break; + case 2: + ctypesType = i.second->IsSigned() ? "ctypes.c_int16" : "ctypes.c_uint16"; + break; + case 4: + ctypesType = i.second->IsSigned() ? "ctypes.c_int32" : "ctypes.c_uint32"; + break; + default: + ctypesType = i.second->IsSigned() ? "ctypes.c_int64" : "ctypes.c_uint64"; + break; + } + fprintf(out, "%sEnum = %s\n", name.c_str(), ctypesType); fprintf(enums, "\n\nclass %s(enum.IntEnum):\n", name.c_str()); for (auto& j : i.second->GetEnumeration()->GetMembers()) diff --git a/view/sharedcache/api/python/sharedcache.py b/view/sharedcache/api/python/sharedcache.py index dff9bcc3..cac4050e 100644 --- a/view/sharedcache/api/python/sharedcache.py +++ b/view/sharedcache/api/python/sharedcache.py @@ -40,6 +40,7 @@ class CacheImage: @dataclasses.dataclass class CacheSymbol: symbol_type: sccore.SymbolTypeEnum + symbol_binding: sccore.SymbolBindingEnum address: int name: str @@ -94,6 +95,7 @@ def image_to_api(image: CacheImage) -> sccore.BNSharedCacheImage: def symbol_from_api(symbol: sccore.BNSharedCacheSymbol) -> CacheSymbol: return CacheSymbol( symbol_type=symbol.symbolType, + symbol_binding=symbol.symbolBinding, address=symbol.address, name=symbol.name ) @@ -101,6 +103,7 @@ def symbol_from_api(symbol: sccore.BNSharedCacheSymbol) -> CacheSymbol: def symbol_to_api(symbol: CacheSymbol) -> sccore.BNSharedCacheSymbol: return sccore.BNSharedCacheSymbol( symbolType=symbol.symbol_type, + symbolBinding=symbol.symbol_binding, address=symbol.address, _name=BNAllocString(symbol.name) ) diff --git a/view/sharedcache/api/python/sharedcache_enums.py b/view/sharedcache/api/python/sharedcache_enums.py index 9a98eba4..d772adda 100644 --- a/view/sharedcache/api/python/sharedcache_enums.py +++ b/view/sharedcache/api/python/sharedcache_enums.py @@ -26,6 +26,13 @@ class SharedCacheRegionType(enum.IntEnum): SharedCacheRegionTypeNonImage = 3 +class SymbolBinding(enum.IntEnum): + NoBinding = 0 + LocalBinding = 1 + GlobalBinding = 2 + WeakBinding = 3 + + class SymbolType(enum.IntEnum): FunctionSymbol = 0 ImportAddressSymbol = 1 diff --git a/view/sharedcache/api/sharedcache.cpp b/view/sharedcache/api/sharedcache.cpp index d1ec680d..d90f2799 100644 --- a/view/sharedcache/api/sharedcache.cpp +++ b/view/sharedcache/api/sharedcache.cpp @@ -107,6 +107,7 @@ CacheSymbol SymbolFromApi(BNSharedCacheSymbol apiSymbol) symbol.name = apiSymbol.name; symbol.address = apiSymbol.address; symbol.type = apiSymbol.symbolType; + symbol.binding = apiSymbol.symbolBinding; return symbol; } @@ -140,7 +141,7 @@ std::pair<std::string, Ref<Type>> CacheSymbol::DemangledName(BinaryView &view) c Ref<Symbol> CacheSymbol::GetBNSymbol(BinaryView &view) const { auto [shortName, _] = DemangledName(view); - return new Symbol(type, shortName, shortName, name, address, nullptr); + return new Symbol(type, shortName, shortName, name, address, binding); } std::string SharedCacheAPI::GetSymbolTypeAsString(const BNSymbolType &type) diff --git a/view/sharedcache/api/sharedcacheapi.h b/view/sharedcache/api/sharedcacheapi.h index 097c185b..070b10f6 100644 --- a/view/sharedcache/api/sharedcacheapi.h +++ b/view/sharedcache/api/sharedcacheapi.h @@ -286,6 +286,7 @@ namespace SharedCacheAPI { struct CacheSymbol { BNSymbolType type; + BNSymbolBinding binding = NoBinding; uint64_t address; std::string name; diff --git a/view/sharedcache/api/sharedcachecore.h b/view/sharedcache/api/sharedcachecore.h index 1324fe16..f8e9c48b 100644 --- a/view/sharedcache/api/sharedcachecore.h +++ b/view/sharedcache/api/sharedcachecore.h @@ -27,9 +27,10 @@ extern "C" { #endif - // binaryninjacore.h is not included so we must duplicate enum types here. + // binaryninjacore.h is not included so we must duplicate enum types here. + // TODO: Why isn't it?! #ifdef BN_TYPE_PARSER - typedef enum BNSegmentFlag + enum BNSegmentFlag : uint8_t { SegmentExecutable = 1, SegmentWritable = 2, @@ -38,9 +39,9 @@ extern "C" SegmentContainsCode = 0x10, SegmentDenyWrite = 0x20, SegmentDenyExecute = 0x40 - } BNSegmentFlag; + }; - typedef enum BNSymbolType + enum BNSymbolType : uint8_t { FunctionSymbol = 0, ImportAddressSymbol = 1, @@ -51,7 +52,15 @@ extern "C" LibraryFunctionSymbol = 6, SymbolicFunctionSymbol = 7, LocalLabelSymbol = 8, - } BNSymbolType; + }; + + enum BNSymbolBinding : uint8_t + { + NoBinding = 0, + LocalBinding = 1, + GlobalBinding = 2, + WeakBinding = 3, + }; #endif typedef struct BNBinaryView BNBinaryView; @@ -105,6 +114,7 @@ extern "C" typedef struct BNSharedCacheSymbol { BNSymbolType symbolType; + BNSymbolBinding symbolBinding; uint64_t address; char* name; } BNSharedCacheSymbol; diff --git a/view/sharedcache/core/MachO.cpp b/view/sharedcache/core/MachO.cpp index 29122dad..f3f9ec6c 100644 --- a/view/sharedcache/core/MachO.cpp +++ b/view/sharedcache/core/MachO.cpp @@ -457,7 +457,8 @@ std::optional<SharedCacheMachOHeader> SharedCacheMachOHeader::ParseHeaderForAddr return header; } -std::vector<CacheSymbol> SharedCacheMachOHeader::ReadSymbolTable(VirtualMemory& vm, const TableInfo &symbolInfo, const TableInfo &stringInfo) const +std::vector<CacheSymbol> SharedCacheMachOHeader::ReadSymbolTable(VirtualMemory& vm, const TableInfo &symbolInfo, const TableInfo &stringInfo, + BNSymbolBinding bindingOverride) const { std::vector<CacheSymbol> symbolList; // TODO: This assumes that 95% (or more) are going to be added. @@ -544,11 +545,15 @@ std::vector<CacheSymbol> SharedCacheMachOHeader::ReadSymbolTable(VirtualMemory& if ((nlist.n_desc & N_ARM_THUMB_DEF) == N_ARM_THUMB_DEF) symbolAddress++; - CacheSymbol symbol; - symbol.address = symbolAddress; - symbol.name = std::move(symbolName); - symbol.type = symbolType.value(); - symbolList.emplace_back(symbol); + BNSymbolBinding symbolBinding = GlobalBinding; + if (bindingOverride != NoBinding) + symbolBinding = bindingOverride; + else if (dysymPresent && dysymtab.nlocalsym && entryIndex >= dysymtab.ilocalsym && entryIndex < dysymtab.ilocalsym + dysymtab.nlocalsym) + symbolBinding = LocalBinding; + else if (nlist.n_desc & N_WEAK_DEF) + symbolBinding = WeakBinding; + + symbolList.emplace_back(symbolType.value(), symbolBinding, symbolAddress, std::move(symbolName)); } return symbolList; @@ -566,6 +571,9 @@ bool SharedCacheMachOHeader::AddExportTerminalSymbol( if (symbolName.empty() || symbolAddress == 0) return false; + // Export trie entries are exported by definition. + BNSymbolBinding symbolBinding = (symbolFlags & EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION) ? WeakBinding : GlobalBinding; + // Tries to get the symbol type based off the section containing it. auto sectionSymbolType = [&]() -> BNSymbolType { uint32_t sectionFlags = 0; @@ -593,10 +601,10 @@ bool SharedCacheMachOHeader::AddExportTerminalSymbol( { case EXPORT_SYMBOL_FLAGS_KIND_REGULAR: case EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL: - symbols.emplace_back(sectionSymbolType(), symbolAddress, symbolName); + symbols.emplace_back(sectionSymbolType(), symbolBinding, symbolAddress, symbolName); break; case EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE: - symbols.emplace_back(DataSymbol, symbolAddress, symbolName); + symbols.emplace_back(DataSymbol, symbolBinding, symbolAddress, symbolName); break; default: LogWarnF("Unhandled export symbol kind: {:#x}", symbolFlags & EXPORT_SYMBOL_FLAGS_KIND_MASK); diff --git a/view/sharedcache/core/MachO.h b/view/sharedcache/core/MachO.h index d3a720a9..950e5a46 100644 --- a/view/sharedcache/core/MachO.h +++ b/view/sharedcache/core/MachO.h @@ -70,7 +70,8 @@ struct SharedCacheMachOHeader static std::optional<SharedCacheMachOHeader> ParseHeaderForAddress( std::shared_ptr<VirtualMemory> vm, uint64_t address, const std::string& imagePath); - std::vector<CacheSymbol> ReadSymbolTable(VirtualMemory& vm, const TableInfo &symbolInfo, const TableInfo &stringInfo) const; + std::vector<CacheSymbol> ReadSymbolTable(VirtualMemory& vm, const TableInfo &symbolInfo, const TableInfo &stringInfo, + BNSymbolBinding bindingOverride = NoBinding) const; bool AddExportTerminalSymbol( std::vector<CacheSymbol>& symbols, const std::string& symbolName, const uint8_t* current, diff --git a/view/sharedcache/core/MachOProcessor.cpp b/view/sharedcache/core/MachOProcessor.cpp index 3d922268..8895a6f0 100644 --- a/view/sharedcache/core/MachOProcessor.cpp +++ b/view/sharedcache/core/MachOProcessor.cpp @@ -130,7 +130,7 @@ void SharedCacheMachOProcessor::ApplyUnmappedLocalSymbols(const SharedCache& cac TableInfo symbolInfo = {symbolTableStart, localSymbolsEntry.nlistCount}; TableInfo stringInfo = {localStringsAddr, localSymbolsInfo.stringsSize}; BulkSymbolModification bulkSymbolModification(m_view); - const auto symbols = header.ReadSymbolTable(*localSymbolsVM, symbolInfo, stringInfo); + const auto symbols = header.ReadSymbolTable(*localSymbolsVM, symbolInfo, stringInfo, LocalBinding); for (const auto &sym: symbols) { auto [symbol, symbolType] = sym.GetBNSymbolAndType(*m_view); diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index c084c692..09093ba5 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -21,7 +21,7 @@ std::pair<std::string, Ref<Type>> CacheSymbol::DemangledName(BinaryView &view) c std::pair<Ref<Symbol>, Ref<Type>> CacheSymbol::GetBNSymbolAndType(BinaryView& view) const { auto [shortName, demangledType] = DemangledName(view); - auto symbol = new Symbol(type, shortName, shortName, name, address, nullptr); + auto symbol = new Symbol(type, shortName, shortName, name, address, binding); return {symbol, demangledType}; } diff --git a/view/sharedcache/core/SharedCache.h b/view/sharedcache/core/SharedCache.h index 58f1f38c..010dff10 100644 --- a/view/sharedcache/core/SharedCache.h +++ b/view/sharedcache/core/SharedCache.h @@ -10,12 +10,13 @@ struct CacheSymbol { BNSymbolType type; + BNSymbolBinding binding = NoBinding; uint64_t address; std::string name; CacheSymbol() = default; - CacheSymbol(BNSymbolType type, uint64_t address, std::string name) : - type(type), address(address), name(std::move(name)) + CacheSymbol(BNSymbolType type, BNSymbolBinding binding, uint64_t address, std::string name) : + type(type), binding(binding), address(address), name(std::move(name)) {} ~CacheSymbol() = default; diff --git a/view/sharedcache/core/ffi.cpp b/view/sharedcache/core/ffi.cpp index 81c3acf7..7ad10f9b 100644 --- a/view/sharedcache/core/ffi.cpp +++ b/view/sharedcache/core/ffi.cpp @@ -91,6 +91,7 @@ BNSharedCacheSymbol SymbolToApi(const CacheSymbol& symbol) apiSymbol.name = BNAllocStringWithLength(symbol.name.data(), symbol.name.size()); apiSymbol.address = symbol.address; apiSymbol.symbolType = symbol.type; + apiSymbol.symbolBinding = symbol.binding; return apiSymbol; } @@ -100,6 +101,7 @@ CacheSymbol SymbolFromApi(const BNSharedCacheSymbol& apiSymbol) symbol.name = apiSymbol.name; symbol.address = apiSymbol.address; symbol.type = apiSymbol.symbolType; + symbol.binding = apiSymbol.symbolBinding; return symbol; } |
