From 3d403cfae9d5a366f112c8a5936a371a01cfd230 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Mon, 10 Jul 2017 21:40:51 -0400 Subject: Add confidence levels to type objects --- python/lowlevelil.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'python/lowlevelil.py') diff --git a/python/lowlevelil.py b/python/lowlevelil.py index c359a79c..62e33a75 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -309,8 +309,9 @@ class LowLevelILInstruction(object): size = tokens[i].size operand = tokens[i].operand context = tokens[i].context + confidence = tokens[i].confidence address = tokens[i].address - result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address)) + result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) core.BNFreeInstructionText(tokens, count.value) return result -- cgit v1.3.1 From bf9014621643585efed73386ed3e00067cf3ce17 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Sat, 15 Jul 2017 14:17:03 -0400 Subject: Add flags option to LLIL store --- python/lowlevelil.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'python/lowlevelil.py') diff --git a/python/lowlevelil.py b/python/lowlevelil.py index c359a79c..33a85a97 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -722,17 +722,18 @@ class LowLevelILFunction(object): """ return self.expr(LowLevelILOperation.LLIL_LOAD, addr.index, size=size) - def store(self, size, addr, value): + def store(self, size, addr, value, flags=None): """ ``store`` Writes ``size`` bytes to expression ``addr`` read from expression ``value`` :param int size: number of bytes to write :param LowLevelILExpr addr: the expression to write to :param LowLevelILExpr value: the expression to be written + :param str flags: which flags are set by this operation :return: The expression ``[addr].size = value`` :rtype: LowLevelILExpr """ - return self.expr(LowLevelILOperation.LLIL_STORE, addr.index, value.index, size=size) + return self.expr(LowLevelILOperation.LLIL_STORE, addr.index, value.index, size=size, flags=flags) def push(self, size, value): """ -- cgit v1.3.1 From 24b090492a216278fbc0e43e8f01cec13fa59696 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Tue, 25 Jul 2017 20:20:24 -0400 Subject: Add mappings from LLIL to normal MLIL --- binaryninjaapi.h | 2 ++ binaryninjacore.h | 2 ++ lowlevelil.cpp | 12 ++++++++++++ python/lowlevelil.py | 28 +++++++++++++++++++++++++++- 4 files changed, 43 insertions(+), 1 deletion(-) (limited to 'python/lowlevelil.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 83d12d21..d69fec0d 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2464,6 +2464,8 @@ namespace BinaryNinja Ref GetMediumLevelIL() const; Ref GetMappedMediumLevelIL() const; + size_t GetMediumLevelILInstructionIndex(size_t instr) const; + size_t GetMediumLevelILExprIndex(size_t expr) const; size_t GetMappedMediumLevelILInstructionIndex(size_t instr) const; size_t GetMappedMediumLevelILExprIndex(size_t expr) const; }; diff --git a/binaryninjacore.h b/binaryninjacore.h index 01c78ff4..bcd5fbbf 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -2386,6 +2386,8 @@ extern "C" BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMediumLevelILForLowLevelIL(BNLowLevelILFunction* func); BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMappedMediumLevelIL(BNLowLevelILFunction* func); + BINARYNINJACOREAPI size_t BNGetMediumLevelILInstructionIndex(BNLowLevelILFunction* func, size_t instr); + BINARYNINJACOREAPI size_t BNGetMediumLevelILExprIndex(BNLowLevelILFunction* func, size_t expr); BINARYNINJACOREAPI size_t BNGetMappedMediumLevelILInstructionIndex(BNLowLevelILFunction* func, size_t instr); BINARYNINJACOREAPI size_t BNGetMappedMediumLevelILExprIndex(BNLowLevelILFunction* func, size_t expr); diff --git a/lowlevelil.cpp b/lowlevelil.cpp index 4ff16a05..0cb733ac 100644 --- a/lowlevelil.cpp +++ b/lowlevelil.cpp @@ -955,6 +955,18 @@ Ref LowLevelILFunction::GetMappedMediumLevelIL() const } +size_t LowLevelILFunction::GetMediumLevelILInstructionIndex(size_t instr) const +{ + return BNGetMediumLevelILInstructionIndex(m_object, instr); +} + + +size_t LowLevelILFunction::GetMediumLevelILExprIndex(size_t expr) const +{ + return BNGetMediumLevelILExprIndex(m_object, expr); +} + + size_t LowLevelILFunction::GetMappedMediumLevelILInstructionIndex(size_t instr) const { return BNGetMappedMediumLevelILInstructionIndex(m_object, instr); diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 62e33a75..08ca04e6 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -327,9 +327,17 @@ class LowLevelILInstruction(object): return LowLevelILInstruction(self.function.non_ssa_form, core.BNGetLowLevelILNonSSAExprIndex(self.function.handle, self.expr_index)) + @property + def medium_level_il(self): + """Gets the medium level IL expression corresponding to this expression (may be None for eliminated instructions)""" + expr = self.function.get_medium_level_il_expr_index(self.expr_index) + if expr is None: + return None + return mediumlevelil.MediumLevelILInstruction(self.function.medium_level_il, expr) + @property def mapped_medium_level_il(self): - """Gets the medium level IL expression corresponding to this expression""" + """Gets the mapped medium level IL expression corresponding to this expression""" expr = self.function.get_mapped_medium_level_il_expr_index(self.expr_index) if expr is None: return None @@ -1652,6 +1660,24 @@ class LowLevelILFunction(object): result = function.RegisterValue(self.arch, value) return result + def get_medium_level_il_instruction_index(self, instr): + med_il = self.medium_level_il + if med_il is None: + return None + result = core.BNGetMediumLevelILInstructionIndex(self.handle, instr) + if result >= core.BNGetMediumLevelILInstructionCount(med_il.handle): + return None + return result + + def get_medium_level_il_expr_index(self, expr): + med_il = self.medium_level_il + if med_il is None: + return None + result = core.BNGetMediumLevelILExprIndex(self.handle, expr) + if result >= core.BNGetMediumLevelILExprCount(med_il.handle): + return None + return result + def get_mapped_medium_level_il_instruction_index(self, instr): med_il = self.mapped_medium_level_il if med_il is None: -- cgit v1.3.1 From 22edfd701bff068067b43a8e6a682202d19ce122 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Tue, 8 Aug 2017 23:55:48 -0400 Subject: Fixing llil and mlil incoming/outgoing edges, and dominator apis --- python/basicblock.py | 18 +++++++++++------- python/lowlevelil.py | 3 +++ python/mediumlevelil.py | 4 ++++ 3 files changed, 18 insertions(+), 7 deletions(-) (limited to 'python/lowlevelil.py') diff --git a/python/basicblock.py b/python/basicblock.py index fc7a870e..9ecf90d0 100644 --- a/python/basicblock.py +++ b/python/basicblock.py @@ -64,6 +64,10 @@ class BasicBlock(object): return True return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents) + def _create_instance(self, view, handle): + """Internal method used to instantiante child instances""" + return BasicBlock(view, handle) + @property def function(self): """Basic block function (read-only)""" @@ -117,7 +121,7 @@ class BasicBlock(object): for i in xrange(0, count.value): branch_type = BranchType(edges[i].type) if edges[i].target: - target = BasicBlock(self.view, core.BNNewBasicBlockReference(edges[i].target)) + target = self._create_instance(self.view, core.BNNewBasicBlockReference(edges[i].target)) else: target = None result.append(BasicBlockEdge(branch_type, self, target, edges[i].backEdge)) @@ -133,7 +137,7 @@ class BasicBlock(object): for i in xrange(0, count.value): branch_type = BranchType(edges[i].type) if edges[i].target: - target = BasicBlock(self.view, core.BNNewBasicBlockReference(edges[i].target)) + target = self._create_instance(self.view, core.BNNewBasicBlockReference(edges[i].target)) else: target = None result.append(BasicBlockEdge(branch_type, self, target, edges[i].backEdge)) @@ -152,7 +156,7 @@ class BasicBlock(object): blocks = core.BNGetBasicBlockDominators(self.handle, count) result = [] for i in xrange(0, count.value): - result.append(BasicBlock(self.view, core.BNNewBasicBlockReference(blocks[i]))) + result.append(self._create_instance(self.view, core.BNNewBasicBlockReference(blocks[i]))) core.BNFreeBasicBlockList(blocks, count.value) return result @@ -163,7 +167,7 @@ class BasicBlock(object): blocks = core.BNGetBasicBlockStrictDominators(self.handle, count) result = [] for i in xrange(0, count.value): - result.append(BasicBlock(self.view, core.BNNewBasicBlockReference(blocks[i]))) + result.append(self._create_instance(self.view, core.BNNewBasicBlockReference(blocks[i]))) core.BNFreeBasicBlockList(blocks, count.value) return result @@ -173,7 +177,7 @@ class BasicBlock(object): result = core.BNGetBasicBlockImmediateDominator(self.handle) if not result: return None - return BasicBlock(self.view, result) + return self._create_instance(self.view, result) @property def dominator_tree_children(self): @@ -182,7 +186,7 @@ class BasicBlock(object): blocks = core.BNGetBasicBlockDominatorTreeChildren(self.handle, count) result = [] for i in xrange(0, count.value): - result.append(BasicBlock(self.view, core.BNNewBasicBlockReference(blocks[i]))) + result.append(self._create_instance(self.view, core.BNNewBasicBlockReference(blocks[i]))) core.BNFreeBasicBlockList(blocks, count.value) return result @@ -193,7 +197,7 @@ class BasicBlock(object): blocks = core.BNGetBasicBlockDominanceFrontier(self.handle, count) result = [] for i in xrange(0, count.value): - result.append(BasicBlock(self.view, core.BNNewBasicBlockReference(blocks[i]))) + result.append(self._create_instance(self.view, core.BNNewBasicBlockReference(blocks[i]))) core.BNFreeBasicBlockList(blocks, count.value) return result diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 9f532e6f..e50f80c6 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -1716,6 +1716,9 @@ class LowLevelILBasicBlock(basicblock.BasicBlock): else: return self.il_function[self.end + idx] + def _create_instance(self, view, handle): + """Internal method by super to instantiante child instances""" + return LowLevelILBasicBlock(view, handle, self.il_function) def LLIL_TEMP(n): return n | 0x80000000 diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index feca0937..c837aa42 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -885,3 +885,7 @@ class MediumLevelILBasicBlock(basicblock.BasicBlock): return self.il_function[idx + self.start] else: return self.il_function[self.end + idx] + + def _create_instance(self, view, handle): + """Internal method by super to instantiante child instances""" + return MediumLevelILBasicBlock(view, handle, self.il_function) -- cgit v1.3.1 From 47333ef2460edfa9b5ba5be26fd19f80c0d8d8b6 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Tue, 29 Aug 2017 20:13:57 -0400 Subject: Updating APIs to deal with stack adjustment --- binaryninjaapi.h | 5 ++++- binaryninjacore.h | 4 +++- lowlevelilinstruction.cpp | 27 +++++++++++++++++++++++++-- lowlevelilinstruction.h | 8 ++++++++ python/lowlevelil.py | 13 +++++++++++++ python/types.py | 19 +++++++++++++++++-- type.cpp | 16 ++++++++++++++-- 7 files changed, 84 insertions(+), 8 deletions(-) (limited to 'python/lowlevelil.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 5fb95021..1ac60625 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1872,6 +1872,7 @@ namespace BinaryNinja void SetConst(const Confidence& cnst); void SetVolatile(const Confidence& vltl); void SetTypeName(const QualifiedName& name); + Confidence GetStackAdjustment() const; uint64_t GetElementCount() const; uint64_t GetOffset() const; @@ -1911,7 +1912,8 @@ namespace BinaryNinja static Ref ArrayType(const Confidence>& type, uint64_t elem); static Ref FunctionType(const Confidence>& returnValue, const Confidence>& callingConvention, - const std::vector& params, const Confidence& varArg = Confidence(false, 0)); + const std::vector& params, const Confidence& varArg = Confidence(false, 0), + const Confidence& stackAdjust = Confidence(0, 0)); static std::string GenerateAutoTypeId(const std::string& source, const QualifiedName& name); static std::string GenerateAutoDemangledTypeId(const QualifiedName& name); @@ -2517,6 +2519,7 @@ namespace BinaryNinja ExprId JumpTo(ExprId dest, const std::vector& targets, const ILSourceLocation& loc = ILSourceLocation()); ExprId Call(ExprId dest, const ILSourceLocation& loc = ILSourceLocation()); + ExprId CallStackAdjust(ExprId dest, size_t adjust, const ILSourceLocation& loc = ILSourceLocation()); ExprId CallSSA(const std::vector& output, ExprId dest, const std::vector& params, const SSARegister& stack, size_t newMemoryVer, size_t prevMemoryVer, const ILSourceLocation& loc = ILSourceLocation()); diff --git a/binaryninjacore.h b/binaryninjacore.h index f20cc1f2..1bb4c726 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -323,6 +323,7 @@ extern "C" LLIL_JUMP, LLIL_JUMP_TO, LLIL_CALL, + LLIL_CALL_STACK_ADJUST, LLIL_RET, LLIL_NORET, LLIL_IF, @@ -2655,7 +2656,7 @@ extern "C" BINARYNINJACOREAPI BNType* BNCreateArrayType(BNTypeWithConfidence* type, uint64_t elem); BINARYNINJACOREAPI BNType* BNCreateFunctionType(BNTypeWithConfidence* returnValue, BNCallingConventionWithConfidence* callingConvention, BNFunctionParameter* params, - size_t paramCount, BNBoolWithConfidence* varArg); + size_t paramCount, BNBoolWithConfidence* varArg, BNSizeWithConfidence* stackAdjust); BINARYNINJACOREAPI BNType* BNNewTypeReference(BNType* type); BINARYNINJACOREAPI BNType* BNDuplicateType(BNType* type); BINARYNINJACOREAPI char* BNGetTypeAndName(BNType* type, BNQualifiedName* name); @@ -2688,6 +2689,7 @@ extern "C" BINARYNINJACOREAPI void BNTypeSetMemberAccess(BNType* type, BNMemberAccessWithConfidence* access); BINARYNINJACOREAPI void BNTypeSetConst(BNType* type, BNBoolWithConfidence* cnst); BINARYNINJACOREAPI void BNTypeSetVolatile(BNType* type, BNBoolWithConfidence* vltl); + BINARYNINJACOREAPI BNSizeWithConfidence BNGetTypeStackAdjustment(BNType* type); BINARYNINJACOREAPI char* BNGetTypeString(BNType* type, BNPlatform* platform); BINARYNINJACOREAPI char* BNGetTypeStringBeforeName(BNType* type, BNPlatform* platform); diff --git a/lowlevelilinstruction.cpp b/lowlevelilinstruction.cpp index 19bfd983..d85e4f17 100644 --- a/lowlevelilinstruction.cpp +++ b/lowlevelilinstruction.cpp @@ -60,6 +60,7 @@ unordered_map {LowSSARegisterLowLevelOperandUsage, SSARegisterLowLevelOperand}, {ConstantLowLevelOperandUsage, IntegerLowLevelOperand}, {VectorLowLevelOperandUsage, IntegerLowLevelOperand}, + {StackAdjustmentLowLevelOperandUsage, IntegerLowLevelOperand}, {TargetLowLevelOperandUsage, IndexLowLevelOperand}, {TrueTargetLowLevelOperandUsage, IndexLowLevelOperand}, {FalseTargetLowLevelOperandUsage, IndexLowLevelOperand}, @@ -111,6 +112,7 @@ unordered_map> {LLIL_JUMP, {DestExprLowLevelOperandUsage}}, {LLIL_JUMP_TO, {DestExprLowLevelOperandUsage, TargetListLowLevelOperandUsage}}, {LLIL_CALL, {DestExprLowLevelOperandUsage}}, + {LLIL_CALL_STACK_ADJUST, {DestExprLowLevelOperandUsage, StackAdjustmentLowLevelOperandUsage}}, {LLIL_RET, {DestExprLowLevelOperandUsage}}, {LLIL_IF, {ConditionExprLowLevelOperandUsage, TrueTargetLowLevelOperandUsage, FalseTargetLowLevelOperandUsage}}, @@ -1020,7 +1022,7 @@ LowLevelILInstruction LowLevelILInstructionBase::GetSSAForm() const return *this; size_t expr = GetSSAExprIndex(); size_t instr = GetSSAInstructionIndex(); - return LowLevelILInstruction(ssa, ssa->GetRawExpr(GetSSAExprIndex()), expr, instr); + return LowLevelILInstruction(ssa, ssa->GetRawExpr(expr), expr, instr); } @@ -1031,7 +1033,7 @@ LowLevelILInstruction LowLevelILInstructionBase::GetNonSSAForm() const return *this; size_t expr = GetNonSSAExprIndex(); size_t instr = GetNonSSAInstructionIndex(); - return LowLevelILInstruction(nonSsa, nonSsa->GetRawExpr(GetSSAExprIndex()), expr, instr); + return LowLevelILInstruction(nonSsa, nonSsa->GetRawExpr(expr), expr, instr); } @@ -1160,6 +1162,9 @@ void LowLevelILInstruction::VisitExprs(const std::function().VisitExprs(func); break; + case LLIL_CALL_STACK_ADJUST: + GetDestExpr().VisitExprs(func); + break; case LLIL_CALL_SSA: GetDestExpr().VisitExprs(func); break; @@ -1301,6 +1306,9 @@ ExprId LowLevelILInstruction::CopyTo(LowLevelILFunction* dest, return dest->Jump(subExprHandler(GetDestExpr()), *this); case LLIL_CALL: return dest->Call(subExprHandler(GetDestExpr()), *this); + case LLIL_CALL_STACK_ADJUST: + return dest->CallStackAdjust(subExprHandler(GetDestExpr()), + GetStackAdjustment(), *this); case LLIL_RET: return dest->Return(subExprHandler(GetDestExpr()), *this); case LLIL_JUMP_TO: @@ -1647,6 +1655,15 @@ int64_t LowLevelILInstruction::GetVector() const } +size_t LowLevelILInstruction::GetStackAdjustment() const +{ + size_t operandIndex; + if (GetOperandIndexForUsage(StackAdjustmentLowLevelOperandUsage, operandIndex)) + return (size_t)GetRawOperandAsInteger(operandIndex); + throw LowLevelILInstructionAccessException(); +} + + size_t LowLevelILInstruction::GetTarget() const { size_t operandIndex; @@ -2133,6 +2150,12 @@ ExprId LowLevelILFunction::Call(ExprId dest, const ILSourceLocation& loc) } +ExprId LowLevelILFunction::CallStackAdjust(ExprId dest, size_t adjust, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_CALL_STACK_ADJUST, loc, 0, 0, dest, adjust); +} + + ExprId LowLevelILFunction::CallSSA(const vector& output, ExprId dest, const vector& params, const SSARegister& stack, size_t newMemoryVer, size_t prevMemoryVer, const ILSourceLocation& loc) { diff --git a/lowlevelilinstruction.h b/lowlevelilinstruction.h index 03688700..b2849d44 100644 --- a/lowlevelilinstruction.h +++ b/lowlevelilinstruction.h @@ -127,6 +127,7 @@ namespace BinaryNinja LowSSARegisterLowLevelOperandUsage, ConstantLowLevelOperandUsage, VectorLowLevelOperandUsage, + StackAdjustmentLowLevelOperandUsage, TargetLowLevelOperandUsage, TrueTargetLowLevelOperandUsage, FalseTargetLowLevelOperandUsage, @@ -499,6 +500,7 @@ namespace BinaryNinja template SSARegister GetLowSSARegister() const { return As().GetLowSSARegister(); } template int64_t GetConstant() const { return As().GetConstant(); } template int64_t GetVector() const { return As().GetVector(); } + template size_t GetStackAdjustment() const { return As().GetStackAdjustment(); } template size_t GetTarget() const { return As().GetTarget(); } template size_t GetTrueTarget() const { return As().GetTrueTarget(); } template size_t GetFalseTarget() const { return As().GetFalseTarget(); } @@ -551,6 +553,7 @@ namespace BinaryNinja SSARegister GetLowSSARegister() const; int64_t GetConstant() const; int64_t GetVector() const; + size_t GetStackAdjustment() const; size_t GetTarget() const; size_t GetTrueTarget() const; size_t GetFalseTarget() const; @@ -774,6 +777,11 @@ namespace BinaryNinja { LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } }; + template <> struct LowLevelILInstructionAccessor: public LowLevelILInstructionBase + { + LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } + size_t GetStackAdjustment() const { return (size_t)GetRawOperandAsInteger(1); } + }; template <> struct LowLevelILInstructionAccessor: public LowLevelILInstructionBase { LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } diff --git a/python/lowlevelil.py b/python/lowlevelil.py index e50f80c6..75a3f1ad 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -161,6 +161,7 @@ class LowLevelILInstruction(object): LowLevelILOperation.LLIL_JUMP: [("dest", "expr")], LowLevelILOperation.LLIL_JUMP_TO: [("dest", "expr"), ("targets", "int_list")], LowLevelILOperation.LLIL_CALL: [("dest", "expr")], + LowLevelILOperation.LLIL_CALL_STACK_ADJUST: [("dest", "expr"), ("stack_adjustment", "int")], LowLevelILOperation.LLIL_RET: [("dest", "expr")], LowLevelILOperation.LLIL_NORET: [], LowLevelILOperation.LLIL_IF: [("condition", "expr"), ("true", "int"), ("false", "int")], @@ -1262,6 +1263,18 @@ class LowLevelILFunction(object): """ return self.expr(LowLevelILOperation.LLIL_CALL, dest.index) + def call_stack_adjust(self, dest, stack_adjust): + """ + ``call_stack_adjust`` returns an expression which first pushes the address of the next instruction onto the stack + then jumps (branches) to the expression ``dest``. After the function exits, ``stack_adjust`` is added to the + stack pointer register. + + :param LowLevelILExpr dest: the expression to call + :return: The expression ``call(dest), stack += stack_adjust`` + :rtype: LowLevelILExpr + """ + return self.expr(LowLevelILOperation.LLIL_CALL_STACK_ADJUST, dest.index, stack_adjust) + def ret(self, dest): """ ``ret`` returns an expression which jumps (branches) to the expression ``dest``. ``ret`` is a special alias for diff --git a/python/types.py b/python/types.py index bf4a7b74..2557db2c 100644 --- a/python/types.py +++ b/python/types.py @@ -362,6 +362,12 @@ class Type(object): """Offset into structure (read-only)""" return core.BNGetTypeOffset(self.handle) + @property + def stack_adjustment(self): + """Stack adjustment for function (read-only)""" + result = core.BNGetTypeStackAdjustment(self.handle) + return SizeWithConfidence(result.value, confidence = result.confidence) + def __str__(self): platform = None if self.platform is not None: @@ -551,7 +557,7 @@ class Type(object): return Type(core.BNCreateArrayType(type_conf, count)) @classmethod - def function(self, ret, params, calling_convention=None, variable_arguments=None): + def function(self, ret, params, calling_convention=None, variable_arguments=None, stack_adjust=None): """ ``function`` class method for creating an function Type. @@ -605,8 +611,17 @@ class Type(object): vararg_conf.value = variable_arguments.value vararg_conf.confidence = variable_arguments.confidence + if stack_adjust is None: + stack_adjust = SizeWithConfidence(0, confidence = 0) + elif not isinstance(stack_adjust, SizeWithConfidence): + stack_adjust = SizeWithConfidence(stack_adjust) + + stack_adjust_conf = core.BNSizeWithConfidence() + stack_adjust_conf.value = stack_adjust.value + stack_adjust_conf.confidence = stack_adjust.confidence + return Type(core.BNCreateFunctionType(ret_conf, conv_conf, param_buf, len(params), - vararg_conf)) + vararg_conf, stack_adjust_conf)) @classmethod def generate_auto_type_id(self, source, name): diff --git a/type.cpp b/type.cpp index aa891557..40a69ae2 100644 --- a/type.cpp +++ b/type.cpp @@ -425,6 +425,13 @@ uint64_t Type::GetOffset() const } +Confidence Type::GetStackAdjustment() const +{ + BNSizeWithConfidence result = BNGetTypeStackAdjustment(m_object); + return Confidence(result.value, result.confidence); +} + + string Type::GetString(Platform* platform) const { char* str = BNGetTypeString(m_object, platform ? platform->GetObject() : nullptr); @@ -663,7 +670,8 @@ Ref Type::ArrayType(const Confidence>& type, uint64_t elem) Ref Type::FunctionType(const Confidence>& returnValue, const Confidence>& callingConvention, - const std::vector& params, const Confidence& varArg) + const std::vector& params, const Confidence& varArg, + const Confidence& stackAdjust) { BNTypeWithConfidence returnValueConf; returnValueConf.type = returnValue->GetObject(); @@ -689,8 +697,12 @@ Ref Type::FunctionType(const Confidence>& returnValue, varArgConf.value = varArg.GetValue(); varArgConf.confidence = varArg.GetConfidence(); + BNSizeWithConfidence stackAdjustConf; + stackAdjustConf.value = stackAdjust.GetValue(); + stackAdjustConf.confidence = stackAdjust.GetConfidence(); + Type* type = new Type(BNCreateFunctionType(&returnValueConf, &callingConventionConf, - paramArray, params.size(), &varArgConf)); + paramArray, params.size(), &varArgConf, &stackAdjustConf)); delete[] paramArray; return type; } -- cgit v1.3.1