Skip to content
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
573 changes: 573 additions & 0 deletions ui/backgroundsortfilterrows.h

Large diffs are not rendered by default.

68 changes: 68 additions & 0 deletions view/sharedcache/api/python/sharedcache.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,71 @@ def image_to_api(image: CacheImage) -> sccore.BNSharedCacheImage:
regionStarts=core_region_starts
)

@dataclasses.dataclass
class CacheString:
string_type: sccore.StringTypeEnum
address: int
raw_length: int
text: str
region_start: int
image_start: int

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In sharedcache.cpp, you state that "A zeroed imageStart means the region is not associated with an image". Should this detail be surfaced to Python as well in some capacity (even if just a doc comment)?


def __str__(self):
return repr(self)

def __repr__(self):
return f"<CacheString 0x{self.address:x}: {self.text!r}>"


def string_from_api(string: sccore.BNSharedCacheString) -> CacheString:
return CacheString(
string_type=string.stringType,
address=string.address,
raw_length=string.rawLength,
text=string.text,
region_start=string.regionStart,
image_start=string.imageStart
)


class CacheStringScanner:
def __init__(self, handle: sccore.BNSharedCacheStringScannerHandle):
self.handle = handle

def __del__(self):
if self.handle is not None:
sccore.BNFreeSharedCacheStringScanner(self.handle)

def start(self) -> bool:
return sccore.BNSharedCacheStringScannerStart(self.handle)

@property
def is_complete(self) -> bool:
return sccore.BNSharedCacheStringScannerIsComplete(self.handle)

@property
def progress(self) -> (int, int):
current = ctypes.c_ulonglong()
total = ctypes.c_ulonglong()
sccore.BNSharedCacheStringScannerGetProgress(self.handle, current, total)
return current.value, total.value

@property
def string_count(self) -> int:
return sccore.BNSharedCacheStringScannerGetStringCount(self.handle)

def take_strings(self, max_count: int = 0xffffffffffffffff) -> [CacheString]:
count = ctypes.c_ulonglong()
value = sccore.BNSharedCacheStringScannerTakeStrings(self.handle, max_count, count)
if value is None:
return []
result = []
for i in range(count.value):
result.append(string_from_api(value[i]))
sccore.BNSharedCacheFreeStringList(value, count)
return result


def symbol_from_api(symbol: sccore.BNSharedCacheSymbol) -> CacheSymbol:
return CacheSymbol(
symbol_type=symbol.symbolType,
Expand Down Expand Up @@ -291,6 +356,9 @@ def symbols(self) -> [CacheSymbol]:
sccore.BNSharedCacheFreeSymbolList(value, count)
return result

def create_string_scanner(self) -> CacheStringScanner:
return CacheStringScanner(sccore.BNSharedCacheControllerCreateStringScanner(self.handle))


def _get_shared_cache(instance: binaryninja.PythonScriptingInstance):
if instance.interpreter.active_view is None:
Expand Down
7 changes: 7 additions & 0 deletions view/sharedcache/api/python/sharedcache_enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ class SharedCacheRegionType(enum.IntEnum):
SharedCacheRegionTypeNonImage = 3


class StringType(enum.IntEnum):
AsciiString = 0
Utf16String = 1
Utf32String = 2
Utf8String = 3


class SymbolBinding(enum.IntEnum):
NoBinding = 0
LocalBinding = 1
Expand Down
90 changes: 90 additions & 0 deletions view/sharedcache/api/sharedcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ CacheRegion RegionFromApi(BNSharedCacheRegion apiRegion)
region.size = apiRegion.size;
region.flags = apiRegion.flags;
region.type = apiRegion.regionType;
// A zeroed imageStart means the region is not associated with an image.
if (apiRegion.imageStart != 0)
region.imageStart = apiRegion.imageStart;
return region;
}

Expand Down Expand Up @@ -111,6 +114,19 @@ CacheSymbol SymbolFromApi(BNSharedCacheSymbol apiSymbol)
return symbol;
}

