diff options
| author | Peter LaFosse <peter@vector35.com> | 2018-05-07 16:28:39 -0400 |
|---|---|---|
| committer | Peter LaFosse <peter@vector35.com> | 2018-05-07 16:28:39 -0400 |
| commit | 40930128dc95f6cb8a9f2c1a4ce098fd15ae02ef (patch) | |
| tree | 4df97bc539c9fa6c9c362aa1d6630f50ed2dfa24 | |
| parent | f3040b9ef97f6dc521a14fa7a12c4a8d9b953e21 (diff) | |
| parent | b5779972913a77276afa808a415b23ecdfabcf72 (diff) | |
Merge branch 'dev' into test_relocation
| -rw-r--r-- | architecture.cpp | 16 | ||||
| -rw-r--r-- | binaryninjaapi.h | 14 | ||||
| -rw-r--r-- | binaryninjacore.h | 16 | ||||
| -rw-r--r-- | docs/about/open-source.md | 4 | ||||
| -rw-r--r-- | examples/llil_parser/src/llil_parser.cpp | 3 | ||||
| -rw-r--r-- | examples/mlil_parser/src/mlil_parser.cpp | 4 | ||||
| -rw-r--r-- | lowlevelilinstruction.cpp | 38 | ||||
| -rw-r--r-- | lowlevelilinstruction.h | 17 | ||||
| -rw-r--r-- | mediumlevelil.cpp | 6 | ||||
| -rw-r--r-- | mediumlevelilinstruction.cpp | 87 | ||||
| -rw-r--r-- | mediumlevelilinstruction.h | 39 | ||||
| -rw-r--r-- | python/basicblock.py | 2 | ||||
| -rw-r--r-- | python/interaction.py | 6 | ||||
| -rw-r--r-- | python/lowlevelil.py | 14 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 33 |
15 files changed, 272 insertions, 27 deletions
diff --git a/architecture.cpp b/architecture.cpp index 36241ac0..d7ab348b 100644 --- a/architecture.cpp +++ b/architecture.cpp @@ -196,8 +196,8 @@ bool Architecture::GetInstructionLowLevelILCallback(void* ctxt, const uint8_t* d size_t* len, BNLowLevelILFunction* il) { Architecture* arch = (Architecture*)ctxt; - LowLevelILFunction func(il); - return arch->GetInstructionLowLevelIL(data, addr, *len, func); + Ref<LowLevelILFunction> func(new LowLevelILFunction(BNNewLowLevelILFunctionReference(il))); + return arch->GetInstructionLowLevelIL(data, addr, *len, *func); } @@ -402,8 +402,8 @@ size_t Architecture::GetFlagWriteLowLevelILCallback(void* ctxt, BNLowLevelILOper uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount, BNLowLevelILFunction* il) { Architecture* arch = (Architecture*)ctxt; - LowLevelILFunction func(il); - return arch->GetFlagWriteLowLevelIL(op, size, flagWriteType, flag, operands, operandCount, func); + Ref<LowLevelILFunction> func(new LowLevelILFunction(BNNewLowLevelILFunctionReference(il))); + return arch->GetFlagWriteLowLevelIL(op, size, flagWriteType, flag, operands, operandCount, *func); } @@ -411,16 +411,16 @@ size_t Architecture::GetFlagConditionLowLevelILCallback(void* ctxt, BNLowLevelIL BNLowLevelILFunction* il) { Architecture* arch = (Architecture*)ctxt; - LowLevelILFunction func(il); - return arch->GetFlagConditionLowLevelIL(cond, semClass, func); + Ref<LowLevelILFunction> func(new LowLevelILFunction(BNNewLowLevelILFunctionReference(il))); + return arch->GetFlagConditionLowLevelIL(cond, semClass, *func); } size_t Architecture::GetSemanticFlagGroupLowLevelILCallback(void* ctxt, uint32_t semGroup, BNLowLevelILFunction* il) { Architecture* arch = (Architecture*)ctxt; - LowLevelILFunction func(il); - return arch->GetSemanticFlagGroupLowLevelIL(semGroup, func); + Ref<LowLevelILFunction> func(new LowLevelILFunction(BNNewLowLevelILFunctionReference(il))); + return arch->GetSemanticFlagGroupLowLevelIL(semGroup, *func); } diff --git a/binaryninjaapi.h b/binaryninjaapi.h index b9405a07..b753455b 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2831,12 +2831,16 @@ namespace BinaryNinja ExprId Call(ExprId dest, const ILSourceLocation& loc = ILSourceLocation()); ExprId CallStackAdjust(ExprId dest, size_t adjust, const std::map<uint32_t, int32_t>& regStackAdjust, const ILSourceLocation& loc = ILSourceLocation()); + ExprId TailCall(ExprId dest, const ILSourceLocation& loc = ILSourceLocation()); ExprId CallSSA(const std::vector<SSARegister>& output, ExprId dest, const std::vector<ExprId>& params, const SSARegister& stack, size_t newMemoryVer, size_t prevMemoryVer, const ILSourceLocation& loc = ILSourceLocation()); ExprId SystemCallSSA(const std::vector<SSARegister>& output, const std::vector<ExprId>& params, const SSARegister& stack, size_t newMemoryVer, size_t prevMemoryVer, const ILSourceLocation& loc = ILSourceLocation()); + ExprId TailCallSSA(const std::vector<SSARegister>& output, ExprId dest, const std::vector<ExprId>& params, + const SSARegister& stack, size_t newMemoryVer, size_t prevMemoryVer, + const ILSourceLocation& loc = ILSourceLocation()); ExprId Return(size_t dest, const ILSourceLocation& loc = ILSourceLocation()); ExprId NoReturn(const ILSourceLocation& loc = ILSourceLocation()); ExprId FlagCondition(BNLowLevelILFlagCondition cond, uint32_t semClass = 0, @@ -3150,6 +3154,10 @@ namespace BinaryNinja const ILSourceLocation& loc = ILSourceLocation()); ExprId SyscallUntyped(const std::vector<Variable>& output, const std::vector<Variable>& params, ExprId stack, const ILSourceLocation& loc = ILSourceLocation()); + ExprId TailCall(const std::vector<Variable>& output, ExprId dest, const std::vector<ExprId>& params, + const ILSourceLocation& loc = ILSourceLocation()); + ExprId TailCallUntyped(const std::vector<Variable>& output, ExprId dest, const std::vector<Variable>& params, + ExprId stack, const ILSourceLocation& loc = ILSourceLocation()); ExprId CallSSA(const std::vector<SSAVariable>& output, ExprId dest, const std::vector<ExprId>& params, size_t newMemVersion, size_t prevMemVersion, const ILSourceLocation& loc = ILSourceLocation()); ExprId CallUntypedSSA(const std::vector<SSAVariable>& output, ExprId dest, @@ -3160,6 +3168,11 @@ namespace BinaryNinja ExprId SyscallUntypedSSA(const std::vector<SSAVariable>& output, const std::vector<SSAVariable>& params, size_t newMemVersion, size_t prevMemVersion, ExprId stack, const ILSourceLocation& loc = ILSourceLocation()); + ExprId TailCallSSA(const std::vector<SSAVariable>& output, ExprId dest, const std::vector<ExprId>& params, + size_t newMemVersion, size_t prevMemVersion, const ILSourceLocation& loc = ILSourceLocation()); + ExprId TailCallUntypedSSA(const std::vector<SSAVariable>& output, ExprId dest, + const std::vector<SSAVariable>& params, size_t newMemVersion, size_t prevMemVersion, + ExprId stack, const ILSourceLocation& loc = ILSourceLocation()); ExprId Return(const std::vector<ExprId>& sources, const ILSourceLocation& loc = ILSourceLocation()); ExprId NoReturn(const ILSourceLocation& loc = ILSourceLocation()); ExprId CompareEqual(size_t size, ExprId left, ExprId right, @@ -3280,6 +3293,7 @@ namespace BinaryNinja size_t GetSSAMemoryDefinition(size_t version) const; std::set<size_t> GetSSAVarUses(const SSAVariable& var) const; std::set<size_t> GetSSAMemoryUses(size_t version) const; + bool IsSSAVarLive(const SSAVariable& var) const; std::set<size_t> GetVariableDefinitions(const Variable& var) const; std::set<size_t> GetVariableUses(const Variable& var) const; diff --git a/binaryninjacore.h b/binaryninjacore.h index 0f147f27..202684a8 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -347,6 +347,7 @@ extern "C" LLIL_JUMP_TO, LLIL_CALL, LLIL_CALL_STACK_ADJUST, + LLIL_TAILCALL, LLIL_RET, LLIL_NORET, LLIL_IF, @@ -418,6 +419,7 @@ extern "C" LLIL_FLAG_BIT_SSA, LLIL_CALL_SSA, LLIL_SYSCALL_SSA, + LLIL_TAILCALL_SSA, LLIL_CALL_PARAM, // Only valid within the LLIL_CALL_SSA, LLIL_SYSCALL_SSA, LLIL_INTRINSIC, LLIL_INTRINSIC_SSA instructions LLIL_CALL_STACK_SSA, // Only valid within the LLIL_CALL_SSA or LLIL_SYSCALL_SSA instructions LLIL_CALL_OUTPUT_SSA, // Only valid within the LLIL_CALL_SSA or LLIL_SYSCALL_SSA instructions @@ -862,8 +864,8 @@ extern "C" MLIL_JUMP_TO, MLIL_CALL, // Not valid in SSA form (see MLIL_CALL_SSA) MLIL_CALL_UNTYPED, // Not valid in SSA form (see MLIL_CALL_UNTYPED_SSA) - MLIL_CALL_OUTPUT, // Only valid within MLIL_CALL or MLIL_SYSCALL family instructions - MLIL_CALL_PARAM, // Only valid within MLIL_CALL or MLIL_SYSCALL family instructions + MLIL_CALL_OUTPUT, // Only valid within MLIL_CALL, MLIL_SYSCALL, MLIL_TAILCALL family instructions + MLIL_CALL_PARAM, // Only valid within MLIL_CALL, MLIL_SYSCALL, MLIL_TAILCALL family instructions MLIL_RET, // Not valid in SSA form (see MLIL_RET_SSA) MLIL_NORET, MLIL_IF, @@ -883,6 +885,8 @@ extern "C" MLIL_ADD_OVERFLOW, MLIL_SYSCALL, // Not valid in SSA form (see MLIL_SYSCALL_SSA) MLIL_SYSCALL_UNTYPED, // Not valid in SSA form (see MLIL_SYSCALL_UNTYPED_SSA) + MLIL_TAILCALL, // Not valid in SSA form (see MLIL_TAILCALL_SSA) + MLIL_TAILCALL_UNTYPED, // Not valid in SSA form (see MLIL_TAILCALL_UNTYPED_SSA) MLIL_INTRINSIC, // Not valid in SSA form (see MLIL_INTRINSIC_SSA) MLIL_FREE_VAR_SLOT, // Not valid in SSA from (see MLIL_FREE_VAR_SLOT_SSA) MLIL_BP, @@ -930,8 +934,10 @@ extern "C" MLIL_CALL_UNTYPED_SSA, MLIL_SYSCALL_SSA, MLIL_SYSCALL_UNTYPED_SSA, - MLIL_CALL_PARAM_SSA, // Only valid within the MLIL_CALL_SSA, MLIL_SYSCALL_SSA family instructions - MLIL_CALL_OUTPUT_SSA, // Only valid within the MLIL_CALL_SSA or MLIL_SYSCALL_SSA family instructions + MLIL_TAILCALL_SSA, + MLIL_TAILCALL_UNTYPED_SSA, + MLIL_CALL_PARAM_SSA, // Only valid within the MLIL_CALL_SSA, MLIL_SYSCALL_SSA, MLIL_TAILCALL_SSA family instructions + MLIL_CALL_OUTPUT_SSA, // Only valid within the MLIL_CALL_SSA or MLIL_SYSCALL_SSA, MLIL_TAILCALL_SSA family instructions MLIL_LOAD_SSA, MLIL_LOAD_STRUCT_SSA, MLIL_STORE_SSA, @@ -2878,6 +2884,8 @@ extern "C" size_t version, size_t* count); BINARYNINJACOREAPI size_t* BNGetMediumLevelILSSAMemoryUses(BNMediumLevelILFunction* func, size_t version, size_t* count); + BINARYNINJACOREAPI bool BNIsMediumLevelILSSAVarLive(BNMediumLevelILFunction* func, + const BNVariable* var, size_t version); BINARYNINJACOREAPI size_t* BNGetMediumLevelILVariableDefinitions(BNMediumLevelILFunction* func, const BNVariable* var, size_t* count); diff --git a/docs/about/open-source.md b/docs/about/open-source.md index a25fb24e..b0a35f37 100644 --- a/docs/about/open-source.md +++ b/docs/about/open-source.md @@ -47,7 +47,7 @@ Binary Ninja uses [Qt 5.10] under an LGPLv3 license which requires that we host Please note that we offer no support for running Binary Ninja with modified Qt libraries. 1. Follow the installation requirements on the [Building Qt 5 from Git] page. -2. Download the Qt 5.10.0 [tarball] from binary.ninja. (Note this is an unmodified 5.10 identical to that available from Qt's source control, but must be hosted locally according to the [Qt 5.10] terms.) +2. Download the Qt 5.10.1 [tarball] from binary.ninja. (Note this is an unmodified 5.10 identical to that available from Qt's source control, but must be hosted locally according to the [Qt 5.10] terms.) 3. Next, build QT using the aforementioned instructions. 4. On OS X, you will need to disable the code-signing signature since it would otherwise prevent changes to binaries or shared libraries. We recommend a tool such as [unsign]. 5. Finally, replace the built libraries: @@ -97,7 +97,7 @@ Please note that we offer no support for running Binary Ninja with modified Qt l [sphinx]: http://www.sphinx-doc.org/en/stable/index.html [sqlite license]: https://www.sqlite.org/copyright.html [sqlite]: https://www.sqlite.org/index.html -[tarball]: https://binary.ninja/qt5.10.0.tar.xz +[tarball]: https://binary.ninja/qt5.10.1.tar.xz [tomcrypt license]: https://github.com/libtom/libtomcrypt/blob/develop/LICENSE [tomcrypt]: https://github.com/libtom/libtomcrypt [unsign]: https://github.com/steakknife/unsign diff --git a/examples/llil_parser/src/llil_parser.cpp b/examples/llil_parser/src/llil_parser.cpp index 72ac71bd..75029d19 100644 --- a/examples/llil_parser/src/llil_parser.cpp +++ b/examples/llil_parser/src/llil_parser.cpp @@ -91,6 +91,8 @@ static void PrintOperation(BNLowLevelILOperation operation) ENUM_PRINTER(LLIL_JUMP) ENUM_PRINTER(LLIL_JUMP_TO) ENUM_PRINTER(LLIL_CALL) + ENUM_PRINTER(LLIL_CALL_STACK_ADJUST) + ENUM_PRINTER(LLIL_TAILCALL) ENUM_PRINTER(LLIL_RET) ENUM_PRINTER(LLIL_NORET) ENUM_PRINTER(LLIL_IF) @@ -126,6 +128,7 @@ static void PrintOperation(BNLowLevelILOperation operation) ENUM_PRINTER(LLIL_FLAG_BIT_SSA) ENUM_PRINTER(LLIL_CALL_SSA) ENUM_PRINTER(LLIL_SYSCALL_SSA) + ENUM_PRINTER(LLIL_TAILCALL_SSA) ENUM_PRINTER(LLIL_CALL_PARAM_SSA) ENUM_PRINTER(LLIL_CALL_STACK_SSA) ENUM_PRINTER(LLIL_CALL_OUTPUT_SSA) diff --git a/examples/mlil_parser/src/mlil_parser.cpp b/examples/mlil_parser/src/mlil_parser.cpp index 8fb762eb..0e621ead 100644 --- a/examples/mlil_parser/src/mlil_parser.cpp +++ b/examples/mlil_parser/src/mlil_parser.cpp @@ -114,6 +114,8 @@ static void PrintOperation(BNMediumLevelILOperation operation) ENUM_PRINTER(MLIL_ADD_OVERFLOW) ENUM_PRINTER(MLIL_SYSCALL) ENUM_PRINTER(MLIL_SYSCALL_UNTYPED) + ENUM_PRINTER(MLIL_TAILCALL) + ENUM_PRINTER(MLIL_TAILCALL_UNTYPED) ENUM_PRINTER(MLIL_BP) ENUM_PRINTER(MLIL_TRAP) ENUM_PRINTER(MLIL_UNDEF) @@ -132,6 +134,8 @@ static void PrintOperation(BNMediumLevelILOperation operation) ENUM_PRINTER(MLIL_CALL_UNTYPED_SSA) ENUM_PRINTER(MLIL_SYSCALL_SSA) ENUM_PRINTER(MLIL_SYSCALL_UNTYPED_SSA) + ENUM_PRINTER(MLIL_TAILCALL_SSA) + ENUM_PRINTER(MLIL_TAILCALL_UNTYPED_SSA) ENUM_PRINTER(MLIL_CALL_PARAM_SSA) ENUM_PRINTER(MLIL_CALL_OUTPUT_SSA) ENUM_PRINTER(MLIL_LOAD_SSA) diff --git a/lowlevelilinstruction.cpp b/lowlevelilinstruction.cpp index 8fb87a9e..5f5dc397 100644 --- a/lowlevelilinstruction.cpp +++ b/lowlevelilinstruction.cpp @@ -148,6 +148,7 @@ unordered_map<BNLowLevelILOperation, vector<LowLevelILOperandUsage>> {LLIL_CALL, {DestExprLowLevelOperandUsage}}, {LLIL_CALL_STACK_ADJUST, {DestExprLowLevelOperandUsage, StackAdjustmentLowLevelOperandUsage, RegisterStackAdjustmentsLowLevelOperandUsage}}, + {LLIL_TAILCALL, {DestExprLowLevelOperandUsage}}, {LLIL_RET, {DestExprLowLevelOperandUsage}}, {LLIL_IF, {ConditionExprLowLevelOperandUsage, TrueTargetLowLevelOperandUsage, FalseTargetLowLevelOperandUsage}}, @@ -161,6 +162,9 @@ unordered_map<BNLowLevelILOperation, vector<LowLevelILOperandUsage>> {LLIL_SYSCALL_SSA, {OutputSSARegistersLowLevelOperandUsage, OutputMemoryVersionLowLevelOperandUsage, StackSSARegisterLowLevelOperandUsage, StackMemoryVersionLowLevelOperandUsage, ParameterExprsLowLevelOperandUsage}}, + {LLIL_TAILCALL_SSA, {OutputSSARegistersLowLevelOperandUsage, OutputMemoryVersionLowLevelOperandUsage, + DestExprLowLevelOperandUsage, StackSSARegisterLowLevelOperandUsage, + StackMemoryVersionLowLevelOperandUsage, ParameterExprsLowLevelOperandUsage}}, {LLIL_REG_PHI, {DestSSARegisterLowLevelOperandUsage, SourceSSARegistersLowLevelOperandUsage}}, {LLIL_REG_STACK_PHI, {DestSSARegisterStackLowLevelOperandUsage, SourceSSARegisterStacksLowLevelOperandUsage}}, {LLIL_FLAG_PHI, {DestSSAFlagLowLevelOperandUsage, SourceSSAFlagsLowLevelOperandUsage}}, @@ -1808,6 +1812,9 @@ void LowLevelILInstruction::VisitExprs(const std::function<bool(const LowLevelIL case LLIL_CALL_STACK_ADJUST: GetDestExpr<LLIL_CALL_STACK_ADJUST>().VisitExprs(func); break; + case LLIL_TAILCALL: + GetDestExpr<LLIL_TAILCALL>().VisitExprs(func); + break; case LLIL_CALL_SSA: GetDestExpr<LLIL_CALL_SSA>().VisitExprs(func); for (auto& i : GetParameterExprs<LLIL_CALL_SSA>()) @@ -1817,6 +1824,11 @@ void LowLevelILInstruction::VisitExprs(const std::function<bool(const LowLevelIL for (auto& i : GetParameterExprs<LLIL_SYSCALL_SSA>()) i.VisitExprs(func); break; + case LLIL_TAILCALL_SSA: + GetDestExpr<LLIL_TAILCALL_SSA>().VisitExprs(func); + for (auto& i : GetParameterExprs<LLIL_TAILCALL_SSA>()) + i.VisitExprs(func); + break; case LLIL_RET: GetDestExpr<LLIL_RET>().VisitExprs(func); break; @@ -2037,6 +2049,8 @@ ExprId LowLevelILInstruction::CopyTo(LowLevelILFunction* dest, case LLIL_CALL_STACK_ADJUST: return dest->CallStackAdjust(subExprHandler(GetDestExpr<LLIL_CALL_STACK_ADJUST>()), GetStackAdjustment<LLIL_CALL_STACK_ADJUST>(), GetRegisterStackAdjustments<LLIL_CALL_STACK_ADJUST>(), *this); + case LLIL_TAILCALL: + return dest->TailCall(subExprHandler(GetDestExpr<LLIL_TAILCALL>()), *this); case LLIL_RET: return dest->Return(subExprHandler(GetDestExpr<LLIL_RET>()), *this); case LLIL_JUMP_TO: @@ -2080,6 +2094,12 @@ ExprId LowLevelILInstruction::CopyTo(LowLevelILFunction* dest, return dest->SystemCallSSA(GetOutputSSARegisters<LLIL_SYSCALL_SSA>(), params, GetStackSSARegister<LLIL_SYSCALL_SSA>(), GetDestMemoryVersion<LLIL_SYSCALL_SSA>(), GetSourceMemoryVersion<LLIL_SYSCALL_SSA>(), *this); + case LLIL_TAILCALL_SSA: + for (auto& i : GetParameterExprs<LLIL_TAILCALL_SSA>()) + params.push_back(subExprHandler(i)); + return dest->TailCallSSA(GetOutputSSARegisters<LLIL_TAILCALL_SSA>(), subExprHandler(GetDestExpr<LLIL_TAILCALL_SSA>()), + params, GetStackSSARegister<LLIL_TAILCALL_SSA>(), GetDestMemoryVersion<LLIL_TAILCALL_SSA>(), + GetSourceMemoryVersion<LLIL_TAILCALL_SSA>(), *this); case LLIL_REG_PHI: return dest->RegisterPhi(GetDestSSARegister<LLIL_REG_PHI>(), GetSourceSSARegisters<LLIL_REG_PHI>(), *this); case LLIL_REG_STACK_PHI: @@ -3157,6 +3177,12 @@ ExprId LowLevelILFunction::CallStackAdjust(ExprId dest, size_t adjust, } +ExprId LowLevelILFunction::TailCall(ExprId dest, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_TAILCALL, loc, 0, 0, dest); +} + + ExprId LowLevelILFunction::CallSSA(const vector<SSARegister>& output, ExprId dest, const vector<ExprId>& params, const SSARegister& stack, size_t newMemoryVer, size_t prevMemoryVer, const ILSourceLocation& loc) { @@ -3181,6 +3207,18 @@ ExprId LowLevelILFunction::SystemCallSSA(const vector<SSARegister>& output, cons } +ExprId LowLevelILFunction::TailCallSSA(const vector<SSARegister>& output, ExprId dest, const vector<ExprId>& params, + const SSARegister& stack, size_t newMemoryVer, size_t prevMemoryVer, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_TAILCALL_SSA, loc, 0, 0, + AddExprWithLocation(LLIL_CALL_OUTPUT_SSA, loc, 0, 0, newMemoryVer, + output.size() * 2, AddSSARegisterList(output)), dest, + AddExprWithLocation(LLIL_CALL_STACK_SSA, loc, 0, 0, stack.reg, stack.version, prevMemoryVer), + AddExprWithLocation(LLIL_CALL_PARAM, loc, 0, 0, + params.size(), AddOperandList(params))); +} + + ExprId LowLevelILFunction::Return(size_t dest, const ILSourceLocation& loc) { return AddExprWithLocation(LLIL_RET, loc, 0, 0, dest); diff --git a/lowlevelilinstruction.h b/lowlevelilinstruction.h index 675baa3c..e845bcd0 100644 --- a/lowlevelilinstruction.h +++ b/lowlevelilinstruction.h @@ -1107,6 +1107,10 @@ namespace BinaryNinja size_t GetStackAdjustment() const { return (size_t)GetRawOperandAsInteger(1); } std::map<uint32_t, int32_t> GetRegisterStackAdjustments() const { return GetRawOperandAsRegisterStackAdjustments(2); } }; + template <> struct LowLevelILInstructionAccessor<LLIL_TAILCALL>: public LowLevelILInstructionBase + { + LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } + }; template <> struct LowLevelILInstructionAccessor<LLIL_RET>: public LowLevelILInstructionBase { LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } @@ -1163,6 +1167,19 @@ namespace BinaryNinja void SetStackSSAVersion(size_t version) { GetRawOperandAsExpr(1).UpdateRawOperand(1, version); } void SetOutputSSARegisters(const std::vector<SSARegister>& regs) { GetRawOperandAsExpr(0).UpdateRawOperandAsSSARegisterList(1, regs); } }; + template <> struct LowLevelILInstructionAccessor<LLIL_TAILCALL_SSA>: public LowLevelILInstructionBase + { + LowLevelILSSARegisterList GetOutputSSARegisters() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSARegisterList(1); } + size_t GetDestMemoryVersion() const { return GetRawOperandAsExpr(0).GetRawOperandAsIndex(0); } + LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); } + SSARegister GetStackSSARegister() const { return GetRawOperandAsExpr(2).GetRawOperandAsSSARegister(0); } + size_t GetSourceMemoryVersion() const { return GetRawOperandAsExpr(2).GetRawOperandAsIndex(2); } + LowLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExpr(3).GetRawOperandAsExprList(0); } + void SetDestMemoryVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(0, version); } + void SetSourceMemoryVersion(size_t version) { GetRawOperandAsExpr(2).UpdateRawOperand(2, version); } + void SetStackSSAVersion(size_t version) { GetRawOperandAsExpr(2).UpdateRawOperand(1, version); } + void SetOutputSSARegisters(const std::vector<SSARegister>& regs) { GetRawOperandAsExpr(0).UpdateRawOperandAsSSARegisterList(1, regs); } + }; template <> struct LowLevelILInstructionAccessor<LLIL_INTRINSIC>: public LowLevelILInstructionBase { diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index 0a28bd49..1795a54d 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -486,6 +486,12 @@ set<size_t> MediumLevelILFunction::GetSSAMemoryUses(size_t version) const } +bool MediumLevelILFunction::IsSSAVarLive(const SSAVariable& var) const +{ + return BNIsMediumLevelILSSAVarLive(m_object, &var.var, var.version); +} + + set<size_t> MediumLevelILFunction::GetVariableDefinitions(const Variable& var) const { size_t count; diff --git a/mediumlevelilinstruction.cpp b/mediumlevelilinstruction.cpp index fa66f553..9cf82b08 100644 --- a/mediumlevelilinstruction.cpp +++ b/mediumlevelilinstruction.cpp @@ -129,6 +129,10 @@ unordered_map<BNMediumLevelILOperation, vector<MediumLevelILOperandUsage>> {MLIL_SYSCALL, {OutputVariablesMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage}}, {MLIL_SYSCALL_UNTYPED, {OutputVariablesSubExprMediumLevelOperandUsage, ParameterVariablesMediumLevelOperandUsage, StackExprMediumLevelOperandUsage}}, + {MLIL_TAILCALL, {OutputVariablesMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, + ParameterExprsMediumLevelOperandUsage}}, + {MLIL_TAILCALL_UNTYPED, {OutputVariablesSubExprMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, + ParameterVariablesMediumLevelOperandUsage}}, {MLIL_CALL_SSA, {OutputSSAVariablesSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage, SourceMemoryVersionMediumLevelOperandUsage}}, @@ -142,6 +146,13 @@ unordered_map<BNMediumLevelILOperation, vector<MediumLevelILOperandUsage>> {MLIL_SYSCALL_UNTYPED_SSA, {OutputSSAVariablesSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, ParameterSSAVariablesMediumLevelOperandUsage, ParameterSSAMemoryVersionMediumLevelOperandUsage, StackExprMediumLevelOperandUsage}}, + {MLIL_TAILCALL_SSA, {OutputSSAVariablesSubExprMediumLevelOperandUsage, + OutputSSAMemoryVersionMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, + ParameterExprsMediumLevelOperandUsage, SourceMemoryVersionMediumLevelOperandUsage}}, + {MLIL_TAILCALL_UNTYPED_SSA, {OutputSSAVariablesSubExprMediumLevelOperandUsage, + OutputSSAMemoryVersionMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, + ParameterSSAVariablesMediumLevelOperandUsage, ParameterSSAMemoryVersionMediumLevelOperandUsage, + StackExprMediumLevelOperandUsage}}, {MLIL_RET, {SourceExprsMediumLevelOperandUsage}}, {MLIL_IF, {ConditionExprMediumLevelOperandUsage, TrueTargetMediumLevelOperandUsage, FalseTargetMediumLevelOperandUsage}}, @@ -1267,6 +1278,22 @@ void MediumLevelILInstruction::VisitExprs(const std::function<bool(const MediumL for (auto& i : GetParameterExprs<MLIL_SYSCALL_SSA>()) i.VisitExprs(func); break; + case MLIL_TAILCALL: + GetDestExpr<MLIL_TAILCALL>().VisitExprs(func); + for (auto& i : GetParameterExprs<MLIL_TAILCALL>()) + i.VisitExprs(func); + break; + case MLIL_TAILCALL_UNTYPED: + GetDestExpr<MLIL_TAILCALL_UNTYPED>().VisitExprs(func); + break; + case MLIL_TAILCALL_SSA: + GetDestExpr<MLIL_TAILCALL_SSA>().VisitExprs(func); + for (auto& i : GetParameterExprs<MLIL_TAILCALL_SSA>()) + i.VisitExprs(func); + break; + case MLIL_TAILCALL_UNTYPED_SSA: + GetDestExpr<MLIL_TAILCALL_UNTYPED_SSA>().VisitExprs(func); + break; case MLIL_RET: for (auto& i : GetSourceExprs<MLIL_RET>()) i.VisitExprs(func); @@ -1504,6 +1531,27 @@ ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest, GetDestMemoryVersion<MLIL_SYSCALL_UNTYPED_SSA>(), GetSourceMemoryVersion<MLIL_SYSCALL_UNTYPED_SSA>(), subExprHandler(GetStackExpr<MLIL_SYSCALL_UNTYPED_SSA>()), *this); + case MLIL_TAILCALL: + for (auto& i : GetParameterExprs<MLIL_TAILCALL>()) + params.push_back(subExprHandler(i)); + return dest->TailCall(GetOutputVariables<MLIL_TAILCALL>(), subExprHandler(GetDestExpr<MLIL_TAILCALL>()), + params, *this); + case MLIL_TAILCALL_UNTYPED: + return dest->TailCallUntyped(GetOutputVariables<MLIL_TAILCALL_UNTYPED>(), + subExprHandler(GetDestExpr<MLIL_TAILCALL_UNTYPED>()), GetParameterVariables<MLIL_TAILCALL_UNTYPED>(), + subExprHandler(GetStackExpr<MLIL_TAILCALL_UNTYPED>()), *this); + case MLIL_TAILCALL_SSA: + for (auto& i : GetParameterExprs<MLIL_TAILCALL_SSA>()) + params.push_back(subExprHandler(i)); + return dest->TailCallSSA(GetOutputSSAVariables<MLIL_TAILCALL_SSA>(), subExprHandler(GetDestExpr<MLIL_TAILCALL_SSA>()), + params, GetDestMemoryVersion<MLIL_TAILCALL_SSA>(), GetSourceMemoryVersion<MLIL_TAILCALL_SSA>(), *this); + case MLIL_TAILCALL_UNTYPED_SSA: + return dest->TailCallUntypedSSA(GetOutputSSAVariables<MLIL_TAILCALL_UNTYPED_SSA>(), + subExprHandler(GetDestExpr<MLIL_TAILCALL_UNTYPED_SSA>()), + GetParameterSSAVariables<MLIL_TAILCALL_UNTYPED_SSA>(), + GetDestMemoryVersion<MLIL_TAILCALL_UNTYPED_SSA>(), + GetSourceMemoryVersion<MLIL_TAILCALL_UNTYPED_SSA>(), + subExprHandler(GetStackExpr<MLIL_TAILCALL_UNTYPED_SSA>()), *this); case MLIL_RET: for (auto& i : GetSourceExprs<MLIL_RET>()) params.push_back(subExprHandler(i)); @@ -2483,6 +2531,23 @@ ExprId MediumLevelILFunction::SyscallUntyped(const vector<Variable>& output, con } +ExprId MediumLevelILFunction::TailCall(const vector<Variable>& output, ExprId dest, + const vector<ExprId>& params, const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_TAILCALL, loc, 0, output.size(), AddVariableList(output), dest, + params.size(), AddOperandList(params)); +} + + +ExprId MediumLevelILFunction::TailCallUntyped(const vector<Variable>& output, ExprId dest, + const vector<Variable>& params, ExprId stack, const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_TAILCALL_UNTYPED, loc, 0, + AddExprWithLocation(MLIL_CALL_OUTPUT, loc, 0, output.size(), AddVariableList(output)), dest, + AddExprWithLocation(MLIL_CALL_PARAM, loc, 0, params.size(), AddVariableList(params)), stack); +} + + ExprId MediumLevelILFunction::CallSSA(const vector<SSAVariable>& output, ExprId dest, const vector<ExprId>& params, size_t newMemVersion, size_t prevMemVersion, const ILSourceLocation& loc) { @@ -2527,6 +2592,28 @@ ExprId MediumLevelILFunction::SyscallUntypedSSA(const vector<SSAVariable>& outpu } +ExprId MediumLevelILFunction::TailCallSSA(const vector<SSAVariable>& output, ExprId dest, const vector<ExprId>& params, + size_t newMemVersion, size_t prevMemVersion, const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_TAILCALL_SSA, loc, 0, + AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, + output.size() * 2, AddSSAVariableList(output)), dest, + params.size(), AddOperandList(params), prevMemVersion); +} + + +ExprId MediumLevelILFunction::TailCallUntypedSSA(const vector<SSAVariable>& output, ExprId dest, + const vector<SSAVariable>& params, size_t newMemVersion, size_t prevMemVersion, + ExprId stack, const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_TAILCALL_UNTYPED_SSA, loc, 0, + AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, + output.size() * 2, AddSSAVariableList(output)), dest, + AddExprWithLocation(MLIL_CALL_PARAM_SSA, loc, 0, prevMemVersion, + params.size() * 2, AddSSAVariableList(params)), stack); +} + + ExprId MediumLevelILFunction::Return(const vector<ExprId>& sources, const ILSourceLocation& loc) { return AddExprWithLocation(MLIL_RET, loc, 0, sources.size(), AddOperandList(sources)); diff --git a/mediumlevelilinstruction.h b/mediumlevelilinstruction.h index e3167585..b37b8832 100644 --- a/mediumlevelilinstruction.h +++ b/mediumlevelilinstruction.h @@ -839,6 +839,19 @@ namespace BinaryNinja MediumLevelILVariableList GetParameterVariables() const { return GetRawOperandAsExpr(1).GetRawOperandAsVariableList(0); } MediumLevelILInstruction GetStackExpr() const { return GetRawOperandAsExpr(2); } }; + template <> struct MediumLevelILInstructionAccessor<MLIL_TAILCALL>: public MediumLevelILInstructionBase + { + MediumLevelILVariableList GetOutputVariables() const { return GetRawOperandAsVariableList(0); } + MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(2); } + MediumLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExprList(3); } + }; + template <> struct MediumLevelILInstructionAccessor<MLIL_TAILCALL_UNTYPED>: public MediumLevelILInstructionBase + { + MediumLevelILVariableList GetOutputVariables() const { return GetRawOperandAsExpr(0).GetRawOperandAsVariableList(0); } + MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); } + MediumLevelILVariableList GetParameterVariables() const { return GetRawOperandAsExpr(2).GetRawOperandAsVariableList(0); } + MediumLevelILInstruction GetStackExpr() const { return GetRawOperandAsExpr(3); } + }; template <> struct MediumLevelILInstructionAccessor<MLIL_CALL_SSA>: public MediumLevelILInstructionBase { @@ -890,6 +903,32 @@ namespace BinaryNinja void SetOutputSSAVariables(const std::vector<SSAVariable>& vars) { GetRawOperandAsExpr(0).UpdateRawOperandAsSSAVariableList(1, vars); } void SetParameterSSAVariables(const std::vector<SSAVariable>& vars) { GetRawOperandAsExpr(1).UpdateRawOperandAsSSAVariableList(1, vars); } }; + template <> struct MediumLevelILInstructionAccessor<MLIL_TAILCALL_SSA>: public MediumLevelILInstructionBase + { + size_t GetDestMemoryVersion() const { return GetRawOperandAsExpr(0).GetRawOperandAsIndex(0); } + MediumLevelILSSAVariableList GetOutputSSAVariables() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSAVariableList(1); } + MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); } + MediumLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExprList(2); } + size_t GetSourceMemoryVersion() const { return GetRawOperandAsIndex(4); } + void SetDestMemoryVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(0, version); } + void SetSourceMemoryVersion(size_t version) { UpdateRawOperand(4, version); } + void SetOutputSSAVariables(const std::vector<SSAVariable>& vars) { GetRawOperandAsExpr(0).UpdateRawOperandAsSSAVariableList(1, vars); } + void SetParameterExprs(const std::vector<MediumLevelILInstruction>& params) { UpdateRawOperandAsExprList(2, params); } + void SetParameterExprs(const std::vector<ExprId>& params) { UpdateRawOperandAsExprList(2, params); } + }; + template <> struct MediumLevelILInstructionAccessor<MLIL_TAILCALL_UNTYPED_SSA>: public MediumLevelILInstructionBase + { + size_t GetDestMemoryVersion() const { return GetRawOperandAsExpr(0).GetRawOperandAsIndex(0); } + MediumLevelILSSAVariableList GetOutputSSAVariables() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSAVariableList(1); } + MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); } + MediumLevelILSSAVariableList GetParameterSSAVariables() const { return GetRawOperandAsExpr(2).GetRawOperandAsSSAVariableList(1); } + size_t GetSourceMemoryVersion() const { return GetRawOperandAsExpr(2).GetRawOperandAsIndex(0); } + MediumLevelILInstruction GetStackExpr() const { return GetRawOperandAsExpr(3); } + void SetDestMemoryVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(0, version); } + void SetSourceMemoryVersion(size_t version) { GetRawOperandAsExpr(2).UpdateRawOperand(0, version); } + void SetOutputSSAVariables(const std::vector<SSAVariable>& vars) { GetRawOperandAsExpr(0).UpdateRawOperandAsSSAVariableList(1, vars); } + void SetParameterSSAVariables(const std::vector<SSAVariable>& vars) { GetRawOperandAsExpr(2).UpdateRawOperandAsSSAVariableList(1, vars); } + }; template <> struct MediumLevelILInstructionAccessor<MLIL_RET>: public MediumLevelILInstructionBase { diff --git a/python/basicblock.py b/python/basicblock.py index 4dc783c3..c55e15f0 100644 --- a/python/basicblock.py +++ b/python/basicblock.py @@ -308,7 +308,7 @@ class BasicBlock(object): idx = start while idx < end: - data = self.view.read(idx, 16) + data = self.view.read(idx, self.arch.max_instr_length) inst_info = self.arch.get_instruction_info(data, idx) inst_text = self.arch.get_instruction_text(data, idx) diff --git a/python/interaction.py b/python/interaction.py index 4f6ed67d..5b7ec497 100644 --- a/python/interaction.py +++ b/python/interaction.py @@ -669,11 +669,9 @@ def get_save_filename_input(prompt, ext="", default_name=""): def get_directory_name_input(prompt, default_name=""): """ - ``get_directory_name_input`` prompts the user for a directory name to save as, optionally providing and - default_name. + ``get_directory_name_input`` prompts the user for a directory name to save as, optionally providing a default_name. - Note: This API function differently on the command line vs. the UI. In the UI a popup is used. On the commandline - a simple text prompt is used. The ui uses the native window popup for file selection. + Note: This API function differently on the command line vs. the UI. In the UI a popup is used. On the commandline a simple text prompt is used. The ui uses the native window popup for file selection. :param str prompt: Prompt to display. :param str default_name: Optional, default directory name. diff --git a/python/lowlevelil.py b/python/lowlevelil.py index ab6170a5..34048704 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -260,6 +260,7 @@ class LowLevelILInstruction(object): LowLevelILOperation.LLIL_JUMP_TO: [("dest", "expr"), ("targets", "int_list")], LowLevelILOperation.LLIL_CALL: [("dest", "expr")], LowLevelILOperation.LLIL_CALL_STACK_ADJUST: [("dest", "expr"), ("stack_adjustment", "int"), ("reg_stack_adjustments", "reg_stack_adjust")], + LowLevelILOperation.LLIL_TAILCALL: [("dest", "expr")], LowLevelILOperation.LLIL_RET: [("dest", "expr")], LowLevelILOperation.LLIL_NORET: [], LowLevelILOperation.LLIL_IF: [("condition", "expr"), ("true", "int"), ("false", "int")], @@ -328,6 +329,7 @@ class LowLevelILInstruction(object): LowLevelILOperation.LLIL_FLAG_BIT_SSA: [("src", "flag_ssa"), ("bit", "int")], LowLevelILOperation.LLIL_CALL_SSA: [("output", "expr"), ("dest", "expr"), ("stack", "expr"), ("param", "expr")], LowLevelILOperation.LLIL_SYSCALL_SSA: [("output", "expr"), ("stack", "expr"), ("param", "expr")], + LowLevelILOperation.LLIL_TAILCALL_SSA: [("output", "expr"), ("dest", "expr"), ("stack", "expr"), ("param", "expr")], LowLevelILOperation.LLIL_CALL_OUTPUT_SSA: [("dest_memory", "int"), ("dest", "reg_ssa_list")], LowLevelILOperation.LLIL_CALL_STACK_SSA: [("src", "reg_ssa"), ("src_memory", "int")], LowLevelILOperation.LLIL_CALL_PARAM: [("src", "expr_list")], @@ -1592,10 +1594,20 @@ class LowLevelILFunction(object): """ return self.expr(LowLevelILOperation.LLIL_CALL_STACK_ADJUST, dest.index, stack_adjust) + def tailcall(self, dest): + """ + ``tailcall`` returns an expression which jumps (branches) to the expression ``dest`` + + :param LowLevelILExpr dest: the expression to jump to + :return: The expression ``tailcall(dest)`` + :rtype: LowLevelILExpr + """ + return self.expr(LowLevelILOperation.LLIL_TAILCALL, dest.index) + def ret(self, dest): """ ``ret`` returns an expression which jumps (branches) to the expression ``dest``. ``ret`` is a special alias for - jump that makes the disassembler top disassembling. + jump that makes the disassembler stop disassembling. :param LowLevelILExpr dest: the expression to jump to :return: The expression ``jump(dest)`` diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index caf19e8e..100795fe 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -148,6 +148,8 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_ADD_OVERFLOW: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_SYSCALL: [("output", "var_list"), ("params", "expr_list")], MediumLevelILOperation.MLIL_SYSCALL_UNTYPED: [("output", "expr"), ("params", "expr"), ("stack", "expr")], + MediumLevelILOperation.MLIL_TAILCALL: [("output", "var_list"), ("dest", "expr"), ("params", "expr_list")], + MediumLevelILOperation.MLIL_TAILCALL_UNTYPED: [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_BP: [], MediumLevelILOperation.MLIL_TRAP: [("vector", "int")], MediumLevelILOperation.MLIL_INTRINSIC: [("output", "var_list"), ("intrinsic", "intrinsic"), ("params", "expr_list")], @@ -193,6 +195,8 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA: [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_SYSCALL_SSA: [("output", "expr"), ("params", "expr_list"), ("src_memory", "int")], MediumLevelILOperation.MLIL_SYSCALL_UNTYPED_SSA: [("output", "expr"), ("params", "expr"), ("stack", "expr")], + MediumLevelILOperation.MLIL_TAILCALL_SSA: [("output", "expr"), ("dest", "expr"), ("params", "expr_list"), ("src_memory", "int")], + MediumLevelILOperation.MLIL_TAILCALL_UNTYPED_SSA: [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_CALL_OUTPUT_SSA: [("dest_memory", "int"), ("dest", "var_ssa_list")], MediumLevelILOperation.MLIL_CALL_PARAM_SSA: [("src_memory", "int"), ("src", "var_ssa_list")], MediumLevelILOperation.MLIL_LOAD_SSA: [("src", "expr"), ("src_memory", "int")], @@ -410,11 +414,12 @@ class MediumLevelILInstruction(object): return [self.dest] elif self.operation in [MediumLevelILOperation.MLIL_SET_VAR_SPLIT, MediumLevelILOperation.MLIL_SET_VAR_SPLIT_SSA]: return [self.high, self.low] - elif self.operation in [MediumLevelILOperation.MLIL_CALL, MediumLevelILOperation.MLIL_SYSCALL]: + elif self.operation in [MediumLevelILOperation.MLIL_CALL, MediumLevelILOperation.MLIL_SYSCALL, MediumLevelILOperation.MLIL_TAILCALL]: return self.output - elif self.operation in [MediumLevelILOperation.MLIL_CALL_UNTYPED, MediumLevelILOperation.MLIL_SYSCALL_UNTYPED, + elif self.operation in [MediumLevelILOperation.MLIL_CALL_UNTYPED, MediumLevelILOperation.MLIL_SYSCALL_UNTYPED, MediumLevelILOperation.MLIL_TAILCALL_UNTYPED, MediumLevelILOperation.MLIL_CALL_SSA, MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA, - MediumLevelILOperation.MLIL_SYSCALL_SSA, MediumLevelILOperation.MLIL_SYSCALL_UNTYPED_SSA]: + MediumLevelILOperation.MLIL_SYSCALL_SSA, MediumLevelILOperation.MLIL_SYSCALL_UNTYPED_SSA, + MediumLevelILOperation.MLIL_TAILCALL_SSA, MediumLevelILOperation.MLIL_TAILCALL_UNTYPED_SSA]: return self.output.vars_written elif self.operation in [MediumLevelILOperation.MLIL_CALL_OUTPUT, MediumLevelILOperation.MLIL_CALL_OUTPUT_SSA]: return self.dest @@ -430,14 +435,14 @@ class MediumLevelILInstruction(object): elif self.operation in [MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD, MediumLevelILOperation.MLIL_SET_VAR_ALIASED_FIELD]: return [self.prev] + self.src.vars_read - elif self.operation in [MediumLevelILOperation.MLIL_CALL, MediumLevelILOperation.MLIL_SYSCALL, - MediumLevelILOperation.MLIL_CALL_SSA, MediumLevelILOperation.MLIL_SYSCALL_SSA]: + elif self.operation in [MediumLevelILOperation.MLIL_CALL, MediumLevelILOperation.MLIL_SYSCALL, MediumLevelILOperation.MLIL_TAILCALL, + MediumLevelILOperation.MLIL_CALL_SSA, MediumLevelILOperation.MLIL_SYSCALL_SSA, MediumLevelILOperation.MLIL_TAILCALL_SSA]: result = [] for param in self.params: result += param.vars_read return result - elif self.operation in [MediumLevelILOperation.MLIL_CALL_UNTYPED, MediumLevelILOperation.MLIL_SYSCALL_UNTYPED, - MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA, MediumLevelILOperation.MLIL_SYSCALL_UNTYPED_SSA]: + elif self.operation in [MediumLevelILOperation.MLIL_CALL_UNTYPED, MediumLevelILOperation.MLIL_SYSCALL_UNTYPED, MediumLevelILOperation.MLIL_TAILCALL_UNTYPED, + MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA, MediumLevelILOperation.MLIL_SYSCALL_UNTYPED_SSA, MediumLevelILOperation.MLIL_TAILCALL_UNTYPED_SSA]: return self.params.vars_read elif self.operation in [MediumLevelILOperation.MLIL_CALL_PARAM, MediumLevelILOperation.MLIL_CALL_PARAM_SSA, MediumLevelILOperation.MLIL_VAR_PHI]: @@ -851,6 +856,20 @@ class MediumLevelILFunction(object): core.BNFreeILInstructionList(instrs) return result + def is_ssa_var_live(self, ssa_var): + """ + ``is_ssa_var_live`` determines if ``ssa_var`` is live at any point in the function + + :param SSAVariable ssa_var: the SSA variable to query + :return: whether the variable is live at any point in the function + :rtype: bool + """ + var_data = core.BNVariable() + var_data.type = ssa_var.var.source_type + var_data.index = ssa_var.var.index + var_data.storage = ssa_var.var.storage + return core.BNIsMediumLevelILSSAVarLive(self.handle, var_data, ssa_var.version) + def get_var_definitions(self, var): count = ctypes.c_ulonglong() var_data = core.BNVariable() |
