summaryrefslogtreecommitdiff
path: root/view
diff options
context:
space:
mode:
authorMark Rowe <mark@vector35.com>2026-02-13 18:33:54 -0800
committerMark Rowe <mark@vector35.com>2026-02-13 19:42:13 -0800
commitc9dbb48365bf1a0c5c06daa2234e21e64d9bc2f7 (patch)
treedd476df611f5d74590d48afb869896670a8f560c /view
parente2feac85c58785640a2760f137a44c08ef953931 (diff)
[DSC] Correctly mark symbols as having local, global, or weak binding
Diffstat (limited to 'view')
-rw-r--r--view/sharedcache/api/python/generator.cpp18
-rw-r--r--view/sharedcache/api/python/sharedcache.py3
-rw-r--r--view/sharedcache/api/python/sharedcache_enums.py7
-rw-r--r--view/sharedcache/api/sharedcache.cpp3
-rw-r--r--view/sharedcache/api/sharedcacheapi.h1
-rw-r--r--view/sharedcache/api/sharedcachecore.h20
-rw-r--r--view/sharedcache/core/MachO.cpp24
-rw-r--r--view/sharedcache/core/MachO.h3
-rw-r--r--view/sharedcache/core/MachOProcessor.cpp2
-rw-r--r--view/sharedcache/core/SharedCache.cpp2
-rw-r--r--view/sharedcache/core/SharedCache.h5
-rw-r--r--view/sharedcache/core/ffi.cpp2
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;
}