CacheString StringFromApi(const BNSharedCacheString& apiString)
{
CacheString string;
string.type = apiString.stringType;
string.address = apiString.address;
string.rawLength = apiString.rawLength;
string.text = apiString.text;
string.regionStart = apiString.regionStart;
if (apiString.imageStart != 0)
string.imageStart = apiString.imageStart;
return string;
}

std::string SharedCacheAPI::GetRegionTypeAsString(const BNSharedCacheRegionType &type)
{
switch (type)
Expand Down Expand Up @@ -359,3 +375,77 @@ std::vector<CacheSymbol> SharedCacheController::GetSymbols() const
BNSharedCacheFreeSymbolList(symbols, count);
return result;
}

CacheStringScanner::CacheStringScanner(BNSharedCacheStringScanner* scanner) : m_object(scanner) {}


CacheStringScanner::~CacheStringScanner()
{
if (m_object)
BNFreeSharedCacheStringScanner(m_object);
}


CacheStringScanner::CacheStringScanner(CacheStringScanner&& other) noexcept : m_object(other.m_object)
{
other.m_object = nullptr;
}


CacheStringScanner& CacheStringScanner::operator=(CacheStringScanner&& other) noexcept
{
if (this != &other)
{
if (m_object)
BNFreeSharedCacheStringScanner(m_object);
m_object = other.m_object;
other.m_object = nullptr;
}
return *this;
}


bool CacheStringScanner::Start()
{
return BNSharedCacheStringScannerStart(m_object);
}


bool CacheStringScanner::IsComplete() const
{
return BNSharedCacheStringScannerIsComplete(m_object);
}


std::pair<uint64_t, uint64_t> CacheStringScanner::GetProgress() const
{
uint64_t current = 0;
uint64_t total = 0;
BNSharedCacheStringScannerGetProgress(m_object, &current, &total);
return {current, total};
}


uint64_t CacheStringScanner::GetStringCount() const
{
return BNSharedCacheStringScannerGetStringCount(m_object);
}


std::vector<CacheString> CacheStringScanner::TakeStrings(uint64_t maxCount)
{
size_t count;
BNSharedCacheString* strings = BNSharedCacheStringScannerTakeStrings(m_object, maxCount, &count);
std::vector<CacheString> result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.emplace_back(StringFromApi(strings[i]));
BNSharedCacheFreeStringList(strings, count);
return result;
}


std::unique_ptr<CacheStringScanner> SharedCacheController::CreateStringScanner() const
{
return std::make_unique<CacheStringScanner>(BNSharedCacheControllerCreateStringScanner(m_object));
}
36 changes: 36 additions & 0 deletions view/sharedcache/api/sharedcacheapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <binaryninjaapi.h>
#include "sharedcachecore.h"

#include <memory>

