From 768f7c78465fb93936e5ca50a0ca712664fe54e7 Mon Sep 17 00:00:00 2001 From: kat Date: Sun, 6 Jul 2025 15:05:01 -0400 Subject: KernelCache rewrite --- view/kernelcache/core/Utility.h | 106 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 view/kernelcache/core/Utility.h (limited to 'view/kernelcache/core/Utility.h') diff --git a/view/kernelcache/core/Utility.h b/view/kernelcache/core/Utility.h new file mode 100644 index 00000000..5664fd9b --- /dev/null +++ b/view/kernelcache/core/Utility.h @@ -0,0 +1,106 @@ +#pragma once + +#include +#include + +#include "binaryninjaapi.h" + +#ifdef _MSC_VER +inline int CountTrailingZeros(uint64_t value) +{ + unsigned long index; // 32-bit long on Windows + if (_BitScanForward64(&index, value)) + { + return index; + } + else + { + return 64; // If the value is 0, return 64. + } +} +#else +inline int CountTrailingZeros(uint64_t value) +{ + return value == 0 ? 64 : __builtin_ctzll(value); +} +#endif + +BNSegmentFlag SegmentFlagsFromMachOProtections(int initProt, int maxProt); + +int64_t readSLEB128(const uint8_t*& current, const uint8_t* end); + +uint64_t readLEB128(const uint8_t*& current, const uint8_t* end); + +uint64_t readValidULEB128(const uint8_t*& current, const uint8_t* end); + +void ApplySymbol(BinaryNinja::Ref view, BinaryNinja::Ref typeLib, + BinaryNinja::Ref symbol, BinaryNinja::Ref type = nullptr); + +// Returns the "image name" for a given path. +// /blah/foo/bar/libObjCThing.dylib -> libObjCThing.dylib +std::string BaseFileName(const std::string& path); + +bool IsSameFolderForFile(BinaryNinja::Ref a, BinaryNinja::Ref b); +bool IsSameFolder(BinaryNinja::Ref a, BinaryNinja::Ref b); + +// Represents a range of addresses [start, end). +// Note that `end` is not included within the range. +struct AddressRange +{ + uint64_t start; + uint64_t end; + + AddressRange(uint64_t start, uint64_t end) : start(start), end(end) {} + + AddressRange() : start(0), end(0) {} + + bool Overlaps(const AddressRange& b) const { return start < b.end && b.start < end; } + + bool operator<(const AddressRange& b) const { return start < b.start || (start == b.start && end < b.end); } + + friend bool operator<(const AddressRange& range, uint64_t address) { return range.end <= address; } + + friend bool operator<(uint64_t address, const AddressRange& range) { return address < range.start; } +}; + +// A map keyed by address ranges that can be looked up via any +// address within a range thanks to C++14's transparent comparators. +template +using AddressRangeMap = std::map>; + +// TODO: Document this! +template +class WeakAllocPtr +{ +protected: + std::weak_ptr m_weakPtr; // Weak reference to the object + std::function()> m_allocator; // Function to recreate the object + +public: + explicit WeakAllocPtr(std::function()> allocator) : m_allocator(allocator) {} + + WeakAllocPtr(std::weak_ptr weakPtr, std::function()> allocator) : m_allocator(allocator) + { + if (weakPtr == nullptr) + { + m_weakPtr = {}; + } + else + { + m_weakPtr = weakPtr; + } + } + + std::shared_ptr lock() + { + std::shared_ptr sharedPtr = m_weakPtr.lock(); + if (!sharedPtr) + { + sharedPtr = m_allocator(); + m_weakPtr = sharedPtr; + } + return sharedPtr; + } + + std::shared_ptr lock_no_allocate() { return m_weakPtr.lock(); } +}; -- cgit v1.3.1