Skip to content
Closed
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
6 changes: 6 additions & 0 deletions binaryninjaapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -11430,6 +11430,12 @@ namespace BinaryNinja {
BNExprFolding GetExprFolding(uint64_t addr);
void SetExprFolding(uint64_t addr, BNExprFolding mode);

bool IsConditionInverted(uint64_t addr);
void SetConditionInverted(uint64_t addr, bool invert);

BNEarlyReturn GetEarlyReturn(uint64_t addr);
void SetEarlyReturn(uint64_t addr, BNEarlyReturn mode);

std::map<Variable, std::set<Variable>> GetMergedVariables();
void MergeVariables(const Variable& target, const std::set<Variable>& sources);
void UnmergeVariables(const Variable& target, const std::set<Variable>& sources);
Expand Down
21 changes: 20 additions & 1 deletion binaryninjacore.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
// Current ABI version for linking to the core. This is incremented any time
// there are changes to the API that affect linking, including new functions,
// new types, or modifications to existing functions or types.
#define BN_CURRENT_CORE_ABI_VERSION 108
#define BN_CURRENT_CORE_ABI_VERSION 110

// Minimum ABI version that is supported for loading of plugins. Plugins that
// are linked to an ABI version less than this will not be able to load and
Expand Down Expand Up @@ -1024,6 +1024,12 @@ extern "C"

// HLIL expression can be folded into other expressions or has been folded
HLILFoldableExpr = 0x100,

// HLIL condition can be displayed as the inverse
HLILInvertableCondition = 0x200,

// HLIL condition can be rewritten as an early return
HLILEarlyReturnPossible = 0x400,
} BNILInstructionAttribute;

typedef enum BNIntrinsicClass
Expand Down Expand Up @@ -3238,6 +3244,15 @@ extern "C"
AllowExprFolding
} BNExprFolding;

typedef enum BNEarlyReturn
{
DefaultEarlyReturn,
PreventEarlyReturn,
SmallestSideEarlyReturn,
TrueSideEarlyReturn,
FalseSideEarlyReturn
} BNEarlyReturn;

typedef struct BNDebugFunctionInfo
{
char* shortName;
Expand Down Expand Up @@ -4993,6 +5008,10 @@ extern "C"
BNFunction* func, const BNVariable* var, BNDeadStoreElimination mode);
BINARYNINJACOREAPI BNExprFolding BNGetExprFolding(BNFunction* func, uint64_t addr);
BINARYNINJACOREAPI void BNSetExprFolding(BNFunction* func, uint64_t addr, BNExprFolding mode);
BINARYNINJACOREAPI bool BNIsConditionInverted(BNFunction* func, uint64_t addr);
BINARYNINJACOREAPI void BNSetConditionInverted(BNFunction* func, uint64_t addr, bool invert);
BINARYNINJACOREAPI BNEarlyReturn BNGetEarlyReturn(BNFunction* func, uint64_t addr);
BINARYNINJACOREAPI void BNSetEarlyReturn(BNFunction* func, uint64_t addr, BNEarlyReturn mode);
BINARYNINJACOREAPI BNMergedVariable* BNGetMergedVariables(BNFunction* func, size_t* count);
BINARYNINJACOREAPI void BNFreeMergedVariableList(BNMergedVariable* vars, size_t count);
BINARYNINJACOREAPI void BNMergeVariables(BNFunction* func, const BNVariable* target, const BNVariable* sources,
Expand Down
24 changes: 24 additions & 0 deletions function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2825,6 +2825,30 @@ void Function::SetExprFolding(uint64_t addr, BNExprFolding mode)
}


bool Function::IsConditionInverted(uint64_t addr)
{
return BNIsConditionInverted(m_object, addr);
}


void Function::SetConditionInverted(uint64_t addr, bool invert)
{
BNSetConditionInverted(m_object, addr, invert);
}


BNEarlyReturn Function::GetEarlyReturn(uint64_t addr)
{
return BNGetEarlyReturn(m_object, addr);
}


void Function::SetEarlyReturn(uint64_t addr, BNEarlyReturn mode)
{
BNSetEarlyReturn(m_object, addr, mode);
}


