Skip to content
This repository has been archived by the owner on Nov 19, 2024. It is now read-only.

Commit

Permalink
Fix empty colocator for real vtables & update ABI
Browse files Browse the repository at this point in the history
  • Loading branch information
emesare committed Jan 15, 2024
1 parent caeb60c commit e53d786
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 15 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@
"fstream": "cpp",
"random": "cpp",
"scoped_allocator": "cpp",
"strstream": "cpp"
"strstream": "cpp",
"bitset": "cpp",
"typeindex": "cpp"
},
"dotnet.defaultSolution": "disable"
}
2 changes: 1 addition & 1 deletion binaryninja-api
Submodule binaryninja-api updated 189 files
2 changes: 1 addition & 1 deletion include/virtual_function_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class VirtualFunctionTable

VirtualFunctionTable(BinaryView* view, uint64_t address);
std::vector<VirtualFunction> GetVirtualFunctions();
CompleteObjectLocator GetCOLocator();
std::optional<CompleteObjectLocator> GetCOLocator();
Ref<Type> GetType();
Ref<Symbol> CreateSymbol();
std::string GetSymbolName();
Expand Down
11 changes: 6 additions & 5 deletions src/constructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ bool Constructor::IsValid()

std::string Constructor::GetName()
{
return GetRootVirtualFunctionTable()->GetCOLocator().GetTypeDescriptor().GetDemangledName();
return GetRootVirtualFunctionTable()->GetCOLocator()->GetTypeDescriptor().GetDemangledName();
}

std::optional<VirtualFunctionTable> Constructor::GetRootVirtualFunctionTable()
Expand Down Expand Up @@ -127,13 +127,13 @@ Ref<Type> Constructor::CreateObjectType()
}

VirtualFunctionTable currentVft = VirtualFunctionTable(m_view, sourceDataVar.address);
CompleteObjectLocator currentVftCOLocator = currentVft.GetCOLocator();
auto currentVftCOLocator = currentVft.GetCOLocator();

if (offset != 0)
if (offset != 0 && currentVftCOLocator.has_value())
{
objBuilder.AddMemberAtOffset(
Type::PointerType(m_view->GetAddressSize(), sourceDataVar.type),
"vtable_" + currentVftCOLocator.GetAssociatedClassName(), offset);
"vtable_" + currentVftCOLocator->GetAssociatedClassName(), offset);
}
else
{
Expand Down Expand Up @@ -169,7 +169,8 @@ Ref<Type> Constructor::CreateObjectType()
auto innerTy = innerConstructor.CreateObjectType();

innerStructures.emplace_back(BaseStructure(innerTy->GetNamedTypeReference(),
innerConstructor.GetRootVirtualFunctionTable()->GetCOLocator().m_offsetValue, innerTy->GetWidth()));
innerConstructor.GetRootVirtualFunctionTable()->GetCOLocator()->m_offsetValue,
innerTy->GetWidth()));
}
}
objBuilder.SetBaseStructures(innerStructures);
Expand Down
24 changes: 17 additions & 7 deletions src/virtual_function_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ std::vector<VirtualFunction> VirtualFunctionTable::GetVirtualFunctions()
if (segment->GetFlags() & (SegmentExecutable | SegmentDenyWrite))
{
LogInfo("Discovered function from vtable reference -> %x", vFuncAddr);
m_view->CreateUserFunction(m_view->GetDefaultPlatform(), vFuncAddr);
funcs.emplace_back(m_view->GetAnalysisFunctionsForAddress(vFuncAddr).front());
auto vFunc = m_view->CreateUserFunction(m_view->GetDefaultPlatform(), vFuncAddr);
funcs.emplace_back(vFunc);
}
else
{
Expand All @@ -54,9 +54,14 @@ std::vector<VirtualFunction> VirtualFunctionTable::GetVirtualFunctions()
return vFuncs;
}

CompleteObjectLocator VirtualFunctionTable::GetCOLocator()
std::optional<CompleteObjectLocator> VirtualFunctionTable::GetCOLocator()
{
std::vector<uint64_t> dataRefs = m_view->GetDataReferencesFrom(m_address - m_view->GetAddressSize());
if (dataRefs.empty())
{
LogError("Invalid COLocator for vtable %x", m_address);
return std::nullopt;
}
return CompleteObjectLocator(m_view, dataRefs.front());
}

Expand Down Expand Up @@ -100,15 +105,20 @@ Ref<Symbol> VirtualFunctionTable::CreateSymbol()
std::string VirtualFunctionTable::GetSymbolName()
{
auto coLocator = GetCOLocator();
std::string className = coLocator.GetClassName();
if (coLocator.IsSubObject())
return className + "::`vftable'" + "{for `" + coLocator.GetAssociatedClassName() + "'}";
if (!coLocator.has_value())
return std::to_string(m_address) + "::`vftable'";
std::string className = coLocator->GetClassName();
if (coLocator->IsSubObject())
return className + "::`vftable'" + "{for `" + coLocator->GetAssociatedClassName() + "'}";
return className + "::`vftable'";
}

// Example: Animal::VTable
// If subobject this will return the type name of the subobject type.
std::string VirtualFunctionTable::GetTypeName()
{
return GetCOLocator().GetAssociatedClassName() + "::VTable";
auto coLocator = GetCOLocator();
if (!coLocator.has_value())
return std::to_string(m_address) + "::`vftable'";
return coLocator->GetAssociatedClassName() + "::VTable";
}

0 comments on commit e53d786

Please sign in to comment.