Skip to content

Commit 0245b2c

Browse files
committed
Let calling conventions opt out of heuristics
1 parent f8feaa5 commit 0245b2c

4 files changed

Lines changed: 35 additions & 0 deletions

File tree

binaryninjaapi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4639,6 +4639,7 @@ __attribute__ ((format (printf, 1, 2)))
46394639
static bool AreArgumentRegistersSharedIndexCallback(void* ctxt);
46404640
static bool IsStackReservedForArgumentRegistersCallback(void* ctxt);
46414641
static bool IsStackAdjustedOnReturnCallback(void* ctxt);
4642+
static bool IsEligibleForHeuristicsCallback(void* ctxt);
46424643

46434644
static uint32_t GetIntegerReturnValueRegisterCallback(void* ctxt);
46444645
static uint32_t GetHighIntegerReturnValueRegisterCallback(void* ctxt);
@@ -4666,6 +4667,7 @@ __attribute__ ((format (printf, 1, 2)))
46664667
virtual bool AreArgumentRegistersSharedIndex();
46674668
virtual bool IsStackReservedForArgumentRegisters();
46684669
virtual bool IsStackAdjustedOnReturn();
4670+
virtual bool IsEligibleForHeuristics();
46694671

46704672
virtual uint32_t GetIntegerReturnValueRegister() = 0;
46714673
virtual uint32_t GetHighIntegerReturnValueRegister();
@@ -4693,6 +4695,7 @@ __attribute__ ((format (printf, 1, 2)))
46934695
virtual bool AreArgumentRegistersSharedIndex() override;
46944696
virtual bool IsStackReservedForArgumentRegisters() override;
46954697
virtual bool IsStackAdjustedOnReturn() override;
4698+
virtual bool IsEligibleForHeuristics() override;
46964699

46974700
virtual uint32_t GetIntegerReturnValueRegister() override;
46984701
virtual uint32_t GetHighIntegerReturnValueRegister() override;

binaryninjacore.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1948,6 +1948,7 @@ extern "C"
19481948
bool (*areArgumentRegistersSharedIndex)(void* ctxt);
19491949
bool (*isStackReservedForArgumentRegisters)(void* ctxt);
19501950
bool (*isStackAdjustedOnReturn)(void* ctxt);
1951+
bool (*isEligibleForHeuristics)(void* ctxt);
19511952

19521953
uint32_t (*getIntegerReturnValueRegister)(void* ctxt);
19531954
uint32_t (*getHighIntegerReturnValueRegister)(void* ctxt);
@@ -4428,6 +4429,7 @@ __attribute__ ((format (printf, 1, 2)))
44284429
BINARYNINJACOREAPI bool BNAreArgumentRegistersSharedIndex(BNCallingConvention* cc);
44294430
BINARYNINJACOREAPI bool BNIsStackReservedForArgumentRegisters(BNCallingConvention* cc);
44304431
BINARYNINJACOREAPI bool BNIsStackAdjustedOnReturn(BNCallingConvention* cc);
4432+
BINARYNINJACOREAPI bool BNIsEligibleForHeuristics(BNCallingConvention* cc);
44314433

44324434
BINARYNINJACOREAPI uint32_t BNGetIntegerReturnValueRegister(BNCallingConvention* cc);
44334435
BINARYNINJACOREAPI uint32_t BNGetHighIntegerReturnValueRegister(BNCallingConvention* cc);

callingconvention.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ CallingConvention::CallingConvention(Architecture* arch, const string& name)
4343
cc.areArgumentRegistersSharedIndex = AreArgumentRegistersSharedIndexCallback;
4444
cc.isStackReservedForArgumentRegisters = IsStackReservedForArgumentRegistersCallback;
4545
cc.isStackAdjustedOnReturn = IsStackAdjustedOnReturnCallback;
46+
cc.isEligibleForHeuristics = IsEligibleForHeuristicsCallback;
4647
cc.getIntegerReturnValueRegister = GetIntegerReturnValueRegisterCallback;
4748
cc.getHighIntegerReturnValueRegister = GetHighIntegerReturnValueRegisterCallback;
4849
cc.getFloatReturnValueRegister = GetFloatReturnValueRegisterCallback;
@@ -144,6 +145,13 @@ bool CallingConvention::IsStackAdjustedOnReturnCallback(void* ctxt)
144145
}
145146

