summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--view/macho/machoview.cpp7
-rw-r--r--view/macho/machoview.h129
-rw-r--r--view/sharedcache/CMakeLists.txt2
-rw-r--r--view/sharedcache/api/python/sharedcache.py13
-rw-r--r--view/sharedcache/api/python/sharedcache_enums.py6
-rw-r--r--view/sharedcache/api/sharedcache.cpp2
-rw-r--r--view/sharedcache/api/sharedcacheapi.h2
-rw-r--r--view/sharedcache/api/sharedcachecore.h8
-rw-r--r--view/sharedcache/core/SharedCache.cpp26
-rw-r--r--view/sharedcache/core/SharedCache.h2
10 files changed, 163 insertions, 34 deletions
diff --git a/view/macho/machoview.cpp b/view/macho/machoview.cpp
index 9ee393e8..ec0ea4d5 100644
--- a/view/macho/machoview.cpp
+++ b/view/macho/machoview.cpp
@@ -14,13 +14,6 @@
#include "lowlevelilinstruction.h"
#include "rapidjsonwrapper.h"
-enum {
- N_STAB = 0xe0,
- N_PEXT = 0x10,
- N_TYPE = 0x0e,
- N_EXT = 0x01
-};
-
using namespace BinaryNinja;
using namespace std;
diff --git a/view/macho/machoview.h b/view/macho/machoview.h
index 6a5e80ae..74508559 100644
--- a/view/macho/machoview.h
+++ b/view/macho/machoview.h
@@ -268,14 +268,129 @@ typedef int vm_prot_t;
#define SEG_UNIXSTACK "__UNIXSTACK"
#define SEG_IMPORT "__IMPORT"
-//Symbol Types (N_TYPE)
-#define N_UNDF 0x0
-#define N_ABS 0x2
-#define N_SECT 0xe
-#define N_PBUD 0xc
-#define N_INDR 0xa
+/*
+ * Symbols with a index into the string table of zero (n_un.n_strx == 0) are
+ * defined to have a null, "", name. Therefore all string indexes to non null
+ * names must not have a zero string index. This is bit historical information
+ * that has never been well documented.
+ */
+
+/*
+ * The n_type field really contains four fields:
+ * unsigned char N_STAB:3,
+ * N_PEXT:1,
+ * N_TYPE:3,
+ * N_EXT:1;
+ * which are used via the following masks.
+ */
+#define N_STAB 0xe0 /* if any of these bits set, a symbolic debugging entry */
+#define N_PEXT 0x10 /* private external symbol bit */
+#define N_TYPE 0x0e /* mask for the type bits */
+#define N_EXT 0x01 /* external symbol bit, set for external symbols */
+
+/*
+ * Only symbolic debugging entries have some of the N_STAB bits set and if any
+ * of these bits are set then it is a symbolic debugging entry (a stab). In
+ * which case then the values of the n_type field (the entire field) are given
+ * in <mach-o/stab.h>
+ */
+
+/*
+ * Values for N_TYPE bits of the n_type field.
+ */
+#define N_UNDF 0x0 /* undefined, n_sect == NO_SECT */
+#define N_ABS 0x2 /* absolute, n_sect == NO_SECT */
+#define N_SECT 0xe /* defined in section number n_sect */
+#define N_PBUD 0xc /* prebound undefined (defined in a dylib) */
+#define N_INDR 0xa /* indirect */
-#define N_ARM_THUMB_DEF 0x0008
+/*
+ * If the type is N_INDR then the symbol is defined to be the same as another
+ * symbol. In this case the n_value field is an index into the string table
+ * of the other symbol's name. When the other symbol is defined then they both
+ * take on the defined type and value.
+ */
+
+/*
+ * If the type is N_SECT then the n_sect field contains an ordinal of the
+ * section the symbol is defined in. The sections are numbered from 1 and
+ * refer to sections in order they appear in the load commands for the file
+ * they are in. This means the same ordinal may very well refer to different
+ * sections in different files.
+ *
+ * The n_value field for all symbol table entries (including N_STAB's) gets
+ * updated by the link editor based on the value of it's n_sect field and where
+ * the section n_sect references gets relocated. If the value of the n_sect
+ * field is NO_SECT then it's n_value field is not changed by the link editor.
+ */
+#define NO_SECT 0 /* symbol is not in any section */
+#define MAX_SECT 255 /* 1 thru 255 inclusive */
+
+/*
+ * The bit 0x0020 of the n_desc field is used for two non-overlapping purposes
+ * and has two different symbolic names, N_NO_DEAD_STRIP and N_DESC_DISCARDED.
+ */
+
+/*
+ * The N_NO_DEAD_STRIP bit of the n_desc field only ever appears in a
+ * relocatable .o file (MH_OBJECT filetype). And is used to indicate to the
+ * static link editor it is never to dead strip the symbol.
+ */
+#define N_NO_DEAD_STRIP 0x0020 /* symbol is not to be dead stripped */
+
+/*
+ * The N_DESC_DISCARDED bit of the n_desc field never appears in linked image.
+ * But is used in very rare cases by the dynamic link editor to mark an in
+ * memory symbol as discared and longer used for linking.
+ */
+#define N_DESC_DISCARDED 0x0020 /* symbol is discarded */
+
+/*
+ * The N_WEAK_REF bit of the n_desc field indicates to the dynamic linker that
+ * the undefined symbol is allowed to be missing and is to have the address of
+ * zero when missing.
+ */
+#define N_WEAK_REF 0x0040 /* symbol is weak referenced */
+
+/*
+ * The N_WEAK_DEF bit of the n_desc field indicates to the static and dynamic
+ * linkers that the symbol definition is weak, allowing a non-weak symbol to
+ * also be used which causes the weak definition to be discared. Currently this
+ * is only supported for symbols in coalesed sections.
+ */
+#define N_WEAK_DEF 0x0080 /* coalesed symbol is a weak definition */
+
+/*
+ * The N_REF_TO_WEAK bit of the n_desc field indicates to the dynamic linker
+ * that the undefined symbol should be resolved using flat namespace searching.
+ */
+#define N_REF_TO_WEAK 0x0080 /* reference to a weak symbol */
+
+/*
+ * The N_ARM_THUMB_DEF bit of the n_desc field indicates that the symbol is
+ * a defintion of a Thumb function.
+ */
+#define N_ARM_THUMB_DEF 0x0008 /* symbol is a Thumb function (ARM) */
+
+/*
+ * The N_SYMBOL_RESOLVER bit of the n_desc field indicates that the
+ * that the function is actually a resolver function and should
+ * be called to get the address of the real function to use.
+ * This bit is only available in .o files (MH_OBJECT filetype)
+ */
+#define N_SYMBOL_RESOLVER 0x0100
+
+/*
+ * The N_ALT_ENTRY bit of the n_desc field indicates that the
+ * symbol is pinned to the previous content.
+ */
+#define N_ALT_ENTRY 0x0200
+
+/*
+ * The N_COLD_FUNC bit of the n_desc field indicates that the symbol is used
+ * infrequently and the linker should order it towards the end of the section.
+ */
+#define N_COLD_FUNC 0x0400
/*
* An indirect symbol table entry is simply a 32bit index into the symbol table
diff --git a/view/sharedcache/CMakeLists.txt b/view/sharedcache/CMakeLists.txt
index 07c58514..8620975c 100644
--- a/view/sharedcache/CMakeLists.txt
+++ b/view/sharedcache/CMakeLists.txt
@@ -33,7 +33,7 @@ endif()
set(HARD_FAIL_MODE OFF CACHE BOOL "Enable hard fail mode")
set(SLIDEINFO_DEBUG_TAGS OFF CACHE BOOL "Enable debug tags in slideinfo")
set(VIEW_NAME "DSCView" CACHE STRING "Name of the view")
-set(METADATA_VERSION 4 CACHE STRING "Version of the metadata")
+set(METADATA_VERSION 5 CACHE STRING "Version of the metadata")
add_subdirectory(core)
add_subdirectory(api)
diff --git a/view/sharedcache/api/python/sharedcache.py b/view/sharedcache/api/python/sharedcache.py
index e0e18bde..e3ccbb9b 100644
--- a/view/sharedcache/api/python/sharedcache.py
+++ b/view/sharedcache/api/python/sharedcache.py
@@ -52,14 +52,21 @@ class DSCBackingCacheMapping:
@dataclasses.dataclass
class DSCBackingCache:
path: str
- isPrimary: bool
+ cacheType: BackingCacheType
mappings: list[DSCBackingCacheMapping]
def __str__(self):
return repr(self)
def __repr__(self):
- return f"<DSCBackingCache {self.path} {'Primary' if self.isPrimary else 'Secondary'} | {len(self.mappings)} mappings>"
+ match self.cacheType:
+ case BackingCacheType.BackingCacheTypePrimary:
+ cacheTypeStr = 'Primary'
+ case BackingCacheType.BackingCacheTypeSecondary:
+ cacheTypeStr = 'Secondary'
+ case BackingCacheType.BackingCacheTypeSymbols:
+ cacheTypeStr = 'Symbols'
+ return f"<DSCBackingCache {self.path} {cacheTypeStr} | {len(self.mappings)} mappings>"
@dataclasses.dataclass
@@ -142,7 +149,7 @@ class SharedCache:
mappings.append(mapping)
result.append(DSCBackingCache(
value[i].path,
- value[i].isPrimary,
+ value[i].cacheType,
mappings
))
diff --git a/view/sharedcache/api/python/sharedcache_enums.py b/view/sharedcache/api/python/sharedcache_enums.py
index 34668424..ea86b5c6 100644
--- a/view/sharedcache/api/python/sharedcache_enums.py
+++ b/view/sharedcache/api/python/sharedcache_enums.py
@@ -1,6 +1,12 @@
import enum
+class BackingCacheType(enum.IntEnum):
+ BackingCacheTypePrimary = 0
+ BackingCacheTypeSecondary = 1
+ BackingCacheTypeSymbols = 2
+
+
class DSCViewLoadProgress(enum.IntEnum):
LoadProgressNotStarted = 0
LoadProgressLoadingCaches = 1
diff --git a/view/sharedcache/api/sharedcache.cpp b/view/sharedcache/api/sharedcache.cpp
index a0c4e961..d9838057 100644
--- a/view/sharedcache/api/sharedcache.cpp
+++ b/view/sharedcache/api/sharedcache.cpp
@@ -102,7 +102,7 @@ namespace SharedCacheAPI {
{
BackingCache cache;
cache.path = value[i].path;
- cache.isPrimary = value[i].isPrimary;
+ cache.cacheType = value[i].cacheType;
for (size_t j = 0; j < value[i].mappingCount; j++)
{
BackingCacheMapping mapping;
diff --git a/view/sharedcache/api/sharedcacheapi.h b/view/sharedcache/api/sharedcacheapi.h
index 712cc98e..af82bb62 100644
--- a/view/sharedcache/api/sharedcacheapi.h
+++ b/view/sharedcache/api/sharedcacheapi.h
@@ -105,7 +105,7 @@ namespace SharedCacheAPI {
struct BackingCache {
std::string path;
- bool isPrimary;
+ BNBackingCacheType cacheType;
std::vector<BackingCacheMapping> mappings;
};
diff --git a/view/sharedcache/api/sharedcachecore.h b/view/sharedcache/api/sharedcachecore.h
index c2e1c7bd..54899919 100644
--- a/view/sharedcache/api/sharedcachecore.h
+++ b/view/sharedcache/api/sharedcachecore.h
@@ -64,6 +64,12 @@ extern "C"
LoadProgressFinished,
} BNDSCViewLoadProgress;
+ typedef enum BNBackingCacheType {
+ BackingCacheTypePrimary,
+ BackingCacheTypeSecondary,
+ BackingCacheTypeSymbols,
+ } BNBackingCacheType;
+
typedef struct BNBinaryView BNBinaryView;
typedef struct BNSharedCache BNSharedCache;
typedef struct BNStringRef BNStringRef;
@@ -98,7 +104,7 @@ extern "C"
typedef struct BNDSCBackingCache {
char* path;
- bool isPrimary;
+ BNBackingCacheType cacheType;
BNDSCBackingCacheMapping* mappings;
size_t mappingCount;
} BNDSCBackingCache;
diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp
index 9139d7ba..eae2e5b8 100644
--- a/view/sharedcache/core/SharedCache.cpp
+++ b/view/sharedcache/core/SharedCache.cpp
@@ -517,7 +517,7 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock)
{
dyld_cache_mapping_info mapping {};
BackingCache cache;
- cache.isPrimary = true;
+ cache.cacheType = BackingCacheTypePrimary;
cache.path = path;
for (size_t i = 0; i < primaryCacheHeader.mappingCount; i++)
@@ -583,7 +583,7 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock)
// briefly.
BackingCache cache;
- cache.isPrimary = true;
+ cache.cacheType = BackingCacheTypePrimary;
cache.path = path;
for (size_t i = 0; i < primaryCacheHeader.mappingCount; i++)
@@ -654,7 +654,7 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock)
dyld_cache_mapping_info subCacheMapping {};
BackingCache subCache;
- subCache.isPrimary = false;
+ subCache.cacheType = BackingCacheTypeSecondary;
subCache.path = subCachePath;
for (size_t j = 0; j < subCacheHeader.mappingCount; j++)
@@ -688,7 +688,7 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock)
dyld_cache_mapping_info mapping {}; // We're going to reuse this for all of the mappings. We only need it
// briefly.
BackingCache cache;
- cache.isPrimary = true;
+ cache.cacheType = BackingCacheTypePrimary;
cache.path = path;
for (size_t i = 0; i < primaryCacheHeader.mappingCount; i++)
@@ -740,7 +740,7 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock)
subCacheFile->Read(&subCacheHeader, 0, headerSize);
BackingCache subCache;
- subCache.isPrimary = false;
+ subCache.cacheType = BackingCacheTypeSecondary;
subCache.path = subCachePath;
dyld_cache_mapping_info subCacheMapping {};
@@ -808,7 +808,7 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock)
dyld_cache_mapping_info mapping {};
BackingCache cache;
- cache.isPrimary = true;
+ cache.cacheType = BackingCacheTypePrimary;
cache.path = path;
for (size_t i = 0; i < primaryCacheHeader.mappingCount; i++)
@@ -885,7 +885,7 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock)
dyld_cache_mapping_info subCacheMapping {};
BackingCache subCache;
- subCache.isPrimary = false;
+ subCache.cacheType = BackingCacheTypeSecondary;
subCache.path = subCachePath;
for (size_t j = 0; j < subCacheHeader.mappingCount; j++)
@@ -942,7 +942,7 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock)
subCacheFile->Read(&subCacheHeader, 0, headerSize);
BackingCache subCache;
- subCache.isPrimary = false;
+ subCache.cacheType = BackingCacheTypeSymbols;
subCache.path = subCachePath;
dyld_cache_mapping_info subCacheMapping {};
@@ -957,7 +957,9 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock)
initialState.backingCaches.push_back(std::move(subCache));
}
catch (...)
- {}
+ {
+ m_logger->LogWarn("Failed to load the symbols cache");
+ }
break;
}
}
@@ -3370,7 +3372,7 @@ extern "C"
for (size_t i = 0; i < viewCaches.size(); i++)
{
caches[i].path = BNAllocString(viewCaches[i].path.c_str());
- caches[i].isPrimary = viewCaches[i].isPrimary;
+ caches[i].cacheType = viewCaches[i].cacheType;
BNDSCBackingCacheMapping* mappings;
mappings = new BNDSCBackingCacheMapping[viewCaches[i].mappings.size()];
@@ -3750,7 +3752,7 @@ void SharedCache::ModifiedState::Merge(SharedCache::ModifiedState&& newer)
void BackingCache::Store(SerializationContext& context) const
{
MSS(path);
- MSS(isPrimary);
+ MSS_CAST(cacheType, uint32_t);
MSS(mappings);
}
@@ -3758,7 +3760,7 @@ BackingCache BackingCache::Load(DeserializationContext& context)
{
BackingCache cache;
cache.MSL(path);
- cache.MSL(isPrimary);
+ cache.MSL_CAST(cacheType, uint32_t, BNBackingCacheType);
cache.MSL(mappings);
return cache;
}
diff --git a/view/sharedcache/core/SharedCache.h b/view/sharedcache/core/SharedCache.h
index f5f63749..ee4228ef 100644
--- a/view/sharedcache/core/SharedCache.h
+++ b/view/sharedcache/core/SharedCache.h
@@ -104,7 +104,7 @@ namespace SharedCacheCore {
struct BackingCache : public MetadataSerializable<BackingCache> {
std::string path;
- bool isPrimary = false;
+ BNBackingCacheType cacheType = BackingCacheTypeSecondary;
std::vector<dyld_cache_mapping_info> mappings;
void Store(SerializationContext& context) const;