Skip to content

Commit 0f26e92

Browse files
committed
[SharedCache] Apply demangled names and types more broadly
Fixes the case of stub functions being applied with mangled names.
1 parent a45466f commit 0f26e92

File tree

8 files changed

+50
-24
lines changed

8 files changed

+50
-24
lines changed

view/sharedcache/api/sharedcache.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,19 @@ std::string SharedCacheAPI::GetRegionTypeAsString(const BNSharedCacheRegionType
125125
}
126126
}
127127

128-
Ref<Symbol> CacheSymbol::GetBNSymbol(BinaryView &view) const
128+
std::pair<std::string, Ref<Type>> CacheSymbol::DemangledName(BinaryView &view) const
129129
{
130130
QualifiedName qname;
131-
Ref<Type> outType;
131+
Ref<Type> outType = nullptr;
132132
std::string shortName = name;
133133
if (DemangleGeneric(view.GetDefaultArchitecture(), name, outType, qname, &view, true))
134134
shortName = qname.GetString();
135+
return {shortName, outType};
136+
}
137+
138+
Ref<Symbol> CacheSymbol::GetBNSymbol(BinaryView &view) const
139+
{
140+
auto [shortName, _] = DemangledName(view);
135141
return new Symbol(type, shortName, shortName, name, address, nullptr);
136142
}
137143

view/sharedcache/api/sharedcacheapi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ namespace SharedCacheAPI {
288288
uint64_t address;
289289
std::string name;
290290

291+
std::pair<std::string, BinaryNinja::Ref<BinaryNinja::Type>> DemangledName(BinaryNinja::BinaryView &view) const;
291292
BinaryNinja::Ref<BinaryNinja::Symbol> GetBNSymbol(BinaryNinja::BinaryView& view) const;
292293
};
293294

view/sharedcache/core/MachOProcessor.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ void SharedCacheMachOProcessor::ApplyHeader(SharedCacheMachOHeader& header)
6262
// NOTE: This table is read relative to the link edit segment file base.
6363
const auto symbols = header.ReadSymbolTable(*m_view, *m_vm);
6464
for (const auto& sym : symbols)
65-
ApplySymbol(m_view, typeLib, sym.ToBNSymbol(*m_view));
65+
{
66+
auto [symbol, symbolType] = sym.GetBNSymbolAndType(*m_view);
67+
ApplySymbol(m_view, typeLib, symbol, symbolType);
68+
}
6669
}
6770

6871
// Apply symbols from export trie.
@@ -72,7 +75,10 @@ void SharedCacheMachOProcessor::ApplyHeader(SharedCacheMachOHeader& header)
7275
// TODO: Remove this and use the m_symbols in the cache?
7376
const auto exportSymbols = header.ReadExportSymbolTrie(*m_vm);
7477
for (const auto& sym : exportSymbols)
75-
ApplySymbol(m_view, typeLib, sym.ToBNSymbol(*m_view));
78+
{
79+
auto [symbol, symbolType] = sym.GetBNSymbolAndType(*m_view);
80+
ApplySymbol(m_view, typeLib, symbol, symbolType);
81+
}
7682
}
7783
m_view->EndBulkModifySymbols();
7884
}

view/sharedcache/core/SharedCache.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,21 @@ using namespace BinaryNinja;
1111
// The next id to use when calling Cache::AddEntry
1212
static CacheEntryId nextId = 1;
1313

14-
Ref<Symbol> CacheSymbol::ToBNSymbol(BinaryView& view) const
14+
std::pair<std::string, Ref<Type>> CacheSymbol::DemangledName(BinaryView &view) const
1515
{
1616
QualifiedName qname;
1717
Ref<Type> outType;
1818
std::string shortName = name;
1919
if (DemangleGeneric(view.GetDefaultArchitecture(), name, outType, qname, &view, true))
2020
shortName = qname.GetString();
21-
return new Symbol(type, shortName, shortName, name, address, nullptr);
21+
return { shortName, outType };
22+
}
23+
24+
std::pair<Ref<Symbol>, Ref<Type>> CacheSymbol::GetBNSymbolAndType(BinaryView& view) const
25+
{
26+
auto [shortName, demangledType] = DemangledName(view);
27+
auto symbol = new Symbol(type, shortName, shortName, name, address, nullptr);
28+
return {symbol, demangledType};
2229
}
2330

2431
std::vector<std::string> CacheImage::GetDependencies() const

view/sharedcache/core/SharedCache.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ struct CacheSymbol
3131

3232
CacheSymbol& operator=(CacheSymbol&& other) noexcept = default;
3333

34+
std::pair<std::string, BinaryNinja::Ref<BinaryNinja::Type>> DemangledName(BinaryNinja::BinaryView& view) const;
35+
3436
// NOTE: you should really only call this when adding the symbol to the view.
35-
BinaryNinja::Ref<BinaryNinja::Symbol> ToBNSymbol(BinaryNinja::BinaryView& view) const;
37+
std::pair<BinaryNinja::Ref<BinaryNinja::Symbol>, BinaryNinja::Ref<BinaryNinja::Type>> GetBNSymbolAndType(BinaryNinja::BinaryView& view) const;
3638
};
3739

3840
enum class CacheRegionType
@@ -151,11 +153,8 @@ class CacheEntry
151153
CacheEntry& operator=(CacheEntry&&) = default;
152154

153155
// Construct a cache entry from the file on disk.
154-
// TODO: Seperate this out a bit more.
155156
static std::optional<CacheEntry> FromFile(const std::string& filePath, const std::string& fileName, CacheEntryType type);
156157

