Skip to content

Commit 9c8d4ea

Browse files
committed
Add UI action and API to control early returns in HLIL
1 parent 37d52c9 commit 9c8d4ea

File tree

7 files changed

+48
-2
lines changed

7 files changed

+48
-2
lines changed

binaryninjaapi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11433,6 +11433,9 @@ namespace BinaryNinja {
1143311433
bool IsConditionInverted(uint64_t addr);
1143411434
void SetConditionInverted(uint64_t addr, bool invert);
1143511435

11436+
BNEarlyReturn GetEarlyReturn(uint64_t addr);
11437+
void SetEarlyReturn(uint64_t addr, BNEarlyReturn mode);
11438+
1143611439
std::map<Variable, std::set<Variable>> GetMergedVariables();
1143711440
void MergeVariables(const Variable& target, const std::set<Variable>& sources);
1143811441
void UnmergeVariables(const Variable& target, const std::set<Variable>& sources);

binaryninjacore.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
// Current ABI version for linking to the core. This is incremented any time
3838
// there are changes to the API that affect linking, including new functions,
3939
// new types, or modifications to existing functions or types.
40-
#define BN_CURRENT_CORE_ABI_VERSION 109
40+
#define BN_CURRENT_CORE_ABI_VERSION 110
4141

4242
// Minimum ABI version that is supported for loading of plugins. Plugins that
4343
// are linked to an ABI version less than this will not be able to load and
@@ -1027,6 +1027,9 @@ extern "C"
10271027

10281028
// HLIL condition can be displayed as the inverse
10291029
HLILInvertableCondition = 0x200,
1030+
1031+
// HLIL condition can be rewritten as an early return
1032+
HLILEarlyReturnPossible = 0x400,
10301033
} BNILInstructionAttribute;
10311034

10321035
typedef enum BNIntrinsicClass
@@ -3241,6 +3244,15 @@ extern "C"
32413244
AllowExprFolding
32423245
} BNExprFolding;
32433246

