Skip to content

[MachO] Display type information for more load command types #6719

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
860 changes: 860 additions & 0 deletions macho/types.cpp

Large diffs are not rendered by default.

1,454 changes: 1,454 additions & 0 deletions macho/types.h

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion view/kernelcache/api/kernelcacheapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include <binaryninjaapi.h>
#include "../core/MetadataSerializable.hpp"
#include "../api/view/macho/machoview.h"
#include "macho/types.h"
#include "kernelcachecore.h"

using namespace BinaryNinja;
Expand Down
1 change: 1 addition & 0 deletions view/kernelcache/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ file (GLOB_RECURSE COMMON_SOURCES CONFIGURE_DEPENDS
*.hpp
*.c
*.cpp
../../../macho/*
)

set(SOURCES ${COMMON_SOURCES})
Expand Down
540 changes: 3 additions & 537 deletions view/kernelcache/core/KCView.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion view/kernelcache/core/KernelCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include <binaryninjaapi.h>
#include "KCView.h"
#include "view/macho/machoview.h"
#include "macho/types.h"
#include "MetadataSerializable.hpp"
#include "../api/kernelcachecore.h"

Expand Down
2 changes: 1 addition & 1 deletion view/kernelcache/core/MetadataSerializable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"
#include "../api/kernelcachecore.h"
#include "view/macho/machoview.h"
#include "macho/types.h"

using namespace BinaryNinja;

Expand Down
2 changes: 1 addition & 1 deletion view/macho/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ if(NOT BN_INTERNAL_BUILD)
add_subdirectory(${PROJECT_SOURCE_DIR}/../.. ${PROJECT_BINARY_DIR}/api)
endif()

file(GLOB SOURCES *.cpp *.h ../../objectivec/*)
file(GLOB SOURCES *.cpp *.h ../../objectivec/* ../../macho/*)

if(DEMO)
add_library(view_macho STATIC ${SOURCES})
Expand Down
515 changes: 4 additions & 511 deletions view/macho/machoview.cpp

Large diffs are not rendered by default.

1,372 changes: 3 additions & 1,369 deletions view/macho/machoview.h

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion view/sharedcache/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ if((NOT BN_API_PATH) AND (NOT BN_INTERNAL_BUILD))
endif()
endif()

file(GLOB_RECURSE SOURCES *.cpp *.h ../../../objectivec/*)
file(GLOB_RECURSE SOURCES *.cpp *.h ../../../objectivec/* ../../../macho/*)

add_library(sharedcachecore OBJECT ${SOURCES})

Expand Down
3 changes: 1 addition & 2 deletions view/sharedcache/core/MachO.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

#include "VirtualMemory.h"

// TODO: Including this adds a bunch of binary ninja specific stuff :ugh:
#include "view/macho/machoview.h"
#include "macho/types.h"

struct CacheSymbol;

Expand Down
114 changes: 2 additions & 112 deletions view/sharedcache/core/MachOProcessor.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "MachOProcessor.h"
#include "SharedCache.h"
#include "macho/types.h"

using namespace BinaryNinja;

Expand Down Expand Up @@ -267,116 +268,5 @@ void SharedCacheMachOProcessor::ApplyHeaderDataVariables(SharedCacheMachOHeader&
// TODO: By using a binary reader we assume the sections have all been mapped.
// TODO: Maybe we should just use the virtual memory reader...
// TODO: We can define symbols and data variables even if there is no backing region FWIW
BinaryReader reader(m_view);
// TODO: Do we support non 64 bit header?
reader.Seek(header.textBase + sizeof(mach_header_64));

m_view->DefineDataVariable(header.textBase, Type::NamedType(m_view, QualifiedName("mach_header_64")));
m_view->DefineAutoSymbol(
new Symbol(DataSymbol, "__macho_header::" + header.identifierPrefix, header.textBase, LocalBinding));

auto applyLoadCommand = [&](uint64_t cmdAddr, const load_command& load) {
switch (load.cmd)
{
case LC_SEGMENT:
{
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("segment_command")));
reader.SeekRelative(5 * 8);
size_t numSections = reader.Read32();
reader.SeekRelative(4);
for (size_t j = 0; j < numSections; j++)
{
m_view->DefineDataVariable(reader.GetOffset(), Type::NamedType(m_view, QualifiedName("section")));
auto sectionSymName =
fmt::format("__macho_section::{}_[{}]", header.identifierPrefix, std::to_string(j));
auto sectionSym = new Symbol(DataSymbol, sectionSymName, reader.GetOffset(), LocalBinding);
m_view->DefineAutoSymbol(sectionSym);
reader.SeekRelative((8 * 8) + 4);
}
break;
}
case LC_SEGMENT_64:
{
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("segment_command_64")));
reader.SeekRelative(7 * 8);
size_t numSections = reader.Read32();
reader.SeekRelative(4);
for (size_t j = 0; j < numSections; j++)
{
m_view->DefineDataVariable(reader.GetOffset(), Type::NamedType(m_view, QualifiedName("section_64")));
auto sectionSymName =
fmt::format("__macho_section_64::{}_[{}]", header.identifierPrefix, std::to_string(j));
auto sectionSym = new Symbol(DataSymbol, sectionSymName, reader.GetOffset(), LocalBinding);
m_view->DefineAutoSymbol(sectionSym);
reader.SeekRelative(10 * 8);
}
break;
}
case LC_SYMTAB:
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("symtab")));
break;
case LC_DYSYMTAB:
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("dysymtab")));
break;
case LC_UUID:
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("uuid")));
break;
case LC_ID_DYLIB:
case LC_LOAD_DYLIB:
case LC_REEXPORT_DYLIB:
case LC_LOAD_WEAK_DYLIB:
case LC_LOAD_UPWARD_DYLIB:
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("dylib_command")));
if (load.cmdsize - 24 <= 150)
m_view->DefineDataVariable(
cmdAddr + 24, Type::ArrayType(Type::IntegerType(1, true), load.cmdsize - 24));
break;
case LC_CODE_SIGNATURE:
case LC_SEGMENT_SPLIT_INFO:
case LC_FUNCTION_STARTS:
case LC_DATA_IN_CODE:
case LC_DYLIB_CODE_SIGN_DRS:
case LC_DYLD_EXPORTS_TRIE:
case LC_DYLD_CHAINED_FIXUPS:
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("linkedit_data")));
break;
case LC_ENCRYPTION_INFO:
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("encryption_info")));
break;
case LC_VERSION_MIN_MACOSX:
case LC_VERSION_MIN_IPHONEOS:
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("version_min")));
break;
case LC_DYLD_INFO:
case LC_DYLD_INFO_ONLY:
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("dyld_info")));
break;
default:
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("load_command")));
break;
}
};

try
{
for (size_t i = 0; i < header.ident.ncmds; i++)
{
load_command load {};
uint64_t curOffset = reader.GetOffset();
load.cmd = reader.Read32();
load.cmdsize = reader.Read32();

applyLoadCommand(curOffset, load);
m_view->DefineAutoSymbol(new Symbol(DataSymbol,
"__macho_load_command::" + header.identifierPrefix + "_[" + std::to_string(i) + "]", curOffset,
LocalBinding));

uint64_t nextOffset = curOffset + load.cmdsize;
reader.Seek(nextOffset);
}
}
catch (ReadException&)
{
m_logger->LogError("Error when applying Mach-O header types at %llx", header.textBase);
}
MachO::ApplyHeaderTypes(m_view, m_logger, BinaryReader(m_view), header.identifierPrefix, header.textBase, header.ident.ncmds);
}
Loading