Skip to content

Commit ce0a586

Browse files
committed
[MachO] Share creation of types used in Mach-O headers between Mach-O View, shared cache, and kernel cache
1 parent 5ecf8d5 commit ce0a586

File tree

15 files changed

+2001
-2947
lines changed

15 files changed

+2001
-2947
lines changed

macho/types.cpp

Lines changed: 571 additions & 0 deletions
Large diffs are not rendered by default.

macho/types.h

Lines changed: 1408 additions & 0 deletions
Large diffs are not rendered by default.

view/kernelcache/api/kernelcacheapi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#include <binaryninjaapi.h>
44
#include "../core/MetadataSerializable.hpp"
5-
#include "../api/view/macho/machoview.h"
5+
#include "macho/types.h"
66
#include "kernelcachecore.h"
77

88
using namespace BinaryNinja;

view/kernelcache/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ file (GLOB_RECURSE COMMON_SOURCES CONFIGURE_DEPENDS
1414
*.hpp
1515
*.c
1616
*.cpp
17+
../../../macho/*
1718
)
1819

1920
set(SOURCES ${COMMON_SOURCES})

view/kernelcache/core/KCView.cpp

Lines changed: 3 additions & 537 deletions
Large diffs are not rendered by default.

view/kernelcache/core/KernelCache.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
#include <binaryninjaapi.h>
66
#include "KCView.h"
7-
#include "view/macho/machoview.h"
7+
#include "macho/types.h"
88
#include "MetadataSerializable.hpp"
99
#include "../api/kernelcachecore.h"
1010

view/kernelcache/core/MetadataSerializable.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
#include "rapidjson/stringbuffer.h"
4444
#include "rapidjson/prettywriter.h"
4545
#include "../api/kernelcachecore.h"
46-
#include "view/macho/machoview.h"
46+
#include "macho/types.h"
4747

4848
using namespace BinaryNinja;
4949

view/macho/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ if(NOT BN_INTERNAL_BUILD)
66
add_subdirectory(${PROJECT_SOURCE_DIR}/../.. ${PROJECT_BINARY_DIR}/api)
77
endif()
88

9-
file(GLOB SOURCES *.cpp *.h ../../objectivec/*)
9+
file(GLOB SOURCES *.cpp *.h ../../objectivec/* ../../macho/*)
1010

1111
if(DEMO)
1212
add_library(view_macho STATIC ${SOURCES})

view/macho/machoview.cpp

Lines changed: 4 additions & 511 deletions
Large diffs are not rendered by default.

view/macho/machoview.h

Lines changed: 3 additions & 1369 deletions
Large diffs are not rendered by default.

view/sharedcache/core/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ if((NOT BN_API_PATH) AND (NOT BN_INTERNAL_BUILD))
99
endif()
1010
endif()
1111

12-
file(GLOB_RECURSE SOURCES *.cpp *.h ../../../objectivec/*)
12+
file(GLOB_RECURSE SOURCES *.cpp *.h ../../../objectivec/* ../../../macho/*)
1313

1414
add_library(sharedcachecore OBJECT ${SOURCES})
1515

view/sharedcache/core/MachO.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
#include "VirtualMemory.h"
44

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

87
struct CacheSymbol;
98

view/sharedcache/core/MachOProcessor.cpp

Lines changed: 2 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "MachOProcessor.h"
22
#include "SharedCache.h"
3+
#include "macho/types.h"
34

45
using namespace BinaryNinja;
56

@@ -267,116 +268,5 @@ void SharedCacheMachOProcessor::ApplyHeaderDataVariables(SharedCacheMachOHeader&
267268
// TODO: By using a binary reader we assume the sections have all been mapped.
268269
// TODO: Maybe we should just use the virtual memory reader...
269270
// TODO: We can define symbols and data variables even if there is no backing region FWIW
270-
BinaryReader reader(m_view);
271-
// TODO: Do we support non 64 bit header?
272-
reader.Seek(header.textBase + sizeof(mach_header_64));
273-
274-
m_view->DefineDataVariable(header.textBase, Type::NamedType(m_view, QualifiedName("mach_header_64")));
275-
m_view->DefineAutoSymbol(
276-
new Symbol(DataSymbol, "__macho_header::" + header.identifierPrefix, header.textBase, LocalBinding));
277-
278-
auto applyLoadCommand = [&](uint64_t cmdAddr, const load_command& load) {
279-
switch (load.cmd)
280-
{
281-
case LC_SEGMENT:
282-
{
283-
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("segment_command")));
284-
reader.SeekRelative(5 * 8);
285-
size_t numSections = reader.Read32();
286-
reader.SeekRelative(4);
287-
for (size_t j = 0; j < numSections; j++)
288-
{
289-
m_view->DefineDataVariable(reader.GetOffset(), Type::NamedType(m_view, QualifiedName("section")));
290-
auto sectionSymName =
291-
fmt::format("__macho_section::{}_[{}]", header.identifierPrefix, std::to_string(j));
292-
auto sectionSym = new Symbol(DataSymbol, sectionSymName, reader.GetOffset(), LocalBinding);
293-
m_view->DefineAutoSymbol(sectionSym);
294-
reader.SeekRelative((8 * 8) + 4);
295-
}
296-
break;
297-
}
298-
case LC_SEGMENT_64:
299-
{
300-
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("segment_command_64")));
301-
reader.SeekRelative(7 * 8);
302-
size_t numSections = reader.Read32();
303-
reader.SeekRelative(4);
304-
for (size_t j = 0; j < numSections; j++)
305-
{
306-
m_view->DefineDataVariable(reader.GetOffset(), Type::NamedType(m_view, QualifiedName("section_64")));
307-
auto sectionSymName =
308-
fmt::format("__macho_section_64::{}_[{}]", header.identifierPrefix, std::to_string(j));
309-
auto sectionSym = new Symbol(DataSymbol, sectionSymName, reader.GetOffset(), LocalBinding);
310-
m_view->DefineAutoSymbol(sectionSym);
311-
reader.SeekRelative(10 * 8);
312-
}
313-
break;
314-
}
315-
case LC_SYMTAB:
316-
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("symtab")));
317-
break;
318-
case LC_DYSYMTAB:
319-
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("dysymtab")));
320-
break;
321-
case LC_UUID:
322-
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("uuid")));
323-
break;
324-
case LC_ID_DYLIB:
325-
case LC_LOAD_DYLIB:
326-
case LC_REEXPORT_DYLIB:
327-
case LC_LOAD_WEAK_DYLIB:
328-
case LC_LOAD_UPWARD_DYLIB:
329-
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("dylib_command")));
330-
if (load.cmdsize - 24 <= 150)
331-
m_view->DefineDataVariable(
332-
cmdAddr + 24, Type::ArrayType(Type::IntegerType(1, true), load.cmdsize - 24));
333-
break;
334-
case LC_CODE_SIGNATURE:
335-
case LC_SEGMENT_SPLIT_INFO:
336-
case LC_FUNCTION_STARTS:
337-
case LC_DATA_IN_CODE:
338-
case LC_DYLIB_CODE_SIGN_DRS:
339-
case LC_DYLD_EXPORTS_TRIE:
340-
case LC_DYLD_CHAINED_FIXUPS:
341-
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("linkedit_data")));
342-
break;
343-
case LC_ENCRYPTION_INFO:
344-
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("encryption_info")));
345-
break;
346-
case LC_VERSION_MIN_MACOSX:
347-
case LC_VERSION_MIN_IPHONEOS:
348-
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("version_min")));
349-
break;
350-
case LC_DYLD_INFO:
351-
case LC_DYLD_INFO_ONLY:
352-
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("dyld_info")));
353-
break;
354-
default:
355-
m_view->DefineDataVariable(cmdAddr, Type::NamedType(m_view, QualifiedName("load_command")));
356-
break;
357-
}
358-
};
359-
360-
try
361-
{
362-
for (size_t i = 0; i < header.ident.ncmds; i++)
363-
{
364-
load_command load {};
365-
uint64_t curOffset = reader.GetOffset();
366-
load.cmd = reader.Read32();
367-
load.cmdsize = reader.Read32();
368-
369-
applyLoadCommand(curOffset, load);
370-
m_view->DefineAutoSymbol(new Symbol(DataSymbol,
371-
"__macho_load_command::" + header.identifierPrefix + "_[" + std::to_string(i) + "]", curOffset,
372-
LocalBinding));
373-
374-
uint64_t nextOffset = curOffset + load.cmdsize;
375-
reader.Seek(nextOffset);
376-
}
377-
}
378-
catch (ReadException&)
379-
{
380-
m_logger->LogError("Error when applying Mach-O header types at %llx", header.textBase);
381-
}
271+
MachO::ApplyHeaderTypes(m_view, m_logger, BinaryReader(m_view), header.identifierPrefix, header.textBase, header.ident.ncmds);
382272
}

0 commit comments

Comments
 (0)