146147

148+
bool CallingConvention::IsEligibleForHeuristicsCallback(void* ctxt)
149+
{
150+
CallingConvention* cc = (CallingConvention*)ctxt;
151+
return cc->IsEligibleForHeuristics();
152+
}
153+
154+
147155
uint32_t CallingConvention::GetIntegerReturnValueRegisterCallback(void* ctxt)
148156
{
149157
CallingConvention* cc = (CallingConvention*)ctxt;
@@ -284,6 +292,12 @@ bool CallingConvention::IsStackAdjustedOnReturn()
284292
}
285293

286294

295+
bool CallingConvention::IsEligibleForHeuristics()
296+
{
297+
return true;
298+
}
299+
300+
287301
uint32_t CallingConvention::GetHighIntegerReturnValueRegister()
288302
{
289303
return BN_INVALID_REGISTER;
@@ -407,6 +421,12 @@ bool CoreCallingConvention::IsStackAdjustedOnReturn()
407421
}
408422

409423

424+
bool CoreCallingConvention::IsEligibleForHeuristics()
425+
{
426+
return BNIsEligibleForHeuristics(m_object);
427+
}
428+
429+
410430
uint32_t CoreCallingConvention::GetIntegerReturnValueRegister()
411431
{
412432
return BNGetIntegerReturnValueRegister(m_object);

python/callingconvention.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class CallingConvention(object):
4040
arg_regs_share_index = False
4141
stack_reserved_for_arg_regs = False
4242
stack_adjusted_on_return = False
43+
eligible_for_heuristics = True
4344
int_return_reg = None
4445
high_int_return_reg = None
4546
float_return_reg = None
@@ -65,6 +66,7 @@ def __init__(self, arch=None, name=None, handle=None, confidence=binaryninja.typ
6566
self._cb.areArgumentRegistersSharedIndex = self._cb.areArgumentRegistersSharedIndex.__class__(self._arg_regs_share_index)
6667
self._cb.isStackReservedForArgumentRegisters = self._cb.isStackReservedForArgumentRegisters.__class__(self._stack_reserved_for_arg_regs)
6768
self._cb.isStackAdjustedOnReturn = self._cb.isStackAdjustedOnReturn.__class__(self._stack_adjusted_on_return)
69+
self._cb.isEligibleForHeuristics = self._cb.isEligibleForHeuristics.__class__(self._eligible_for_heuristics)
6870
self._cb.getIntegerReturnValueRegister = self._cb.getIntegerReturnValueRegister.__class__(self._get_int_return_reg)
6971
self._cb.getHighIntegerReturnValueRegister = self._cb.getHighIntegerReturnValueRegister.__class__(self._get_high_int_return_reg)
7072
self._cb.getFloatReturnValueRegister = self._cb.getFloatReturnValueRegister.__class__(self._get_float_return_reg)
@@ -83,6 +85,7 @@ def __init__(self, arch=None, name=None, handle=None, confidence=binaryninja.typ
8385
self.__dict__["arg_regs_share_index"] = core.BNAreArgumentRegistersSharedIndex(self.handle)
8486
self.__dict__["stack_reserved_for_arg_regs"] = core.BNIsStackReservedForArgumentRegisters(self.handle)
8587
self.__dict__["stack_adjusted_on_return"] = core.BNIsStackAdjustedOnReturn(self.handle)
88+
self.__dict__["eligible_for_heuristics"] = core.BNIsEligibleForHeuristics(self.handle)
8689

8790
count = ctypes.c_ulonglong()
8891
regs = core.BNGetCallerSavedRegisters(self.handle, count)
@@ -268,6 +271,13 @@ def _stack_adjusted_on_return(self, ctxt):
268271
log.log_error(traceback.format_exc())
269272
return False
270273

274+
def _eligible_for_heuristics(self, ctxt):
275+
try:
276+
return self.__class__.eligible_for_heuristics
277+
except:
278+
log.log_error(traceback.format_exc())
279+
return False
280+
271281
def _get_int_return_reg(self, ctxt):
272282
try:
273283
return self.arch.regs[self.__class__.int_return_reg].index

0 commit comments

Comments
 (0)