template<class T>
class DSCRefCountObject {
void AddRefInternal() { m_refs.fetch_add(1); }
Expand Down Expand Up @@ -296,6 +298,38 @@ namespace SharedCacheAPI {

std::string GetSymbolTypeAsString(const BNSymbolType& type);

struct CacheString
{
BNStringType type;
uint64_t address;
// Length of the string in the cache, in bytes.
size_t rawLength;
// UTF-8 display text, truncated.
std::string text;
uint64_t regionStart;
std::optional<uint64_t> imageStart;
};

class CacheStringScanner
{
BNSharedCacheStringScanner* m_object = nullptr;

public:
explicit CacheStringScanner(BNSharedCacheStringScanner* scanner);
~CacheStringScanner();

CacheStringScanner(const CacheStringScanner&) = delete;
CacheStringScanner& operator=(const CacheStringScanner&) = delete;
CacheStringScanner(CacheStringScanner&& other) noexcept;
CacheStringScanner& operator=(CacheStringScanner&& other) noexcept;

bool Start();
bool IsComplete() const;
std::pair<uint64_t, uint64_t> GetProgress() const;
uint64_t GetStringCount() const;
std::vector<CacheString> TakeStrings(uint64_t maxCount);
};

class SharedCacheController : public DSCCoreRefCountObject<BNSharedCacheController, BNNewSharedCacheControllerReference, BNFreeSharedCacheControllerReference> {
public:
explicit SharedCacheController(BNSharedCacheController* controller);
Expand Down Expand Up @@ -330,5 +364,7 @@ namespace SharedCacheAPI {
std::vector<CacheImage> GetImages() const;
std::vector<CacheImage> GetLoadedImages() const;
std::vector<CacheSymbol> GetSymbols() const;

std::unique_ptr<CacheStringScanner> CreateStringScanner() const;
};
}
37 changes: 37 additions & 0 deletions view/sharedcache/api/sharedcachecore.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,19 @@ extern "C"
GlobalBinding = 2,
WeakBinding = 3,
};

enum BNStringType : uint8_t
{
AsciiString = 0,
Utf16String = 1,
Utf32String = 2,
Utf8String = 3,
};
#endif

typedef struct BNBinaryView BNBinaryView;
typedef struct BNSharedCacheController BNSharedCacheController;
typedef struct BNSharedCacheStringScanner BNSharedCacheStringScanner;

typedef enum BNSharedCacheEntryType {
SharedCacheEntryTypePrimary,
Expand Down Expand Up @@ -119,6 +128,18 @@ extern "C"
char* name;
} BNSharedCacheSymbol;

typedef struct BNSharedCacheString {
BNStringType stringType;
uint64_t address;
// Length of the string in the cache, in bytes.
size_t rawLength;
// UTF-8 display text, truncated.
char* text;
uint64_t regionStart;
// NOTE: If not associated with an image this will be zero.
uint64_t imageStart;
} BNSharedCacheString;

SHAREDCACHE_FFI_API BNSharedCacheController* BNGetSharedCacheController(BNBinaryView* data);

SHAREDCACHE_FFI_API BNSharedCacheController* BNNewSharedCacheControllerReference(BNSharedCacheController* controller);
Expand Down Expand Up @@ -166,6 +187,22 @@ extern "C"
SHAREDCACHE_FFI_API void BNSharedCacheFreeEntry(BNSharedCacheEntry entry);
SHAREDCACHE_FFI_API void BNSharedCacheFreeEntryList(BNSharedCacheEntry* entries, size_t count);

SHAREDCACHE_FFI_API BNSharedCacheStringScanner* BNSharedCacheControllerCreateStringScanner(
BNSharedCacheController* controller);
SHAREDCACHE_FFI_API void BNFreeSharedCacheStringScanner(BNSharedCacheStringScanner* scanner);
SHAREDCACHE_FFI_API bool BNSharedCacheStringScannerStart(BNSharedCacheStringScanner* scanner);
SHAREDCACHE_FFI_API bool BNSharedCacheStringScannerIsComplete(BNSharedCacheStringScanner* scanner);
SHAREDCACHE_FFI_API void BNSharedCacheStringScannerGetProgress(
BNSharedCacheStringScanner* scanner, uint64_t* current, uint64_t* total);

SHAREDCACHE_FFI_API uint64_t BNSharedCacheStringScannerGetStringCount(BNSharedCacheStringScanner* scanner);
// Removes and returns up to maxCount of the queued scan results.
SHAREDCACHE_FFI_API BNSharedCacheString* BNSharedCacheStringScannerTakeStrings(
BNSharedCacheStringScanner* scanner, uint64_t maxCount, size_t* count);

SHAREDCACHE_FFI_API void BNSharedCacheFreeString(BNSharedCacheString string);
SHAREDCACHE_FFI_API void BNSharedCacheFreeStringList(BNSharedCacheString* strings, size_t count);


#ifdef __cplusplus
}
Expand Down
Loading