157-
// TODO: From Project file?
158-
159158
WeakFileAccessor GetAccessor() const;
160159

161160
// Get the headers virtual address.

view/sharedcache/core/Utility.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,8 @@ uint64_t readValidULEB128(const uint8_t*& current, const uint8_t* end)
6565
return value;
6666
}
6767

68-
void ApplySymbol(Ref<BinaryView> view, Ref<TypeLibrary> typeLib, Ref<Symbol> symbol)
68+
void ApplySymbol(Ref<BinaryView> view, Ref<TypeLibrary> typeLib, Ref<Symbol> symbol, Ref<Type> type)
6969
{
70-
Ref<Function> func = nullptr;
7170
auto symbolAddress = symbol->GetAddress();
7271
auto symbolName = symbol->GetFullName();
7372

@@ -78,24 +77,26 @@ void ApplySymbol(Ref<BinaryView> view, Ref<TypeLibrary> typeLib, Ref<Symbol> sym
7877
// Define the symbol!
7978
view->DefineAutoSymbol(symbol);
8079

81-
// Try and pull a type to apply at the symbol location.
82-
Ref<Type> type = nullptr;
80+
// Try and pull a type from a type library to apply at the symbol location.
81+
// The type library type will take precedence over the passed in type.
82+
Ref<Type> selectedType = type;
8383
if (typeLib)
84-
type = view->ImportTypeLibraryObject(typeLib, {symbolName});
84+
selectedType = view->ImportTypeLibraryObject(typeLib, {symbolName});
8585

86+
Ref<Function> func = nullptr;
8687
if (symbol->GetType() == FunctionSymbol)
8788
{
8889
Ref<Platform> targetPlatform = view->GetDefaultPlatform();
8990
// Make sure to check for already added function from the function table.
9091
// Unless we have retrieved a type here we don't need to make a new function.
9192
func = view->GetAnalysisFunction(targetPlatform, symbolAddress);
92-
if (!func || type)
93-
func = view->AddFunctionForAnalysis(targetPlatform, symbolAddress, false, type);
93+
if (!func || selectedType)
94+
func = view->AddFunctionForAnalysis(targetPlatform, symbolAddress, false, selectedType);
9495
}
9596
else
9697
{
9798
// Other symbol types can just use this, they don't need to worry about linear sweep removing them.
98-
view->DefineAutoSymbolAndVariableOrFunction(view->GetDefaultPlatform(), symbol, type);
99+
view->DefineAutoSymbolAndVariableOrFunction(view->GetDefaultPlatform(), symbol, selectedType);
99100
}
100101

101102
if (func)

view/sharedcache/core/Utility.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ uint64_t readLEB128(const uint8_t*& current, const uint8_t* end);
3434
uint64_t readValidULEB128(const uint8_t*& current, const uint8_t* end);
3535

3636
void ApplySymbol(BinaryNinja::Ref<BinaryNinja::BinaryView> view, BinaryNinja::Ref<BinaryNinja::TypeLibrary> typeLib,
37-
BinaryNinja::Ref<BinaryNinja::Symbol> symbol);
37+
BinaryNinja::Ref<BinaryNinja::Symbol> symbol, BinaryNinja::Ref<BinaryNinja::Type> type = nullptr);
3838

3939
// Returns the "image name" for a given path.
4040
// /blah/foo/bar/libObjCThing.dylib -> libObjCThing.dylib

view/sharedcache/workflow/SharedCacheWorkflow.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,28 @@ void IdentifyStub(BinaryView& view, const SharedCacheController& controller, uin
8787
if (!symbol.has_value())
8888
return;
8989

90+
// Demangle if possible, the type pulled will be used, however type library will take precedence.
91+
auto [demangledName, demangledType] = symbol->DemangledName(view);
92+
auto rawName = STUB_PREFIX + symbol->name;
93+
auto shortName = STUB_PREFIX + demangledName;
94+
9095
// Try and retrieve a type for the stub function using type libraries.
9196
if (const auto targetFunc = view.GetAnalysisFunction(view.GetDefaultPlatform(), stubFuncAddr))
9297
{
9398
// NOTE: The type library name is expected to be the image name currently.
9499
// Try and pull the type from the associated type library (if there is one)
95-
Ref<Type> type = nullptr;
100+
Ref<Type> selectedType = demangledType;
96101
if (const auto image = controller.GetImageContaining(symbolAddr))
97102
if (auto typeLib = TypeLibraryFromName(view, image->name))
98-
type = view.ImportTypeLibraryObject(typeLib, {symbol->name});
103+
selectedType = view.ImportTypeLibraryObject(typeLib, {symbol->name});
99104

100-
if (type)
101-
targetFunc->SetAutoType(type);
105+
if (selectedType)
106+
targetFunc->SetAutoType(selectedType);
102107
}
103108

104109
// Define the new symbol!
105-
view.DefineAutoSymbol(new Symbol(symbol->type, STUB_PREFIX + symbol->name, stubFuncAddr));
110+
auto bnSymbol = new Symbol(symbol->type, shortName, shortName, rawName, stubFuncAddr, nullptr);
111+
view.DefineAutoSymbol(bnSymbol);
106112
}
107113

108114
void AnalyzeStubFunction(Ref<Function> func, Ref<MediumLevelILFunction> mlil, SharedCacheController& controller, bool loadImage)

0 commit comments

Comments
 (0)