3247+
typedef enum BNEarlyReturn
3248+
{
3249+
DefaultEarlyReturn,
3250+
PreventEarlyReturn,
3251+
SmallestSideEarlyReturn,
3252+
TrueSideEarlyReturn,
3253+
FalseSideEarlyReturn
3254+
} BNEarlyReturn;
3255+
32443256
typedef struct BNDebugFunctionInfo
32453257
{
32463258
char* shortName;
@@ -4998,6 +5010,8 @@ extern "C"
49985010
BINARYNINJACOREAPI void BNSetExprFolding(BNFunction* func, uint64_t addr, BNExprFolding mode);
49995011
BINARYNINJACOREAPI bool BNIsConditionInverted(BNFunction* func, uint64_t addr);
50005012
BINARYNINJACOREAPI void BNSetConditionInverted(BNFunction* func, uint64_t addr, bool invert);
5013+
BINARYNINJACOREAPI BNEarlyReturn BNGetEarlyReturn(BNFunction* func, uint64_t addr);
5014+
BINARYNINJACOREAPI void BNSetEarlyReturn(BNFunction* func, uint64_t addr, BNEarlyReturn mode);
50015015
BINARYNINJACOREAPI BNMergedVariable* BNGetMergedVariables(BNFunction* func, size_t* count);
50025016
BINARYNINJACOREAPI void BNFreeMergedVariableList(BNMergedVariable* vars, size_t count);
50035017
BINARYNINJACOREAPI void BNMergeVariables(BNFunction* func, const BNVariable* target, const BNVariable* sources,

function.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2837,6 +2837,18 @@ void Function::SetConditionInverted(uint64_t addr, bool invert)
28372837
}
28382838

28392839

2840+
BNEarlyReturn Function::GetEarlyReturn(uint64_t addr)
2841+
{
2842+
return BNGetEarlyReturn(m_object, addr);
2843+
}
2844+
2845+
2846+
void Function::SetEarlyReturn(uint64_t addr, BNEarlyReturn mode)
2847+
{
2848+
BNSetEarlyReturn(m_object, addr, mode);
2849+
}
2850+
2851+
28402852
std::map<Variable, std::set<Variable>> Function::GetMergedVariables()
28412853
{
28422854
size_t count;

python/function.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from .enums import (
3030
AnalysisSkipReason, FunctionGraphType, SymbolType, InstructionTextTokenType, HighlightStandardColor,
3131
HighlightColorStyle, DisassemblyOption, IntegerDisplayType, FunctionAnalysisSkipOverride, FunctionUpdateType,
32-
BuiltinType, ExprFolding
32+
BuiltinType, ExprFolding, EarlyReturn
3333
)
3434

3535
from . import associateddatastore # Required in the main scope due to being an argument for _FunctionAssociatedDataStore
@@ -3476,6 +3476,16 @@ def set_condition_inverted(self, addr: Union[int, highlevelil.HighLevelILInstruc
34763476
addr = addr.address
34773477
core.BNSetConditionInverted(self.handle, addr, invert)
34783478

3479+
def get_early_return(self, addr: Union[int, highlevelil.HighLevelILInstruction]) -> EarlyReturn:
3480+
if isinstance(addr, highlevelil.HighLevelILInstruction):
3481+
addr = addr.address
3482+
return EarlyReturn(core.BNGetEarlyReturn(self.handle, addr))
3483+
3484+
def set_early_return(self, addr: Union[int, highlevelil.HighLevelILInstruction], value: EarlyReturn):
3485+
if isinstance(addr, highlevelil.HighLevelILInstruction):
3486+
addr = addr.address
3487+
core.BNSetEarlyReturn(self.handle, addr, value)
3488+
34793489

34803490
class AdvancedFunctionAnalysisDataRequestor:
34813491
def __init__(self, func: Optional['Function'] = None):

ui/commands.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ TypeRef GetFunctionType(BinaryViewRef data, TypeRef type);
9898
std::optional<uint64_t> getFoldableExprAddress(
9999
BinaryNinja::HighLevelILFunction* hlil, const HighlightTokenState& highlight);
100100
std::optional<uint64_t> getInvertableConditionAddress(BinaryNinja::HighLevelILFunction* hlil, size_t instrIndex);
101+
std::optional<uint64_t> getEarlyReturnAddress(BinaryNinja::HighLevelILFunction* hlil, size_t instrIndex);
101102

102103
/*!
103104
@}

ui/flowgraphwidget.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ class BINARYNINJAUIAPI FlowGraphWidget :
170170
BNExprFolding getCurrentExprFolding();
171171
std::optional<uint64_t> getCurrentInvertableConditionAddress();
172172
bool getCurrentConditionInverted();
173+
std::optional<uint64_t> getCurrentEarlyReturnAddress();
174+
BNEarlyReturn getCurrentEarlyReturn();
173175
std::optional<std::pair<BinaryNinja::Variable, BinaryNinja::Variable>> getMergeVariablesAtCurrentLocation();
174176

175177
protected:
@@ -401,6 +403,7 @@ class BINARYNINJAUIAPI FlowGraphWidget :
401403
void setCurrentVariableDeadStoreElimination(BNDeadStoreElimination elimination);
402404
void setCurrentExprFolding(BNExprFolding folding);
403405
void toggleConditionInverted();
406+
void setCurrentEarlyReturn(BNEarlyReturn earlyReturn);
404407
void splitToNewTabAndNavigateFromCursorPosition();
405408
void splitToNewWindowAndNavigateFromCursorPosition();
406409
void splitToNewPaneAndNavigateFromCursorPosition();

ui/linearview.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ class BINARYNINJAUIAPI LinearView : public QAbstractScrollArea, public View, pub
320320
BNExprFolding getCurrentExprFolding();
321321
std::optional<uint64_t> getCurrentInvertableConditionAddress();
322322
bool getCurrentConditionInverted();
323+
std::optional<uint64_t> getCurrentEarlyReturnAddress();
324+
BNEarlyReturn getCurrentEarlyReturn();
323325

324326
void setDataButtonVisible(bool visible);
325327
std::optional<std::pair<BinaryNinja::Variable, BinaryNinja::Variable>> getMergeVariablesAtCurrentLocation();
@@ -412,6 +414,7 @@ private Q_SLOTS:
412414
void setCurrentVariableDeadStoreElimination(BNDeadStoreElimination elimination);
413415
void setCurrentExprFolding(BNExprFolding folding);
414416
void toggleConditionInverted();
417+
void setCurrentEarlyReturn(BNEarlyReturn earlyReturn);
415418

416419
Q_SIGNALS:
417420
void notifyResizeEvent(int width, int height);

0 commit comments

Comments
 (0)