summaryrefslogtreecommitdiff
path: root/view
diff options
context:
space:
mode:
authorkat <kat@vector35.com>2024-06-27 12:45:20 -0400
committerkat <kat@vector35.com>2024-06-27 12:45:20 -0400
commitde5fdb36657a8a2ac500e4d924870c052c2941f7 (patch)
tree43c14db7a2a8ab8603cb5e61a993d81f4021a275 /view
parent015bb4fa79d01a1e2d4887cba96d150c7e1dd3bb (diff)
Add iOS Platforms. Add Mach-O Typelib support
Diffstat (limited to 'view')
-rw-r--r--view/macho/machoview.cpp82
-rw-r--r--view/macho/machoview.h2
2 files changed, 71 insertions, 13 deletions
diff --git a/view/macho/machoview.cpp b/view/macho/machoview.cpp
index 257f57a6..ef5b1c3b 100644
--- a/view/macho/machoview.cpp
+++ b/view/macho/machoview.cpp
@@ -138,9 +138,7 @@ static string BuildToolVersionToString(uint32_t version)
uint32_t update = version & 0xff;
stringstream ss;
- ss << major << "." << minor;
- if (update)
- ss << "." << update;
+ ss << major << "." << minor << "." << update;
return ss.str();
}
@@ -802,11 +800,14 @@ MachOHeader MachoView::HeaderForAddress(BinaryView* data, uint64_t address, bool
case LC_LOAD_DYLIB:
{
uint32_t offset = reader.Read32();
+ reader.Read32(); // timestamp
+ uint32_t currentVersion = reader.Read32();
if (offset < nextOffset)
{
reader.Seek(curOffset + offset);
string libname = reader.ReadCString();
- header.dylibs.push_back(libname);
+ auto version = BuildToolVersionToString(currentVersion);
+ header.dylibs.push_back({libname, version});
}
}
break;
@@ -1926,17 +1927,19 @@ bool MachoView::InitializeHeader(MachOHeader& header, bool isMainHeader, uint64_
{
vector<Ref<Metadata>> libraries;
vector<Ref<Metadata>> libraryFound;
- for (auto& libName : header.dylibs)
+ for (auto& [libName, libVersion] : header.dylibs)
{
if (!GetExternalLibrary(libName))
{
AddExternalLibrary(libName, {}, true);
}
libraries.push_back(new Metadata(string(libName)));
- Ref<TypeLibrary> typeLib = GetTypeLibrary(libName);
+ // Compose exact name with {install_name}.{platform}.{version}
+ std::string libNameExact = fmt::format("{}.{}.{}", libName, GetDefaultPlatform()->GetName(), libVersion);
+ Ref<TypeLibrary> typeLib = GetTypeLibrary(libNameExact);
if (!typeLib)
{
- vector<Ref<TypeLibrary>> typeLibs = platform->GetTypeLibrariesByName(libName);
+ vector<Ref<TypeLibrary>> typeLibs = GetDefaultPlatform()->GetTypeLibrariesByName(libNameExact);
if (typeLibs.size())
{
typeLib = typeLibs[0];
@@ -1946,6 +1949,22 @@ bool MachoView::InitializeHeader(MachOHeader& header, bool isMainHeader, uint64_
libName.c_str(), typeLib->GetName().c_str(), typeLib->GetGuid().c_str());
}
}
+ if (!typeLib)
+ {
+ typeLib = GetTypeLibrary(libName);
+ if (!typeLib)
+ {
+ vector<Ref<TypeLibrary>> typeLibs = GetDefaultPlatform()->GetTypeLibrariesByName(libName);
+ if (typeLibs.size())
+ {
+ typeLib = typeLibs[0];
+ AddTypeLibrary(typeLib);
+
+ m_logger->LogDebug("mach-o: adding type library for '%s': %s (%s)",
+ libName.c_str(), typeLib->GetName().c_str(), typeLib->GetGuid().c_str());
+ }
+ }
+ }
if (typeLib)
libraryFound.push_back(new Metadata(typeLib->GetName()));
@@ -2344,8 +2363,6 @@ bool MachoView::InitializeHeader(MachOHeader& header, bool isMainHeader, uint64_
Ref<Symbol> MachoView::DefineMachoSymbol(
BNSymbolType type, const string& name, uint64_t addr, BNSymbolBinding binding, bool deferred)
{
- Ref<Type> symbolTypeRef;
-
// If name is empty, symbol is not valid
if (name.size() == 0)
return nullptr;
@@ -2375,17 +2392,19 @@ Ref<Symbol> MachoView::DefineMachoSymbol(
return nullptr;
}
+ Ref<Type> symbolTypeRef;
+
if ((type == ExternalSymbol) || (type == ImportAddressSymbol) || (type == ImportedDataSymbol))
{
QualifiedName n(name);
- // TODO
- Ref<TypeLibrary> appliedLib = nullptr;
+ Ref<TypeLibrary> appliedLib;
symbolTypeRef = ImportTypeLibraryObject(appliedLib, n);
if (symbolTypeRef)
{
m_logger->LogDebug("mach-o: type Library '%s' found hit for '%s'", appliedLib->GetName().c_str(), name.c_str());
RecordImportedObjectLibrary(GetDefaultPlatform(), addr, appliedLib, n);
}
+
}
auto process = [=]() {
@@ -3785,11 +3804,50 @@ uint64_t MachoViewType::ParseHeaders(BinaryView* data, uint64_t imageOffset, mac
errorMsg = "invalid file class";
return 0;
}
+ uint64_t loadCommandStart = reader.GetOffset();
+
+ uint32_t cmd;
+ uint32_t cmdsize;
+ MachoPlatform machoPlat = MachoPlatform::MACHO_PLATFORM_MACOS; // Default to macOS.
+ // Quickly determine the OS from commands.
+ for (uint32_t i = 0; i < ident.ncmds; i++)
+ {
+ cmd = reader.Read32();
+ cmdsize = reader.Read32();
+ if (cmd == LC_BUILD_VERSION)
+ {
+ machoPlat = MachoPlatform(reader.Read32());
+ break;
+ }
+ else if (cmd == LC_VERSION_MIN_MACOSX)
+ {
+ machoPlat = MachoPlatform(1);
+ break;
+ }
+ else if (cmd == LC_VERSION_MIN_IPHONEOS)
+ {
+ machoPlat = MachoPlatform(2);
+ break;
+ }
+ else if (cmd == _LC_VERSION_MIN_TVOS)
+ {
+ machoPlat = MachoPlatform(3);
+ break;
+ }
+ else if (cmd == LC_VERSION_MIN_WATCHOS)
+ {
+ machoPlat = MachoPlatform(4);
+ break;
+ }
+
+ reader.SeekRelative(cmdsize - 8);
+ }
map<string, Ref<Metadata>> metadataMap = {
{"cputype", new Metadata((uint64_t) ident.cputype)},
{"cpusubtype", new Metadata((uint64_t) ident.cpusubtype)},
{"flags", new Metadata((uint64_t) ident.flags)},
+ {"machoplatform", new Metadata((uint64_t) machoPlat)},
};
Ref<Metadata> metadata = new Metadata(metadataMap);
@@ -3810,7 +3868,7 @@ uint64_t MachoViewType::ParseHeaders(BinaryView* data, uint64_t imageOffset, mac
*arch = g_machoViewType->GetArchitecture(ident.cputype, endianness);
}
- return reader.GetOffset();
+ return loadCommandStart;
}
diff --git a/view/macho/machoview.h b/view/macho/machoview.h
index 4bf37ef0..6a5e80ae 100644
--- a/view/macho/machoview.h
+++ b/view/macho/machoview.h
@@ -1285,7 +1285,7 @@ namespace BinaryNinja
std::vector<section_64> symbolStubSections;
std::vector<section_64> symbolPointerSections;
- std::vector<std::string> dylibs;
+ std::vector<std::pair<std::string, std::string>> dylibs;
build_version_command buildVersion;
std::vector<build_tool_version> buildToolVersions;