std::map<Variable, std::set<Variable>> Function::GetMergedVariables()
{
size_t count;
Expand Down
6 changes: 6 additions & 0 deletions objectivec/objc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,7 @@ void ObjCProcessor::ReadMethodList(ObjCReader* reader, ClassBase& cls, std::stri
DefineObjCSymbol(DataSymbol, Type::PointerType(m_data->GetAddressSize(), selType),
"selRef_" + method.name, meth.name, true);
}

// workflow objc support
if (selAddr)
m_selToImplementations[selAddr].push_back(meth.imp);
Expand All @@ -967,6 +968,11 @@ void ObjCProcessor::ReadMethodList(ObjCReader* reader, ClassBase& cls, std::stri
method.imp = meth.imp;
cls.methodList[cursor] = method;
m_localMethods[cursor] = method;

if (selAddr)
m_data->AddUserDataReference(selAddr, meth.imp);
if (selRefAddr)
m_data->AddUserDataReference(selRefAddr, meth.imp);
}
catch (...)
{
Expand Down
22 changes: 21 additions & 1 deletion python/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from .enums import (
AnalysisSkipReason, FunctionGraphType, SymbolType, InstructionTextTokenType, HighlightStandardColor,
HighlightColorStyle, DisassemblyOption, IntegerDisplayType, FunctionAnalysisSkipOverride, FunctionUpdateType,
BuiltinType, ExprFolding
BuiltinType, ExprFolding, EarlyReturn
)

from . import associateddatastore # Required in the main scope due to being an argument for _FunctionAssociatedDataStore
Expand Down Expand Up @@ -3466,6 +3466,26 @@ def set_expr_folding(self, addr: Union[int, highlevelil.HighLevelILInstruction],
addr = addr.address
core.BNSetExprFolding(self.handle, addr, value)

def is_condition_inverted(self, addr: Union[int, highlevelil.HighLevelILInstruction]) -> bool:
if isinstance(addr, highlevelil.HighLevelILInstruction):
addr = addr.address
return core.BNIsConditionInverted(self.handle, addr)

def set_condition_inverted(self, addr: Union[int, highlevelil.HighLevelILInstruction], invert: bool):
if isinstance(addr, highlevelil.HighLevelILInstruction):
addr = addr.address
core.BNSetConditionInverted(self.handle, addr, invert)

def get_early_return(self, addr: Union[int, highlevelil.HighLevelILInstruction]) -> EarlyReturn:
if isinstance(addr, highlevelil.HighLevelILInstruction):
addr = addr.address
return EarlyReturn(core.BNGetEarlyReturn(self.handle, addr))

def set_early_return(self, addr: Union[int, highlevelil.HighLevelILInstruction], value: EarlyReturn):
if isinstance(addr, highlevelil.HighLevelILInstruction):
addr = addr.address
core.BNSetEarlyReturn(self.handle, addr, value)


class AdvancedFunctionAnalysisDataRequestor:
def __init__(self, func: Optional['Function'] = None):
Expand Down
2 changes: 2 additions & 0 deletions ui/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ TypeRef GetFunctionType(BinaryViewRef data, TypeRef type);

std::optional<uint64_t> getFoldableExprAddress(
BinaryNinja::HighLevelILFunction* hlil, const HighlightTokenState& highlight);
std::optional<uint64_t> getInvertableConditionAddress(BinaryNinja::HighLevelILFunction* hlil, size_t instrIndex);
std::optional<uint64_t> getEarlyReturnAddress(BinaryNinja::HighLevelILFunction* hlil, size_t instrIndex);

/*!
@}
Expand Down
6 changes: 6 additions & 0 deletions ui/flowgraphwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ class BINARYNINJAUIAPI FlowGraphWidget :
BNDeadStoreElimination getCurrentVariableDeadStoreElimination();
std::optional<uint64_t> getCurrentFoldableExprAddress();
BNExprFolding getCurrentExprFolding();
std::optional<uint64_t> getCurrentInvertableConditionAddress();
bool getCurrentConditionInverted();
std::optional<uint64_t> getCurrentEarlyReturnAddress();
BNEarlyReturn getCurrentEarlyReturn();
std::optional<std::pair<BinaryNinja::Variable, BinaryNinja::Variable>> getMergeVariablesAtCurrentLocation();

protected:
Expand Down Expand Up @@ -398,6 +402,8 @@ class BINARYNINJAUIAPI FlowGraphWidget :

void setCurrentVariableDeadStoreElimination(BNDeadStoreElimination elimination);
void setCurrentExprFolding(BNExprFolding folding);
void toggleConditionInverted();
void setCurrentEarlyReturn(BNEarlyReturn earlyReturn);
void splitToNewTabAndNavigateFromCursorPosition();
void splitToNewWindowAndNavigateFromCursorPosition();
void splitToNewPaneAndNavigateFromCursorPosition();
Expand Down
6 changes: 6 additions & 0 deletions ui/linearview.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,10 @@ class BINARYNINJAUIAPI LinearView : public QAbstractScrollArea, public View, pub
BNDeadStoreElimination getCurrentVariableDeadStoreElimination();
std::optional<uint64_t> getCurrentFoldableExprAddress();
BNExprFolding getCurrentExprFolding();
std::optional<uint64_t> getCurrentInvertableConditionAddress();
bool getCurrentConditionInverted();
std::optional<uint64_t> getCurrentEarlyReturnAddress();
BNEarlyReturn getCurrentEarlyReturn();

void setDataButtonVisible(bool visible);
std::optional<std::pair<BinaryNinja::Variable, BinaryNinja::Variable>> getMergeVariablesAtCurrentLocation();
Expand Down Expand Up @@ -409,6 +413,8 @@ private Q_SLOTS:

void setCurrentVariableDeadStoreElimination(BNDeadStoreElimination elimination);
void setCurrentExprFolding(BNExprFolding folding);
void toggleConditionInverted();
void setCurrentEarlyReturn(BNEarlyReturn earlyReturn);

Q_SIGNALS:
void notifyResizeEvent(int width, int height);
Expand Down
10 changes: 4 additions & 6 deletions view/kernelcache/api/kernelcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ namespace KernelCacheAPI {
return BNKCViewFastGetImageCount(view->GetObject());
}

bool KernelCache::LoadImageWithInstallName(std::string installName)
bool KernelCache::LoadImageWithInstallName(const std::string& installName)
{
char* str = BNAllocString(installName.c_str());
return BNKCViewLoadImageWithInstallName(m_object, str);
return BNKCViewLoadImageWithInstallName(m_object, installName.c_str());
}

bool KernelCache::LoadImageContainingAddress(uint64_t addr)
Expand Down Expand Up @@ -161,10 +160,9 @@ namespace KernelCacheAPI {
return result;
}

std::optional<KernelCacheMachOHeader> KernelCache::GetMachOHeaderForImage(std::string name)
std::optional<KernelCacheMachOHeader> KernelCache::GetMachOHeaderForImage(const std::string& name)
{
char* str = BNAllocString(name.c_str());
char* outputStr = BNKCViewGetImageHeaderForName(m_object, str);
char* outputStr = BNKCViewGetImageHeaderForName(m_object, name.c_str());
if (outputStr == nullptr)
return {};
std::string output = outputStr;
Expand Down
4 changes: 2 additions & 2 deletions view/kernelcache/api/kernelcacheapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ namespace KernelCacheAPI {
static BNKCViewLoadProgress GetLoadProgress(Ref<BinaryView> view);
static uint64_t FastGetImageCount(Ref<BinaryView> view);

bool LoadImageWithInstallName(std::string installName);
bool LoadImageWithInstallName(const std::string& installName);
bool LoadImageContainingAddress(uint64_t addr);
std::vector<std::string> GetAvailableImages();

Expand All @@ -268,7 +268,7 @@ namespace KernelCacheAPI {
std::vector<KCImage> GetImages();
std::vector<KCImage> GetLoadedImages();

std::optional<KernelCacheMachOHeader> GetMachOHeaderForImage(std::string name);
std::optional<KernelCacheMachOHeader> GetMachOHeaderForImage(const std::string& name);
std::optional<KernelCacheMachOHeader> GetMachOHeaderForAddress(uint64_t address);
};
}
4 changes: 2 additions & 2 deletions view/kernelcache/api/kernelcachecore.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ extern "C"

KERNELCACHE_FFI_API char** BNKCViewGetInstallNames(BNKernelCache* cache, size_t* count);

KERNELCACHE_FFI_API bool BNKCViewLoadImageWithInstallName(BNKernelCache* cache, char* name);
KERNELCACHE_FFI_API bool BNKCViewLoadImageWithInstallName(BNKernelCache* cache, const char* name);
KERNELCACHE_FFI_API bool BNKCViewLoadImageContainingAddress(BNKernelCache* cache, uint64_t address);

KERNELCACHE_FFI_API bool BNKCViewIsImageLoaded(BNKernelCache* cache, uint64_t address);
Expand All @@ -128,7 +128,7 @@ extern "C"
KERNELCACHE_FFI_API void BNKCViewFreeLoadedImages(BNKCImage* images, size_t count);

KERNELCACHE_FFI_API char* BNKCViewGetImageHeaderForAddress(BNKernelCache* cache, uint64_t address);
KERNELCACHE_FFI_API char* BNKCViewGetImageHeaderForName(BNKernelCache* cache, char* name);
KERNELCACHE_FFI_API char* BNKCViewGetImageHeaderForName(BNKernelCache* cache, const char* name);

#ifdef __cplusplus
}
Expand Down
1 change: 1 addition & 0 deletions view/kernelcache/api/python/_kernelcachecore_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
core = None
core_platform = platform.system()

from binaryninja._binaryninjacore import BNFreeString, BNFreeStringList, BNAllocString
from binaryninja import Settings
if Settings().get_bool("corePlugins.view.kernelCache"):
from binaryninja._binaryninjacore import BNGetBundledPluginDirectory
Expand Down
15 changes: 3 additions & 12 deletions view/kernelcache/api/python/kernelcache.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,10 @@ def get_macho_header_for_image(self, name: str):
"""
Return a KernelCacheMachOHeader for the image with the given install name.
"""
s = BNAllocString(name)
outputStr = kccore.BNKCViewGetImageHeaderForName(self.handle, s)
outputStr = kccore.BNKCViewGetImageHeaderForName(self.handle, name)
if outputStr is None:
return None
output = outputStr
BNFreeString(outputStr)
if output == "":
return None
return KernelCacheMachOHeader.LoadFromString(output)
return KernelCacheMachOHeader.LoadFromString(outputStr)

def get_macho_header_for_address(self, address: int):
"""
Expand All @@ -224,11 +219,7 @@ def get_macho_header_for_address(self, address: int):
outputStr = kccore.BNKCViewGetImageHeaderForAddress(self.handle, address)
if outputStr is None:
return None
output = outputStr
BNFreeString(outputStr)
if output == "":
return None
return KernelCacheMachOHeader.LoadFromString(output)
return KernelCacheMachOHeader.LoadFromString(outputStr)

@property
def state(self):
Expand Down
7 changes: 2 additions & 5 deletions view/kernelcache/core/KernelCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2145,11 +2145,9 @@ extern "C"
cache->object->ReleaseAPIRef();
}

bool BNKCViewLoadImageWithInstallName(BNKernelCache* cache, char* name)
bool BNKCViewLoadImageWithInstallName(BNKernelCache* cache, const char* name)
{
std::string imageName = std::string(name);
// FIXME !!!!!!!! BNFreeString(name);

if (cache->object)
return cache->object->LoadImageWithInstallName(imageName);

Expand Down Expand Up @@ -2321,10 +2319,9 @@ extern "C"
return nullptr;
}

char* BNKCViewGetImageHeaderForName(BNKernelCache* cache, char* name)
char* BNKCViewGetImageHeaderForName(BNKernelCache* cache, const char* name)
{
std::string imageName = std::string(name);
BNFreeString(name);
if (cache->object)
{
auto header = cache->object->SerializedImageHeaderForName(imageName);
Expand Down
2 changes: 1 addition & 1 deletion view/kernelcache/ui/kctriage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void KCTriageView::loadImagesWithAddr(const std::vector<uint64_t>& addresses) {
{
if (imageLoadTask.IsCancelled())
break;
std::string newLoad = fmt::format("Loading images... ({}/{})", loadedImages++, images.size());
const std::string newLoad = fmt::format("Loading images... ({}/{})", loadedImages++, images.size());
imageLoadTask.SetProgressText(newLoad);
if (m_cache->LoadImageWithInstallName(imageName))
setImageLoaded(addr);
Expand Down
Loading