diff options
| author | kat <kat@vector35.com> | 2025-07-06 15:05:01 -0400 |
|---|---|---|
| committer | kat <kat@vector35.com> | 2025-07-07 07:37:23 -0400 |
| commit | 768f7c78465fb93936e5ca50a0ca712664fe54e7 (patch) | |
| tree | 78c73e0022d6006882e365a257595a5b55a37432 /view/kernelcache/api | |
| parent | 8f3e251c42169fb4fe8db9403d900571434d88ff (diff) | |
KernelCache rewrite
Diffstat (limited to 'view/kernelcache/api')
| -rw-r--r-- | view/kernelcache/api/kernelcache.cpp | 335 | ||||
| -rw-r--r-- | view/kernelcache/api/kernelcacheapi.h | 467 | ||||
| -rw-r--r-- | view/kernelcache/api/kernelcachecore.h | 149 | ||||
| -rw-r--r-- | view/kernelcache/api/python/kernelcache.py | 283 | ||||
| -rw-r--r-- | view/kernelcache/api/python/kernelcache_enums.py | 42 |
5 files changed, 663 insertions, 613 deletions
diff --git a/view/kernelcache/api/kernelcache.cpp b/view/kernelcache/api/kernelcache.cpp index 7a650660..30f40656 100644 --- a/view/kernelcache/api/kernelcache.cpp +++ b/view/kernelcache/api/kernelcache.cpp @@ -4,191 +4,192 @@ #include "kernelcacheapi.h" -namespace KernelCacheAPI { +using namespace BinaryNinja; +using namespace KernelCacheAPI; - KernelCache::KernelCache(Ref<BinaryView> view) { - m_object = BNGetKernelCache(view->GetObject()); - } +BNKernelCacheImage ImageToApi(CacheImage image) +{ + BNKernelCacheImage apiImage {}; + apiImage.name = BNAllocString(image.name.c_str()); + apiImage.headerFileAddress = image.headerFileAddress; + apiImage.headerVirtualAddress = image.headerVirtualAddress; + return apiImage; +} - BNKCViewLoadProgress KernelCache::GetLoadProgress(Ref<BinaryView> view) - { - return BNKCViewGetLoadProgress(view->GetFile()->GetSessionId()); - } +CacheImage ImageFromApi(BNKernelCacheImage image) +{ + CacheImage apiImage {}; + apiImage.name = image.name; + apiImage.headerVirtualAddress = image.headerVirtualAddress; + apiImage.headerFileAddress = image.headerFileAddress; + return apiImage; +} - uint64_t KernelCache::FastGetImageCount(Ref<BinaryView> view) - { - return BNKCViewFastGetImageCount(view->GetObject()); - } +CacheSymbol SymbolFromApi(BNKernelCacheSymbol apiSymbol) +{ + CacheSymbol symbol; + symbol.name = apiSymbol.name; + symbol.address = apiSymbol.address; + symbol.type = apiSymbol.symbolType; + return symbol; +} - bool KernelCache::LoadImageWithInstallName(const std::string& installName) - { - return BNKCViewLoadImageWithInstallName(m_object, installName.c_str()); - } +std::pair<std::string, Ref<Type>> CacheSymbol::DemangledName(BinaryView &view) const +{ + QualifiedName qname; + Ref<Type> outType = nullptr; + std::string shortName = name; + if (DemangleGeneric(view.GetDefaultArchitecture(), name, outType, qname, &view, true)) + shortName = qname.GetString(); + return {shortName, outType}; +} - bool KernelCache::LoadImageContainingAddress(uint64_t addr) - { - return BNKCViewLoadImageContainingAddress(m_object, addr); - } +Ref<Symbol> CacheSymbol::GetBNSymbol(BinaryView &view) const +{ + auto [shortName, _] = DemangledName(view); + return new Symbol(type, shortName, shortName, name, address, nullptr); +} - std::vector<std::string> KernelCache::GetAvailableImages() +std::string KernelCacheAPI::GetSymbolTypeAsString(const BNSymbolType &type) +{ + // NOTE: We currently only use the function and data symbol for cache symbols. + // update this if that changes. + switch (type) { - size_t count; - char** value = BNKCViewGetInstallNames(m_object, &count); - if (value == nullptr) - { - return {}; - } - - std::vector<std::string> result; - for (size_t i = 0; i < count; i++) - { - result.push_back(value[i]); - } - - BNFreeStringList(value, count); - return result; + case FunctionSymbol: + return "Function"; + case DataSymbol: + return "Data"; + default: + return "Unknown"; } +} - bool KernelCache::IsImageLoaded(const uint64_t address) const - { - return BNKCViewIsImageLoaded(m_object, address); - } +KernelCacheController::KernelCacheController(BNKernelCacheController *controller) +{ + m_object = controller; +} - std::vector<KCImage> KernelCache::GetImages() - { - size_t count; - BNKCImage* value = BNKCViewGetAllImages(m_object, &count); - if (value == nullptr) - { - return {}; - } +KCRef<KernelCacheController> KernelCacheController::GetController(BinaryView &view) +{ + BNKernelCacheController *controller = BNGetKernelCacheController(view.GetObject()); + if (controller == nullptr) + return nullptr; + return new KernelCacheController(controller); +} - std::vector<KCImage> result; - for (size_t i = 0; i < count; i++) - { - KCImage img; - img.name = value[i].name; - img.headerFileAddress = value[i].headerFileAddress; - for (size_t j = 0; j < value[i].mappingCount; j++) - { - KCImageMemoryMapping mapping; - mapping.name = value[i].mappings[j].name; - mapping.vmAddress = value[i].mappings[j].vmAddress; - mapping.rawViewOffset = value[i].mappings[j].rawViewOffset; - mapping.size = value[i].mappings[j].size; - mapping.loaded = value[i].mappings[j].loaded; - img.mappings.push_back(mapping); - } - result.push_back(img); - } +bool KernelCacheController::ApplyImage(BinaryView &view, const CacheImage &image) +{ + auto apiImage = ImageToApi(image); + bool result = BNKernelCacheControllerApplyImage(m_object, view.GetObject(), &apiImage); + BNKernelCacheFreeImage(apiImage); + return result; +} - BNKCViewFreeAllImages(value, count); - return result; - } +bool KernelCacheController::IsImageLoaded(const CacheImage &image) const +{ + auto apiImage = ImageToApi(image); + bool result = BNKernelCacheControllerIsImageLoaded(m_object, &apiImage); + BNKernelCacheFreeImage(apiImage); + return result; +} - std::vector<KCImage> KernelCache::GetLoadedImages() - { - size_t count; - auto images = BNKCViewGetLoadedImages(m_object, &count); - if (images == nullptr) - { - return {}; - } - std::vector<KCImage> result; - for (size_t i = 0; i < count; i++) - { - KCImage img; - img.name = images[i].name; - img.headerFileAddress = images[i].headerFileAddress; - for (size_t j = 0; j < images[i].mappingCount; j++) - { - KCImageMemoryMapping mapping; - mapping.name = images[i].mappings[j].name; - mapping.vmAddress = images[i].mappings[j].vmAddress; - mapping.rawViewOffset = images[i].mappings[j].rawViewOffset; - mapping.size = images[i].mappings[j].size; - mapping.loaded = images[i].mappings[j].loaded; - img.mappings.push_back(mapping); - } - result.push_back(img); - } - BNKCViewFreeAllImages(images, count); +std::optional<CacheImage> KernelCacheController::GetImageAt(uint64_t address) const +{ + BNKernelCacheImage apiImage; + if (!BNKernelCacheControllerGetImageAt(m_object, address, &apiImage)) + return std::nullopt; + CacheImage image = ImageFromApi(apiImage); + BNKernelCacheFreeImage(apiImage); + return image; +} - return result; - } +std::optional<CacheImage> KernelCacheController::GetImageContaining(uint64_t address) const +{ + BNKernelCacheImage apiImage; + if (!BNKernelCacheControllerGetImageContaining(m_object, address, &apiImage)) + return std::nullopt; + CacheImage image = ImageFromApi(apiImage); + BNKernelCacheFreeImage(apiImage); + return image; +} - std::vector<KCSymbol> KernelCache::LoadAllSymbolsAndWait() - { - size_t count; - BNKCSymbolRep* value = BNKCViewLoadAllSymbolsAndWait(m_object, &count); - if (value == nullptr) - { - return {}; - } +std::optional<CacheImage> KernelCacheController::GetImageWithName(const std::string &name) const +{ + BNKernelCacheImage apiImage; + if (!BNKernelCacheControllerGetImageWithName(m_object, name.c_str(), &apiImage)) + return std::nullopt; + CacheImage image = ImageFromApi(apiImage); + BNKernelCacheFreeImage(apiImage); + return image; +} - std::vector<KCSymbol> result; - for (size_t i = 0; i < count; i++) - { - KCSymbol sym; - sym.address = value[i].address; - sym.name = value[i].name; - sym.image = value[i].image; - result.push_back(sym); - } +std::vector<std::string> KernelCacheController::GetImageDependencies(const CacheImage &image) const +{ + size_t count; + BNKernelCacheImage apiImage = ImageToApi(image); + char **dependencies = BNKernelCacheControllerGetImageDependencies(m_object, &apiImage, &count); + BNKernelCacheFreeImage(apiImage); + std::vector<std::string> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + result.emplace_back(dependencies[i]); + BNFreeStringList(dependencies, count); + return result; +} - BNKCViewFreeSymbols(value, count); - return result; - } +std::optional<CacheSymbol> KernelCacheController::GetSymbolAt(uint64_t address) const +{ + BNKernelCacheSymbol apiSymbol; + if (!BNKernelCacheControllerGetSymbolAt(m_object, address, &apiSymbol)) + return std::nullopt; + CacheSymbol symbol = SymbolFromApi(apiSymbol); + BNKernelCacheFreeSymbol(apiSymbol); + return symbol; +} - std::string KernelCache::GetNameForAddress(uint64_t address) - { - char* name = BNKCViewGetNameForAddress(m_object, address); - if (name == nullptr) - return {}; - std::string result = name; - BNFreeString(name); - return result; - } +std::optional<CacheSymbol> KernelCacheController::GetSymbolWithName(const std::string &name) const +{ + BNKernelCacheSymbol apiSymbol; + if (!BNKernelCacheControllerGetSymbolWithName(m_object, name.c_str(), &apiSymbol)) + return std::nullopt; + CacheSymbol symbol = SymbolFromApi(apiSymbol); + BNKernelCacheFreeSymbol(apiSymbol); + return symbol; +} - std::string KernelCache::GetImageNameForAddress(uint64_t address) - { - char* name = BNKCViewGetImageNameForAddress(m_object, address); - if (name == nullptr) - return {}; - std::string result = name; - BNFreeString(name); - return result; - } +std::vector<CacheImage> KernelCacheController::GetImages() const +{ + size_t count; + BNKernelCacheImage *images = BNKernelCacheControllerGetImages(m_object, &count); + std::vector<CacheImage> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + result.emplace_back(ImageFromApi(images[i])); + BNKernelCacheFreeImageList(images, count); + return result; +} - std::optional<KernelCacheMachOHeader> KernelCache::GetMachOHeaderForImage(const std::string& name) - { - char* outputStr = BNKCViewGetImageHeaderForName(m_object, name.c_str()); - if (outputStr == nullptr) - return {}; - std::string output = outputStr; - BNFreeString(outputStr); - if (output.empty()) - return {}; - KernelCacheMachOHeader header = KernelCacheMachOHeader::LoadFromString(output); - return header; - } - - std::optional<KernelCacheMachOHeader> KernelCache::GetMachOHeaderForAddress(uint64_t address) - { - char* outputStr = BNKCViewGetImageHeaderForAddress(m_object, address); - if (outputStr == nullptr) - return {}; - std::string output = outputStr; - BNFreeString(outputStr); - if (output.empty()) - return {}; - KernelCacheMachOHeader header = KernelCacheMachOHeader::LoadFromString(output); - return header; - } - - BNKCViewState KernelCache::GetState() - { - return BNKCViewGetState(m_object); - } +std::vector<CacheImage> KernelCacheController::GetLoadedImages() const +{ + size_t count; + BNKernelCacheImage *images = BNKernelCacheControllerGetLoadedImages(m_object, &count); + std::vector<CacheImage> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + result.emplace_back(ImageFromApi(images[i])); + BNKernelCacheFreeImageList(images, count); + return result; +} -} // namespace KernelCacheAPI +std::vector<CacheSymbol> KernelCacheController::GetSymbols() const +{ + size_t count; + BNKernelCacheSymbol *symbols = BNKernelCacheControllerGetSymbols(m_object, &count); + std::vector<CacheSymbol> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + result.emplace_back(SymbolFromApi(symbols[i])); + BNKernelCacheFreeSymbolList(symbols, count); + return result; +} diff --git a/view/kernelcache/api/kernelcacheapi.h b/view/kernelcache/api/kernelcacheapi.h index 35c53d78..aceb30a5 100644 --- a/view/kernelcache/api/kernelcacheapi.h +++ b/view/kernelcache/api/kernelcacheapi.h @@ -1,274 +1,311 @@ #pragma once #include <binaryninjaapi.h> -#include "../core/MetadataSerializable.hpp" -#include "../api/view/macho/machoview.h" #include "kernelcachecore.h" -using namespace BinaryNinja; +template<class T> +class KCRefCountObject { + void AddRefInternal() { m_refs.fetch_add(1); } -namespace KernelCacheAPI { - template<class T> - class KCRefCountObject { - void AddRefInternal() { m_refs.fetch_add(1); } + void ReleaseInternal() { + if (m_refs.fetch_sub(1) == 1) + delete this; + } - void ReleaseInternal() { - if (m_refs.fetch_sub(1) == 1) - delete this; - } +public: + std::atomic<int> m_refs; + T *m_object; - public: - std::atomic<int> m_refs; - T *m_object; + KCRefCountObject() : m_refs(0), m_object(nullptr) {} + + virtual ~KCRefCountObject() = default; + + T *GetObject() const { return m_object; } + + static T *GetObject(KCRefCountObject *obj) { + if (!obj) + return nullptr; + return obj->GetObject(); + } - KCRefCountObject() : m_refs(0), m_object(nullptr) {} + void AddRef() { AddRefInternal(); } - virtual ~KCRefCountObject() {} + void Release() { ReleaseInternal(); } - T *GetObject() const { return m_object; } + void AddRefForRegistration() { AddRefInternal(); } +}; - static T *GetObject(KCRefCountObject *obj) { - if (!obj) - return nullptr; - return obj->GetObject(); + +template<class T, T *(*AddObjectReference)(T *), void (*FreeObjectReference)(T *)> +class KCCoreRefCountObject { + void AddRefInternal() { m_refs.fetch_add(1); } + + void ReleaseInternal() { + if (m_refs.fetch_sub(1) == 1) { + if (!m_registeredRef) + delete this; } + } - void AddRef() { AddRefInternal(); } +public: + std::atomic<int> m_refs; + bool m_registeredRef = false; + T *m_object; - void Release() { ReleaseInternal(); } + KCCoreRefCountObject() : m_refs(0), m_object(nullptr) {} - void AddRefForRegistration() { AddRefInternal(); } - }; + virtual ~KCCoreRefCountObject() = default; + T *GetObject() const { return m_object; } - template<class T, T *(*AddObjectReference)(T *), void (*FreeObjectReference)(T *)> - class KCCoreRefCountObject { - void AddRefInternal() { m_refs.fetch_add(1); } + static T *GetObject(KCCoreRefCountObject *obj) { + if (!obj) + return nullptr; + return obj->GetObject(); + } - void ReleaseInternal() { - if (m_refs.fetch_sub(1) == 1) { - if (!m_registeredRef) - delete this; - } - } + void AddRef() { + if (m_object && (m_refs != 0)) + AddObjectReference(m_object); + AddRefInternal(); + } - public: - std::atomic<int> m_refs; - bool m_registeredRef = false; - T *m_object; + void Release() { + if (m_object) + FreeObjectReference(m_object); + ReleaseInternal(); + } + + void AddRefForRegistration() { m_registeredRef = true; } - KCCoreRefCountObject() : m_refs(0), m_object(nullptr) {} + void ReleaseForRegistration() { + m_object = nullptr; + m_registeredRef = false; + if (m_refs == 0) + delete this; + } +}; - virtual ~KCCoreRefCountObject() {} +template <class T> +class KCRef +{ + T* m_obj; +#ifdef BN_REF_COUNT_DEBUG + void* m_assignmentTrace = nullptr; +#endif - T *GetObject() const { return m_object; } +public: + KCRef() : m_obj(NULL) {} - static T *GetObject(KCCoreRefCountObject *obj) { - if (!obj) - return nullptr; - return obj->GetObject(); + KCRef(T* obj) : m_obj(obj) + { + if (m_obj) + { + m_obj->AddRef(); +#ifdef BN_REF_COUNT_DEBUG + m_assignmentTrace = BNRegisterObjectRefDebugTrace(typeid(T).name()); +#endif } + } - void AddRef() { - if (m_object && (m_refs != 0)) - AddObjectReference(m_object); - AddRefInternal(); + KCRef(const KCRef<T>& obj) : m_obj(obj.m_obj) + { + if (m_obj) + { + m_obj->AddRef(); +#ifdef BN_REF_COUNT_DEBUG + m_assignmentTrace = BNRegisterObjectRefDebugTrace(typeid(T).name()); +#endif } + } - void Release() { - if (m_object) - FreeObjectReference(m_object); - ReleaseInternal(); + KCRef(KCRef<T>&& other) : m_obj(other.m_obj) + { + other.m_obj = 0; +#ifdef BN_REF_COUNT_DEBUG + m_assignmentTrace = other.m_assignmentTrace; +#endif + } + + ~KCRef() + { + if (m_obj) + { + m_obj->Release(); +#ifdef BN_REF_COUNT_DEBUG + BNUnregisterObjectRefDebugTrace(typeid(T).name(), m_assignmentTrace); +#endif } + } - void AddRefForRegistration() { m_registeredRef = true; } + KCRef<T>& operator=(const BinaryNinja::Ref<T>& obj) + { +#ifdef BN_REF_COUNT_DEBUG + if (m_obj) + BNUnregisterObjectRefDebugTrace(typeid(T).name(), m_assignmentTrace); + if (obj.m_obj) + m_assignmentTrace = BNRegisterObjectRefDebugTrace(typeid(T).name()); +#endif + T* oldObj = m_obj; + m_obj = obj.m_obj; + if (m_obj) + m_obj->AddRef(); + if (oldObj) + oldObj->Release(); + return *this; + } - void ReleaseForRegistration() { - m_object = nullptr; - m_registeredRef = false; - if (m_refs == 0) - delete this; + KCRef<T>& operator=(KCRef<T>&& other) + { + if (m_obj) + { +#ifdef BN_REF_COUNT_DEBUG + BNUnregisterObjectRefDebugTrace(typeid(T).name(), m_assignmentTrace); +#endif + m_obj->Release(); } - }; + m_obj = other.m_obj; + other.m_obj = 0; +#ifdef BN_REF_COUNT_DEBUG + m_assignmentTrace = other.m_assignmentTrace; +#endif + return *this; + } - struct KCMemoryRegion { - uint64_t vmAddress; - uint64_t size; - std::string prettyName; - }; + KCRef<T>& operator=(T* obj) + { +#ifdef BN_REF_COUNT_DEBUG + if (m_obj) + BNUnregisterObjectRefDebugTrace(typeid(T).name(), m_assignmentTrace); + if (obj) + m_assignmentTrace = BNRegisterObjectRefDebugTrace(typeid(T).name()); +#endif + T* oldObj = m_obj; + m_obj = obj; + if (m_obj) + m_obj->AddRef(); + if (oldObj) + oldObj->Release(); + return *this; + } - struct BackingCacheMapping { - uint64_t vmAddress; - uint64_t size; - uint64_t fileOffset; - }; + operator T*() const + { + return m_obj; + } - struct BackingCache { - std::string path; - bool isPrimary; - std::vector<BackingCacheMapping> mappings; - }; + T* operator->() const + { + return m_obj; + } - struct KCImageMemoryMapping { - std::string name; - uint64_t vmAddress; - uint64_t size; - bool loaded; - uint64_t rawViewOffset; - }; + T& operator*() const + { + return *m_obj; + } - struct KCImage { - std::string name; - uint64_t headerFileAddress; - std::vector<KCImageMemoryMapping> mappings; - }; + bool operator!() const + { + return m_obj == NULL; + } - struct KCSymbol { - uint64_t address; - std::string name; - std::string image; - }; + bool operator==(const T* obj) const + { + return T::GetObject(m_obj) == T::GetObject(obj); + } - using namespace BinaryNinja; - struct KernelCacheMachOHeader : public KernelCacheCore::MetadataSerializable<KernelCacheMachOHeader> { - uint64_t textBase = 0; - uint64_t loadCommandOffset = 0; - mach_header_64 ident; - std::string identifierPrefix; - std::string installName; + bool operator==(const KCRef<T>& obj) const + { + return T::GetObject(m_obj) == T::GetObject(obj.m_obj); + } - std::vector<std::pair<uint64_t, bool>> entryPoints; - std::vector<uint64_t> m_entryPoints; //list of entrypoints + bool operator!=(const T* obj) const + { + return T::GetObject(m_obj) != T::GetObject(obj); + } - symtab_command symtab; - dysymtab_command dysymtab; - dyld_info_command dyldInfo; - routines_command_64 routines64; - function_starts_command functionStarts; - std::vector<section_64> moduleInitSections; - linkedit_data_command exportTrie; - linkedit_data_command chainedFixups {}; + bool operator!=(const KCRef<T>& obj) const + { + return T::GetObject(m_obj) != T::GetObject(obj.m_obj); + } - uint64_t relocationBase; - // Section and program headers, internally use 64-bit form as it is a superset of 32-bit - std::vector<segment_command_64> segments; //only three types of sections __TEXT, __DATA, __IMPORT - segment_command_64 linkeditSegment; - std::vector<section_64> sections; - std::vector<std::string> sectionNames; + bool operator<(const T* obj) const + { + return T::GetObject(m_obj) < T::GetObject(obj); + } - std::vector<section_64> symbolStubSections; - std::vector<section_64> symbolPointerSections; + bool operator<(const KCRef<T>& obj) const + { + return T::GetObject(m_obj) < T::GetObject(obj.m_obj); + } - std::vector<std::string> dylibs; + T* GetPtr() const + { + return m_obj; + } +}; - build_version_command buildVersion; - std::vector<build_tool_version> buildToolVersions; - bool dysymPresent = false; - bool dyldInfoPresent = false; - bool exportTriePresent = false; - bool chainedFixupsPresent = false; - bool routinesPresent = false; - bool functionStartsPresent = false; - bool relocatable = false; - void Store(KernelCacheCore::SerializationContext& context) const { - MSS(textBase); - MSS(loadCommandOffset); - MSS_SUBCLASS(ident); - MSS(identifierPrefix); - MSS(installName); - MSS(entryPoints); - MSS(m_entryPoints); - MSS_SUBCLASS(symtab); - MSS_SUBCLASS(dysymtab); - MSS_SUBCLASS(dyldInfo); - MSS_SUBCLASS(routines64); - MSS_SUBCLASS(functionStarts); - MSS_SUBCLASS(moduleInitSections); - MSS_SUBCLASS(exportTrie); - MSS_SUBCLASS(chainedFixups); - MSS(relocationBase); - MSS_SUBCLASS(segments); - MSS_SUBCLASS(linkeditSegment); - MSS_SUBCLASS(sections); - MSS(sectionNames); - MSS_SUBCLASS(symbolStubSections); - MSS_SUBCLASS(symbolPointerSections); - MSS(dylibs); - MSS_SUBCLASS(buildVersion); - MSS_SUBCLASS(buildToolVersions); - MSS(dysymPresent); - MSS(dyldInfoPresent); - MSS(exportTriePresent); - MSS(chainedFixupsPresent); - MSS(routinesPresent); - MSS(functionStartsPresent); - MSS(relocatable); - } +namespace KernelCacheAPI { + struct CacheMappingInfo + { + uint64_t vmAddress; + uint64_t size; + uint64_t fileOffset; + }; - static KernelCacheMachOHeader Load(KernelCacheCore::DeserializationContext& context) { - KernelCacheMachOHeader header; - header.MSL(textBase); - header.MSL(loadCommandOffset); - header.MSL(ident); - header.MSL(identifierPrefix); - header.MSL(installName); - header.MSL(entryPoints); - header.MSL(m_entryPoints); - header.MSL(symtab); - header.MSL(dysymtab); - header.MSL(dyldInfo); - header.MSL(routines64); - header.MSL(functionStarts); - header.MSL(moduleInitSections); - header.MSL(exportTrie); - header.MSL(chainedFixups); - header.MSL(relocationBase); - header.MSL(segments); - header.MSL(linkeditSegment); - header.MSL(sections); - header.MSL(sectionNames); - header.MSL(symbolStubSections); - header.MSL(symbolPointerSections); - header.MSL(dylibs); - header.MSL(buildVersion); - header.MSL(buildToolVersions); - header.MSL(dysymPresent); - header.MSL(dyldInfoPresent); - header.MSL(exportTriePresent); - header.MSL(chainedFixupsPresent); - header.MSL(routinesPresent); - header.MSL(functionStartsPresent); - header.MSL(relocatable); - return header; - } + struct CacheImage + { + uint64_t headerFileAddress; + uint64_t headerVirtualAddress; + std::string name; }; + struct CacheEntry + { + std::string path; + std::string name; + BNKernelCacheEntryType entryType; + std::vector<CacheMappingInfo> mappings; + }; - class KernelCache : public KCCoreRefCountObject<BNKernelCache, BNNewKernelCacheReference, BNFreeKernelCacheReference> { - public: - KernelCache(Ref<BinaryView> view); + struct CacheSymbol + { + BNSymbolType type; + uint64_t address; + std::string name; + + std::pair<std::string, BinaryNinja::Ref<BinaryNinja::Type>> DemangledName(BinaryNinja::BinaryView &view) const; + BinaryNinja::Ref<BinaryNinja::Symbol> GetBNSymbol(BinaryNinja::BinaryView& view) const; + }; + + std::string GetSymbolTypeAsString(const BNSymbolType& type); - BNKCViewState GetState(); - static BNKCViewLoadProgress GetLoadProgress(Ref<BinaryView> view); - static uint64_t FastGetImageCount(Ref<BinaryView> view); + class KernelCacheController : public KCCoreRefCountObject<BNKernelCacheController, BNNewKernelCacheControllerReference, BNFreeKernelCacheControllerReference> { + public: + explicit KernelCacheController(BNKernelCacheController* controller); + static KCRef<KernelCacheController> GetController(BinaryNinja::BinaryView& view); - bool LoadImageWithInstallName(const std::string& installName); - bool LoadImageContainingAddress(uint64_t addr); - std::vector<std::string> GetAvailableImages(); + // Attempt to load the given image into the view. + // + // It is the callers responsibility to run linear sweep and update analysis, as you might want to add + // multiple images at a time. + bool ApplyImage(BinaryNinja::BinaryView& view, const CacheImage& image); - bool IsImageLoaded(const uint64_t address) const; + bool IsImageLoaded(const CacheImage& image) const; - std::vector<KCSymbol> LoadAllSymbolsAndWait(); + std::optional<CacheImage> GetImageAt(uint64_t address) const; + std::optional<CacheImage> GetImageContaining(uint64_t address) const; + std::optional<CacheImage> GetImageWithName(const std::string& name) const; - std::string GetNameForAddress(uint64_t address); - std::string GetImageNameForAddress(uint64_t address); + std::vector<std::string> GetImageDependencies(const CacheImage& image) const; - std::vector<KCImage> GetImages(); - std::vector<KCImage> GetLoadedImages(); + std::optional<CacheSymbol> GetSymbolAt(uint64_t address) const; + std::optional<CacheSymbol> GetSymbolWithName(const std::string& name) const; - std::optional<KernelCacheMachOHeader> GetMachOHeaderForImage(const std::string& name); - std::optional<KernelCacheMachOHeader> GetMachOHeaderForAddress(uint64_t address); + std::vector<CacheImage> GetImages() const; + std::vector<CacheImage> GetLoadedImages() const; + std::vector<CacheSymbol> GetSymbols() const; }; -}
\ No newline at end of file +} diff --git a/view/kernelcache/api/kernelcachecore.h b/view/kernelcache/api/kernelcachecore.h index 2f158131..02451a3e 100644 --- a/view/kernelcache/api/kernelcachecore.h +++ b/view/kernelcache/api/kernelcachecore.h @@ -28,6 +28,34 @@ extern "C" #endif // _MSC_VER #endif // __GNUC__C + +// binaryninjacore.h is not included so we must duplicate enum types here. +#ifdef BN_TYPE_PARSER +typedef enum BNSegmentFlag +{ + SegmentExecutable = 1, + SegmentWritable = 2, + SegmentReadable = 4, + SegmentContainsData = 8, + SegmentContainsCode = 0x10, + SegmentDenyWrite = 0x20, + SegmentDenyExecute = 0x40 +} BNSegmentFlag; + +typedef enum BNSymbolType +{ + FunctionSymbol = 0, + ImportAddressSymbol = 1, + ImportedFunctionSymbol = 2, + DataSymbol = 3, + ImportedDataSymbol = 4, + ExternalSymbol = 5, + LibraryFunctionSymbol = 6, + SymbolicFunctionSymbol = 7, + LocalLabelSymbol = 8, +} BNSymbolType; +#endif + #define CORE_ALLOCATED_STRUCT(T) #define CORE_ALLOCATED_CLASS(T) \ @@ -35,101 +63,80 @@ extern "C" CORE_ALLOCATED_STRUCT(T) \ private: -#define DECLARE_KERNELCACHE_API_OBJECT_INTERNAL(handle, cls, ns) \ - namespace ns { class cls; } struct handle { ns::cls* object; } - -#define DECLARE_KERNELCACHE_API_OBJECT(handle, cls) DECLARE_KERNELCACHE_API_OBJECT_INTERNAL(handle, cls, KernelCacheCore) - -#define IMPLEMENT_KERNELCACHE_API_OBJECT(handle) \ - CORE_ALLOCATED_CLASS(handle) \ - private: \ - handle m_apiObject; \ - public: \ - typedef handle* APIHandle; \ - handle* GetAPIObject() { return &m_apiObject; } \ - private: -#define INIT_KERNELCACHE_API_OBJECT() \ - m_apiObject.object = this; + typedef struct BNBinaryView BNBinaryView; + typedef struct BNKernelCacheController BNKernelCacheController; - typedef enum BNKCViewState { - Unloaded, - Loaded, - LoadedWithImages, - } BNKCViewState; + typedef enum BNKernelCacheEntryType { + KernelCacheEntryTypePrimary, + KernelCacheEntryTypeSecondary, + KernelCacheEntryTypeSymbols, + KernelCacheEntryTypeDyldData, + KernelCacheEntryTypeStub, + } BNKernelCacheEntryType; - typedef enum BNKCViewLoadProgress { - LoadProgressNotStarted, - LoadProgressLoadingCaches, - LoadProgressLoadingImages, - LoadProgressFinished, - } BNKCViewLoadProgress; + typedef enum BNKernelCacheRegionType { + KernelCacheRegionTypeImage, + KernelCacheRegionTypeStubIsland, + KernelCacheRegionTypeDyldData, + KernelCacheRegionTypeNonImage, + } BNKernelCacheRegionType; - typedef struct BNBinaryView BNBinaryView; - typedef struct BNKernelCache BNKernelCache; + typedef struct BNKernelCacheImage { + char* name; + uint64_t headerVirtualAddress; + uint64_t headerFileAddress; + } BNKernelCacheImage; - typedef struct BNKCImageMemoryMapping { + typedef struct BNKernelCacheRegion { + BNKernelCacheRegionType regionType; char* name; uint64_t vmAddress; uint64_t size; - bool loaded; - uint64_t rawViewOffset; - } BNKCImageMemoryMapping; - - typedef struct BNKCImage { - char* name; - uint64_t headerFileAddress; - BNKCImageMemoryMapping* mappings; - size_t mappingCount; - } BNKCImage; + // NOTE: If not associated with an image this will be zero. + uint64_t imageStart; + BNSegmentFlag flags; + } BNKernelCacheRegion; - typedef struct BNKCMappedMemoryRegion { + typedef struct BNKernelCacheMappingInfo { uint64_t vmAddress; uint64_t size; - char* name; - } BNKCMappedMemoryRegion; + uint64_t fileOffset; + } BNKernelCacheMappingInfo; - typedef struct BNKCMemoryUsageInfo { - uint64_t sharedCacheRefs; - uint64_t mmapRefs; - } BNKCMemoryUsageInfo; - - typedef struct BNKCSymbolRep { + typedef struct BNKernelCacheSymbol { + BNSymbolType symbolType; uint64_t address; char* name; - char* image; - } BNKCSymbolRep; - - KERNELCACHE_FFI_API BNKernelCache* BNGetKernelCache(BNBinaryView* data); + } BNKernelCacheSymbol; - KERNELCACHE_FFI_API BNKernelCache* BNNewKernelCacheReference(BNKernelCache* cache); - KERNELCACHE_FFI_API void BNFreeKernelCacheReference(BNKernelCache* cache); + KERNELCACHE_FFI_API BNKernelCacheController* BNGetKernelCacheController(BNBinaryView* data); - KERNELCACHE_FFI_API char** BNKCViewGetInstallNames(BNKernelCache* cache, size_t* count); + KERNELCACHE_FFI_API BNKernelCacheController* BNNewKernelCacheControllerReference(BNKernelCacheController* controller); + KERNELCACHE_FFI_API void BNFreeKernelCacheControllerReference(BNKernelCacheController* controller); - KERNELCACHE_FFI_API bool BNKCViewLoadImageWithInstallName(BNKernelCache* cache, const char* name); - KERNELCACHE_FFI_API bool BNKCViewLoadImageContainingAddress(BNKernelCache* cache, uint64_t address); + KERNELCACHE_FFI_API bool BNKernelCacheControllerApplyImage(BNKernelCacheController* controller, BNBinaryView* view, BNKernelCacheImage* image); - KERNELCACHE_FFI_API bool BNKCViewIsImageLoaded(BNKernelCache* cache, uint64_t address); + KERNELCACHE_FFI_API bool BNKernelCacheControllerIsImageLoaded(BNKernelCacheController* controller, BNKernelCacheImage* image); - KERNELCACHE_FFI_API char* BNKCViewGetNameForAddress(BNKernelCache* cache, uint64_t address); - KERNELCACHE_FFI_API char* BNKCViewGetImageNameForAddress(BNKernelCache* cache, uint64_t address); + KERNELCACHE_FFI_API bool BNKernelCacheControllerGetImageAt(BNKernelCacheController* controller, uint64_t address, BNKernelCacheImage* image); + KERNELCACHE_FFI_API bool BNKernelCacheControllerGetImageContaining(BNKernelCacheController* controller, uint64_t address, BNKernelCacheImage* image); + KERNELCACHE_FFI_API bool BNKernelCacheControllerGetImageWithName(BNKernelCacheController* controller, const char* name, BNKernelCacheImage* image); - KERNELCACHE_FFI_API BNKCViewState BNKCViewGetState(BNKernelCache* cache); - KERNELCACHE_FFI_API BNKCViewLoadProgress BNKCViewGetLoadProgress(uint64_t sessionID); - KERNELCACHE_FFI_API uint64_t BNKCViewFastGetImageCount(BNBinaryView* view); + KERNELCACHE_FFI_API char** BNKernelCacheControllerGetImageDependencies(BNKernelCacheController* controller, BNKernelCacheImage* image, size_t* count); - KERNELCACHE_FFI_API BNKCSymbolRep* BNKCViewLoadAllSymbolsAndWait(BNKernelCache* cache, size_t* count); - KERNELCACHE_FFI_API void BNKCViewFreeSymbols(BNKCSymbolRep* symbols, size_t count); + KERNELCACHE_FFI_API BNKernelCacheImage* BNKernelCacheControllerGetImages(BNKernelCacheController* controller, size_t* count); + KERNELCACHE_FFI_API BNKernelCacheImage* BNKernelCacheControllerGetLoadedImages(BNKernelCacheController* controller, size_t* count); - KERNELCACHE_FFI_API BNKCImage* BNKCViewGetAllImages(BNKernelCache* cache, size_t* count); - KERNELCACHE_FFI_API void BNKCViewFreeAllImages(BNKCImage* images, size_t count); + KERNELCACHE_FFI_API void BNKernelCacheFreeImage(BNKernelCacheImage image); + KERNELCACHE_FFI_API void BNKernelCacheFreeImageList(BNKernelCacheImage* images, size_t count); - KERNELCACHE_FFI_API BNKCImage* BNKCViewGetLoadedImages(BNKernelCache* cache, size_t* count); - KERNELCACHE_FFI_API void BNKCViewFreeLoadedImages(BNKCImage* images, size_t count); + KERNELCACHE_FFI_API bool BNKernelCacheControllerGetSymbolAt(BNKernelCacheController* controller, uint64_t address, BNKernelCacheSymbol* symbol); + KERNELCACHE_FFI_API bool BNKernelCacheControllerGetSymbolWithName(BNKernelCacheController* controller, const char* name, BNKernelCacheSymbol* symbol); - KERNELCACHE_FFI_API char* BNKCViewGetImageHeaderForAddress(BNKernelCache* cache, uint64_t address); - KERNELCACHE_FFI_API char* BNKCViewGetImageHeaderForName(BNKernelCache* cache, const char* name); + KERNELCACHE_FFI_API BNKernelCacheSymbol* BNKernelCacheControllerGetSymbols(BNKernelCacheController* controller, size_t* count); + KERNELCACHE_FFI_API void BNKernelCacheFreeSymbol(BNKernelCacheSymbol symbol); + KERNELCACHE_FFI_API void BNKernelCacheFreeSymbolList(BNKernelCacheSymbol* symbols, size_t count); #ifdef __cplusplus } #endif diff --git a/view/kernelcache/api/python/kernelcache.py b/view/kernelcache/api/python/kernelcache.py index 9425ef9c..25360213 100644 --- a/view/kernelcache/api/python/kernelcache.py +++ b/view/kernelcache/api/python/kernelcache.py @@ -1,229 +1,210 @@ -import os import ctypes import dataclasses -import traceback +from typing import Optional import binaryninja +from binaryninja import BinaryView from binaryninja._binaryninjacore import BNFreeStringList, BNAllocString, BNFreeString from . import _kernelcachecore as kccore from .kernelcache_enums import * - @dataclasses.dataclass -class KCImageMemoryMapping: +class CacheImage: name: str - vmAddress: int - rawViewOffset: int - size: int + header_virtual_address: int + header_file_address: int def __str__(self): return repr(self) def __repr__(self): - return (f"<KCImageMemoryMapping '{self.name}' {self.vmAddress:x}+{self.size:x} " - f"raw<{self.rawViewOffset:x}>>") - + return f"<CacheImage '{self.name}': 0x{self.header_virtual_address:x} (@0x{self.header_file_address:x})>" @dataclasses.dataclass -class KCImage: +class CacheSymbol: + symbol_type: kccore.SymbolTypeEnum + address: int name: str - headerFileAddress: int - mappings: list[KCImageMemoryMapping] def __str__(self): return repr(self) def __repr__(self): - return f"<KCImage {self.name} @ {self.headerFileAddress:x}>" + return f"<CacheSymbol '{self.name}': 0x{self.address:x}>" +def image_from_api(image: kccore.BNKernelCacheImage) -> CacheImage: + return CacheImage( + name=image.name, + header_file_address=image.headerFileAddress, + header_virtual_address=image.headerVirtualAddress + ) -@dataclasses.dataclass -class KCSymbol: - name: str - image: str - address: int +def image_to_api(image: CacheImage) -> kccore.BNKernelCacheImage: + return kccore.BNKernelCacheImage( + _name=BNAllocString(image.name), + headerFileAddress=image.header_file_address, + headerVirtualAddress=image.header_virtual_address, + ) - def __str__(self): - return repr(self) +def symbol_from_api(symbol: kccore.BNKernelCacheSymbol) -> CacheSymbol: + return CacheSymbol( + symbol_type=symbol.symbolType, + address=symbol.address, + name=symbol.name + ) - def __repr__(self): - return f"<KCSymbol {self.name} @ {self.address:x} ({self.image})>" +def symbol_to_api(symbol: CacheSymbol) -> kccore.BNKernelCacheSymbol: + return kccore.BNKernelCacheSymbol( + symbolType=symbol.symbol_type, + address=symbol.address, + _name=BNAllocString(symbol.name) + ) +class KernelCacheController: + def __init__(self, view: BinaryView): + """ + Retrieve the shared cache controller for a given view. + Call `is_valid` to check if the controller is valid. + """ + self.handle = kccore.BNGetKernelCacheController(view.handle) -@dataclasses.dataclass -class KernelCacheMachOHeader: - header: str + def __del__(self): + if self.handle is not None: + kccore.BNFreeKernelCacheControllerReference(self.handle) - @classmethod - def LoadFromString(cls, s: str): - return cls(header=s) + def __str__(self): + return repr(self) def __repr__(self): - return f"<KernelCacheMachOHeader {self.header!r}>" + return f"<KernelCacheController: {len(self.images)} images>" + def is_valid(self) -> bool: + return self.handle is not None -class KernelCache: - def __init__(self, view): - # Create a KernelCache object from a BinaryView. - self.handle = kccore.BNGetKernelCache(view.handle) + def apply_image(self, view: BinaryView, image: CacheImage) -> bool: + api_image: kccore.BNKernelCacheImage = image_to_api(image) + result = kccore.BNKernelCacheControllerApplyImage(self.handle, view.handle, api_image) + kccore.BNKernelCacheFreeImage(api_image) + return result - @staticmethod - def get_load_progress(view) -> int: - """ - Returns the current load progress. - Note: In the C++ FFI this function takes the BinaryView's file session ID. - """ - return KCViewLoadProgress(kccore.BNKCViewGetLoadProgress(view.file.session_id)) + def is_image_loaded(self, image: CacheImage) -> bool: + api_image: kccore.BNKernelCacheImage = image_to_api(image) + result = kccore.BNKernelCacheControllerIsImageLoaded(self.handle, api_image) + kccore.BNKernelCacheFreeImage(api_image) + return result - @staticmethod - def fast_get_image_count(view) -> int: - """ - Quickly returns the number of images in the kernel cache. - """ - return kccore.BNKCViewFastGetImageCount(view.handle) + def get_image_at(self, address: int) -> Optional[CacheImage]: + api_image = kccore.BNKernelCacheImage() + if not kccore.BNKernelCacheControllerGetImageAt(self.handle, address, api_image): + return None + image = image_from_api(api_image) + kccore.BNKernelCacheFreeImage(api_image) + return image - def load_image_with_install_name(self, install_name: str) -> bool: - """ - Load a kernel cache image by its install name. - """ - return kccore.BNKCViewLoadImageWithInstallName(self.handle, install_name) + def get_image_containing(self, address: int) -> Optional[CacheImage]: + api_image = kccore.BNKernelCacheImage() + if not kccore.BNKernelCacheControllerGetImageContaining(self.handle, address, api_image): + return None + image = image_from_api(api_image) + kccore.BNKernelCacheFreeImage(api_image) + return image - def load_image_containing_address(self, addr: int) -> bool: - """ - Load the image that contains the given address. - """ - return kccore.BNKCViewLoadImageContainingAddress(self.handle, addr) + def get_image_with_name(self, name: str) -> Optional[CacheImage]: + api_image = kccore.BNKernelCacheImage() + if not kccore.BNKernelCacheControllerGetImageWithName(self.handle, name, api_image): + return None + image = image_from_api(api_image) + kccore.BNKernelCacheFreeImage(api_image) + return image - @property - def image_names(self) -> list[str]: + def get_image_dependencies(self, image: CacheImage) -> [str]: """ - Return a list of available kernel cache image install names. + Returns a list of image names that this image depends on. """ count = ctypes.c_ulonglong() - value = kccore.BNKCViewGetInstallNames(self.handle, count) + api_image: kccore.BNKernelCacheImage = image_to_api(image) + value = kccore.BNKernelCacheControllerGetImageDependencies(self.handle, api_image, count) + kccore.BNKernelCacheFreeImage(api_image) if value is None: return [] result = [] for i in range(count.value): - result.append(value[i].decode('utf-8')) + result.append(value[i].decode("utf-8")) BNFreeStringList(value, count) return result + def get_symbol_at(self, address: int) -> Optional[CacheSymbol]: + api_symbol = kccore.BNKernelCacheSymbol() + if not kccore.BNKernelCacheControllerGetSymbolAt(self.handle, address, api_symbol): + return None + symbol = symbol_from_api(api_symbol) + kccore.BNKernelCacheFreeSymbol(api_symbol) + return symbol + + def get_symbol_with_name(self, name: str) -> Optional[CacheSymbol]: + api_symbol = kccore.BNKernelCacheSymbol() + if not kccore.BNKernelCacheControllerGetSymbolWithName(self.handle, name, api_symbol): + return None + symbol = symbol_from_api(api_symbol) + kccore.BNKernelCacheFreeSymbol(api_symbol) + return symbol + @property - def images(self) -> list[KCImage]: - """ - Return all kernel cache images. - """ + def images(self) -> [CacheImage]: count = ctypes.c_ulonglong() - value = kccore.BNKCViewGetAllImages(self.handle, count) + value = kccore.BNKernelCacheControllerGetImages(self.handle, count) if value is None: return [] result = [] for i in range(count.value): - mappings = [] - for j in range(value[i].mappingCount): - mapping = KCImageMemoryMapping( - name=value[i].mappings[j].name, - vmAddress=value[i].mappings[j].vmAddress, - rawViewOffset=value[i].mappings[j].rawViewOffset, - size=value[i].mappings[j].size, - ) - mappings.append(mapping) - result.append(KCImage( - name=value[i].name, - headerFileAddress=value[i].headerFileAddress, - mappings=mappings - )) - kccore.BNKCViewFreeAllImages(value, count) + result.append(image_from_api(value[i])) + kccore.BNKernelCacheFreeImageList(value, count) return result @property - def loaded_images(self) -> list[KCImage]: + def loaded_images(self) -> [CacheImage]: """ - Return the kernel cache images that are currently loaded. + Get a list of images that are currently loaded in the view. """ count = ctypes.c_ulonglong() - images = kccore.BNKCViewGetLoadedImages(self.handle, count) - if images is None: + value = kccore.BNKernelCacheControllerGetLoadedImages(self.handle, count) + if value is None: return [] result = [] for i in range(count.value): - mappings = [] - for j in range(images[i].mappingCount): - mapping = KCImageMemoryMapping( - name=images[i].mappings[j].name, - vmAddress=images[i].mappings[j].vmAddress, - rawViewOffset=images[i].mappings[j].rawViewOffset, - size=images[i].mappings[j].size, - ) - mappings.append(mapping) - result.append(KCImage( - name=images[i].name, - headerFileAddress=images[i].headerFileAddress, - mappings=mappings - )) - kccore.BNKCViewFreeAllImages(images, count) + result.append(image_from_api(value[i])) + kccore.BNKernelCacheFreeImageList(value, count) return result - def load_all_symbols_and_wait(self) -> list[KCSymbol]: - """ - Load all symbols from the kernel cache and wait for completion. - """ + @property + def symbols(self) -> [CacheSymbol]: count = ctypes.c_ulonglong() - value = kccore.BNKCViewLoadAllSymbolsAndWait(self.handle, count) + value = kccore.BNKernelCacheControllerGetSymbols(self.handle, count) if value is None: return [] result = [] for i in range(count.value): - sym = KCSymbol( - name=value[i].name, - image=value[i].image, - address=value[i].address - ) - result.append(sym) - kccore.BNKCViewFreeSymbols(value, count) + result.append(symbol_from_api(value[i])) + kccore.BNKernelCacheFreeSymbolList(value, count) return result - def get_name_for_address(self, address: int) -> str: - """ - Return the symbol name for a given address. - """ - name = kccore.BNKCViewGetNameForAddress(self.handle, address) - if name is None: - return "" - return name - def get_image_name_for_address(self, address: int) -> str: - """ - Return the image name for a given address. - """ - name = kccore.BNKCViewGetImageNameForAddress(self.handle, address) - if name is None: - return "" - return name +def _get_kernel_cache(instance: binaryninja.PythonScriptingInstance): + if instance.interpreter.active_view is None: + return None + controller = KernelCacheController(instance.interpreter.active_view) + if not controller.is_valid(): + return None + return controller - def get_macho_header_for_image(self, name: str): - """ - Return a KernelCacheMachOHeader for the image with the given install name. - """ - outputStr = kccore.BNKCViewGetImageHeaderForName(self.handle, name) - if outputStr is None: - return None - return KernelCacheMachOHeader.LoadFromString(outputStr) - def get_macho_header_for_address(self, address: int): - """ - Return a KernelCacheMachOHeader for the image containing the given address. - """ - outputStr = kccore.BNKCViewGetImageHeaderForAddress(self.handle, address) - if outputStr is None: - return None - return KernelCacheMachOHeader.LoadFromString(outputStr) +binaryninja.PythonScriptingProvider.register_magic_variable( + "kc", + _get_kernel_cache +) - @property - def state(self): - """ - Return the current state of the kernel cache. - """ - return KCViewState(kccore.BNKCViewGetState(self.handle)) +binaryninja.PythonScriptingProvider.register_magic_variable( + "kernel_cache", + _get_kernel_cache +) diff --git a/view/kernelcache/api/python/kernelcache_enums.py b/view/kernelcache/api/python/kernelcache_enums.py index e610c527..83cbf027 100644 --- a/view/kernelcache/api/python/kernelcache_enums.py +++ b/view/kernelcache/api/python/kernelcache_enums.py @@ -1,14 +1,38 @@ import enum -class KCViewLoadProgress(enum.IntEnum): - LoadProgressNotStarted = 0 - LoadProgressLoadingCaches = 1 - LoadProgressLoadingImages = 2 - LoadProgressFinished = 3 +class KernelCacheEntryType(enum.IntEnum): + KernelCacheEntryTypePrimary = 0 + KernelCacheEntryTypeSecondary = 1 + KernelCacheEntryTypeSymbols = 2 + KernelCacheEntryTypeDyldData = 3 + KernelCacheEntryTypeStub = 4 -class KCViewState(enum.IntEnum): - Unloaded = 0 - Loaded = 1 - LoadedWithImages = 2 +class KernelCacheRegionType(enum.IntEnum): + KernelCacheRegionTypeImage = 0 + KernelCacheRegionTypeStubIsland = 1 + KernelCacheRegionTypeDyldData = 2 + KernelCacheRegionTypeNonImage = 3 + + +class SegmentFlag(enum.IntEnum): + SegmentExecutable = 1 + SegmentWritable = 2 + SegmentReadable = 4 + SegmentContainsData = 8 + SegmentContainsCode = 16 + SegmentDenyWrite = 32 + SegmentDenyExecute = 64 + + +class SymbolType(enum.IntEnum): + FunctionSymbol = 0 + ImportAddressSymbol = 1 + ImportedFunctionSymbol = 2 + DataSymbol = 3 + ImportedDataSymbol = 4 + ExternalSymbol = 5 + LibraryFunctionSymbol = 6 + SymbolicFunctionSymbol = 7 + LocalLabelSymbol = 8 |
