From c659d6705bf7d7926dcdeb1defabad5945d414da Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Mon, 30 Aug 2021 15:35:49 -0400 Subject: Commonize all possible IL base classes in commonil.py --- python/__init__.py | 1 + python/commonil.py | 147 ++++++ python/highlevelil.py | 319 +++++------- python/lowlevelil.py | 1274 ++++++++++++++++++++++++++++------------------- python/mediumlevelil.py | 891 +++++++++++++++++++++------------ 5 files changed, 1609 insertions(+), 1023 deletions(-) create mode 100644 python/commonil.py (limited to 'python') diff --git a/python/__init__.py b/python/__init__.py index 734add95..09701f46 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -65,6 +65,7 @@ from .datarender import * from .variable import * from .websocketprovider import * from .workflow import * +from .commonil import * def shutdown(): diff --git a/python/commonil.py b/python/commonil.py new file mode 100644 index 00000000..4a079f02 --- /dev/null +++ b/python/commonil.py @@ -0,0 +1,147 @@ +# Copyright (c) 2019-2021 Vector 35 Inc +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +from dataclasses import dataclass + + +# This file contains a list of top level abstract classes for implementing BNIL instructions + +@dataclass(frozen=True, repr=False) +class Constant: + pass + + +@dataclass(frozen=True, repr=False) +class BinaryOperation: + pass + + +@dataclass(frozen=True, repr=False) +class UnaryOperation: + pass + + +@dataclass(frozen=True, repr=False) +class Comparison(BinaryOperation): + pass + + +@dataclass(frozen=True, repr=False) +class SSA: + pass + + +@dataclass(frozen=True, repr=False) +class Phi(SSA): + pass + + +@dataclass(frozen=True, repr=False) +class FloatingPoint: + pass + + +@dataclass(frozen=True, repr=False) +class ControlFlow: + pass + + +@dataclass(frozen=True, repr=False) +class Terminal(ControlFlow): + pass + + +@dataclass(frozen=True, repr=False) +class Loop(ControlFlow): + pass + + +@dataclass(frozen=True, repr=False) +class Call(ControlFlow): + pass + + +@dataclass(frozen=True, repr=False) +class Syscall(Call): + pass + + +@dataclass(frozen=True, repr=False) +class Tailcall(Call): + pass + +@dataclass(frozen=True, repr=False) +class Return(Terminal): + pass + + +@dataclass(frozen=True, repr=False) +class Signed: + pass + + +@dataclass(frozen=True, repr=False) +class Arithmetic: + pass + + +@dataclass(frozen=True, repr=False) +class Carry(Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class DoublePrecision(Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class Memory: + pass + + +@dataclass(frozen=True, repr=False) +class Load: + pass + + +@dataclass(frozen=True, repr=False) +class Store: + pass + + +@dataclass(frozen=True, repr=False) +class RegisterStack: + pass + + +@dataclass(frozen=True, repr=False) +class SetVar: + pass + + +@dataclass(frozen=True, repr=False) +class StackOperation: + pass + + +@dataclass(frozen=True, repr=False) +class SetReg: + pass diff --git a/python/highlevelil.py b/python/highlevelil.py index 239e51b4..94b6dbfb 100644 --- a/python/highlevelil.py +++ b/python/highlevelil.py @@ -37,6 +37,9 @@ from . import types from . import highlight from . import flowgraph from . import variable +from .commonil import (Call, Tailcall, Syscall, Comparison, Signed, UnaryOperation, BinaryOperation, + SSA, Phi, Loop, ControlFlow, Memory, Constant, Arithmetic, DoublePrecision, Terminal, + FloatingPoint) LinesType = Generator['function.DisassemblyTextLine', None, None] ExpressionIndex = NewType('ExpressionIndex', int) @@ -101,7 +104,7 @@ class GotoLabel: core.BNSetUserGotoLabelName(self.function.source_function.handle, self.id, value) @property - def definition(self): + def definition(self) -> Optional['HighLevelILInstruction']: return self.function.get_label(self.id) @property @@ -643,39 +646,7 @@ class HighLevelILInstruction: @dataclass(frozen=True, repr=False) -class Arithmetic(HighLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class Memory(HighLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class ControlFlow(HighLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class Loop(ControlFlow): - pass - - -@dataclass(frozen=True, repr=False) -class Call(ControlFlow): - - @property - def params(self) -> List[HighLevelILInstruction]: - return NotImplemented - - @property - def vars(self) -> VariablesList: - return [v for i in self.params for v in i.vars] - - -@dataclass(frozen=True, repr=False) -class UnaryOperation(HighLevelILInstruction): +class HighLevelILUnaryBase(UnaryOperation, HighLevelILInstruction): @property def src(self) -> HighLevelILInstruction: @@ -695,7 +666,7 @@ class UnaryOperation(HighLevelILInstruction): @dataclass(frozen=True, repr=False) -class BinaryOperation(HighLevelILInstruction): +class HighLevelILBinaryBase(BinaryOperation, HighLevelILInstruction): @property def left(self) -> HighLevelILInstruction: @@ -719,7 +690,7 @@ class BinaryOperation(HighLevelILInstruction): @dataclass(frozen=True, repr=False) -class Carry(Arithmetic): +class HighLevelILCarryBase(Arithmetic, HighLevelILInstruction): @property def left(self) -> HighLevelILInstruction: @@ -745,60 +716,6 @@ class Carry(Arithmetic): def operands(self) -> List[HighLevelILOperandType]: return [self.left, self.right, self.carry] -@dataclass(frozen=True, repr=False) -class Comparison(BinaryOperation): - pass - - -@dataclass(frozen=True, repr=False) -class Constant(HighLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class SSA(HighLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class Phi(SSA): - pass - - -@dataclass(frozen=True, repr=False) -class FloatingPoint(HighLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class Terminal(ControlFlow): - pass - - -@dataclass(frozen=True, repr=False) -class Return(Terminal): - pass - - -@dataclass(frozen=True, repr=False) -class Signed(HighLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class DoublePrecision(Arithmetic): - pass - - -@dataclass(frozen=True, repr=False) -class Syscall(Call): - pass - - -@dataclass(frozen=True, repr=False) -class Tailcall(Call): - pass - @dataclass(frozen=True, repr=False) class HighLevelILNop(HighLevelILInstruction): @@ -826,7 +743,7 @@ class HighLevelILBlock(HighLevelILInstruction): @dataclass(frozen=True, repr=False) -class HighLevelILIf(ControlFlow): +class HighLevelILIf(ControlFlow, HighLevelILInstruction): @property def condition(self) -> HighLevelILInstruction: @@ -850,7 +767,7 @@ class HighLevelILIf(ControlFlow): @dataclass(frozen=True, repr=False) -class HighLevelILWhile(Loop): +class HighLevelILWhile(Loop, HighLevelILInstruction): @property def condition(self) -> HighLevelILInstruction: @@ -870,7 +787,7 @@ class HighLevelILWhile(Loop): @dataclass(frozen=True, repr=False) -class HighLevelILWhile_ssa(Loop, SSA): +class HighLevelILWhile_ssa(Loop, SSA, HighLevelILInstruction): @property def condition_phi(self) -> HighLevelILInstruction: @@ -894,7 +811,7 @@ class HighLevelILWhile_ssa(Loop, SSA): @dataclass(frozen=True, repr=False) -class HighLevelILDo_while(Loop): +class HighLevelILDo_while(Loop, HighLevelILInstruction): @property def body(self) -> HighLevelILInstruction: @@ -914,7 +831,7 @@ class HighLevelILDo_while(Loop): @dataclass(frozen=True, repr=False) -class HighLevelILDo_while_ssa(Loop, SSA): +class HighLevelILDo_while_ssa(Loop, SSA, HighLevelILInstruction): @property def body(self) -> HighLevelILInstruction: @@ -940,8 +857,9 @@ class HighLevelILDo_while_ssa(Loop, SSA): def operands(self) -> List[HighLevelILOperandType]: return [self.body, self.condition_phi, self.condition] + @dataclass(frozen=True, repr=False) -class HighLevelILFor(Loop): +class HighLevelILFor(Loop, HighLevelILInstruction): @property def init(self) -> HighLevelILInstruction: @@ -977,7 +895,7 @@ class HighLevelILFor(Loop): @dataclass(frozen=True, repr=False) -class HighLevelILFor_ssa(Loop, SSA): +class HighLevelILFor_ssa(Loop, SSA, HighLevelILInstruction): @property def init(self) -> HighLevelILInstruction: @@ -1017,7 +935,7 @@ class HighLevelILFor_ssa(Loop, SSA): @dataclass(frozen=True, repr=False) -class HighLevelILSwitch(ControlFlow): +class HighLevelILSwitch(ControlFlow, HighLevelILInstruction): @property def condition(self) -> HighLevelILInstruction: @@ -1065,16 +983,16 @@ class HighLevelILCase(HighLevelILInstruction): @dataclass(frozen=True, repr=False) -class HighLevelILBreak(Terminal): +class HighLevelILBreak(Terminal, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILContinue(ControlFlow): +class HighLevelILContinue(ControlFlow, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILJump(Terminal): +class HighLevelILJump(Terminal, HighLevelILInstruction): @property def dest(self) -> HighLevelILInstruction: @@ -1090,7 +1008,7 @@ class HighLevelILJump(Terminal): @dataclass(frozen=True, repr=False) -class HighLevelILRet(ControlFlow): +class HighLevelILRet(ControlFlow, HighLevelILInstruction): @property def src(self) -> List[HighLevelILInstruction]: @@ -1106,12 +1024,12 @@ class HighLevelILRet(ControlFlow): @dataclass(frozen=True, repr=False) -class HighLevelILNoret(Terminal): +class HighLevelILNoret(Terminal, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILGoto(Terminal): +class HighLevelILGoto(Terminal, HighLevelILInstruction): @property def target(self) -> GotoLabel: @@ -1149,6 +1067,7 @@ class HighLevelILVar_declare(HighLevelILInstruction): def operands(self) -> List[HighLevelILOperandType]: return [self.var] + @dataclass(frozen=True, repr=False) class HighLevelILVar_init(HighLevelILInstruction): @@ -1178,7 +1097,7 @@ class HighLevelILVar_init(HighLevelILInstruction): @dataclass(frozen=True, repr=False) -class HighLevelILVar_init_ssa(SSA): +class HighLevelILVar_init_ssa(SSA, HighLevelILInstruction): @property def dest(self) -> 'mediumlevelil.SSAVariable': @@ -1262,7 +1181,7 @@ class HighLevelILAssign_unpack(HighLevelILInstruction): @dataclass(frozen=True, repr=False) -class HighLevelILAssign_mem_ssa(SSA): +class HighLevelILAssign_mem_ssa(SSA, HighLevelILInstruction): @property def dest(self) -> HighLevelILInstruction: @@ -1286,7 +1205,7 @@ class HighLevelILAssign_mem_ssa(SSA): @dataclass(frozen=True, repr=False) -class HighLevelILAssign_unpack_mem_ssa(SSA): +class HighLevelILAssign_unpack_mem_ssa(SSA, Memory, HighLevelILInstruction): @property def dest(self) -> List[HighLevelILInstruction]: @@ -1332,8 +1251,9 @@ class HighLevelILVar(HighLevelILInstruction): def operands(self) -> List[HighLevelILOperandType]: return [self.var] + @dataclass(frozen=True, repr=False) -class HighLevelILVar_ssa(SSA): +class HighLevelILVar_ssa(SSA, HighLevelILInstruction): @property def var(self) -> 'mediumlevelil.SSAVariable': @@ -1347,8 +1267,9 @@ class HighLevelILVar_ssa(SSA): def operands(self) -> List[HighLevelILOperandType]: return [self.var] + @dataclass(frozen=True, repr=False) -class HighLevelILVar_phi(Phi): +class HighLevelILVar_phi(Phi, HighLevelILInstruction): @property def dest(self) -> 'mediumlevelil.SSAVariable': @@ -1376,7 +1297,7 @@ class HighLevelILVar_phi(Phi): @dataclass(frozen=True, repr=False) -class HighLevelILMem_phi(Memory, Phi): +class HighLevelILMem_phi(Memory, Phi, HighLevelILInstruction): @property def dest(self) -> int: @@ -1435,12 +1356,12 @@ class HighLevelILArray_index(HighLevelILInstruction): return [self.src, self.index] @property - def vars_used_in_address(self): - return self.src + def vars_used_in_address(self) -> VariablesList: + return self.src.vars @dataclass(frozen=True, repr=False) -class HighLevelILArray_index_ssa(SSA): +class HighLevelILArray_index_ssa(SSA, HighLevelILInstruction): @property def src(self) -> HighLevelILInstruction: @@ -1459,8 +1380,8 @@ class HighLevelILArray_index_ssa(SSA): return [*self.src.vars, *self.index.vars] @property - def vars_used_in_address(self): - return self.src + def vars_used_in_address(self) -> VariablesList: + return self.src.vars @property def operands(self) -> List[HighLevelILOperandType]: @@ -1488,7 +1409,7 @@ class HighLevelILSplit(HighLevelILInstruction): @dataclass(frozen=True, repr=False) -class HighLevelILDeref(UnaryOperation): +class HighLevelILDeref(HighLevelILUnaryBase): @property def vars_used_in_address(self): @@ -1524,7 +1445,7 @@ class HighLevelILDeref_field(HighLevelILInstruction): @dataclass(frozen=True, repr=False) -class HighLevelILDeref_ssa(SSA): +class HighLevelILDeref_ssa(SSA, HighLevelILInstruction): @property def src(self) -> HighLevelILInstruction: @@ -1548,7 +1469,7 @@ class HighLevelILDeref_ssa(SSA): @dataclass(frozen=True, repr=False) -class HighLevelILDeref_field_ssa(SSA): +class HighLevelILDeref_field_ssa(SSA, HighLevelILInstruction): @property def src(self) -> HighLevelILInstruction: @@ -1580,7 +1501,7 @@ class HighLevelILDeref_field_ssa(SSA): @dataclass(frozen=True, repr=False) -class HighLevelILAddress_of(UnaryOperation): +class HighLevelILAddress_of(HighLevelILUnaryBase): @property def vars(self) -> VariablesList: @@ -1596,7 +1517,7 @@ class HighLevelILAddress_of(UnaryOperation): @dataclass(frozen=True, repr=False) -class HighLevelILConst(Constant): +class HighLevelILConst(Constant, HighLevelILInstruction): @property def constant(self) -> int: @@ -1608,7 +1529,7 @@ class HighLevelILConst(Constant): @dataclass(frozen=True, repr=False) -class HighLevelILConst_ptr(Constant): +class HighLevelILConst_ptr(Constant, HighLevelILInstruction): @property def constant(self) -> int: @@ -1620,7 +1541,7 @@ class HighLevelILConst_ptr(Constant): @dataclass(frozen=True, repr=False) -class HighLevelILExtern_ptr(Constant): +class HighLevelILExtern_ptr(Constant, HighLevelILInstruction): @property def constant(self) -> int: @@ -1636,7 +1557,7 @@ class HighLevelILExtern_ptr(Constant): @dataclass(frozen=True, repr=False) -class HighLevelILFloat_const(Constant): +class HighLevelILFloat_const(Constant, HighLevelILInstruction): @property def constant(self) -> float: @@ -1648,7 +1569,7 @@ class HighLevelILFloat_const(Constant): @dataclass(frozen=True, repr=False) -class HighLevelILImport(Constant): +class HighLevelILImport(Constant, HighLevelILInstruction): @property def constant(self) -> int: @@ -1660,157 +1581,157 @@ class HighLevelILImport(Constant): @dataclass(frozen=True, repr=False) -class HighLevelILAdd(Arithmetic, BinaryOperation): +class HighLevelILAdd(Arithmetic, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILAdc(Carry): +class HighLevelILAdc(HighLevelILCarryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILSub(Arithmetic, BinaryOperation): +class HighLevelILSub(Arithmetic, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILSbb(Carry): +class HighLevelILSbb(HighLevelILCarryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILAnd(Arithmetic, BinaryOperation): +class HighLevelILAnd(Arithmetic, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILOr(Arithmetic, BinaryOperation): +class HighLevelILOr(Arithmetic, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILXor(Arithmetic, BinaryOperation): +class HighLevelILXor(Arithmetic, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILLsl(Arithmetic, BinaryOperation): +class HighLevelILLsl(Arithmetic, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILLsr(Arithmetic, BinaryOperation): +class HighLevelILLsr(Arithmetic, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILAsr(Arithmetic, BinaryOperation): +class HighLevelILAsr(Arithmetic, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILRol(Arithmetic, BinaryOperation): +class HighLevelILRol(Arithmetic, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILRlc(Carry): +class HighLevelILRlc(HighLevelILCarryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILRor(Carry): +class HighLevelILRor(HighLevelILCarryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILRrc(Carry): +class HighLevelILRrc(HighLevelILCarryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILMul(Arithmetic, BinaryOperation): +class HighLevelILMul(Arithmetic, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILMulu_dp(BinaryOperation, DoublePrecision): +class HighLevelILMulu_dp(HighLevelILBinaryBase, DoublePrecision): pass @dataclass(frozen=True, repr=False) -class HighLevelILMuls_dp(Signed, BinaryOperation, DoublePrecision): +class HighLevelILMuls_dp(Signed, HighLevelILBinaryBase, DoublePrecision): pass @dataclass(frozen=True, repr=False) -class HighLevelILDivu(Arithmetic, BinaryOperation): +class HighLevelILDivu(Arithmetic, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILDivu_dp(BinaryOperation, DoublePrecision): +class HighLevelILDivu_dp(HighLevelILBinaryBase, DoublePrecision): pass @dataclass(frozen=True, repr=False) -class HighLevelILDivs(Signed, BinaryOperation): +class HighLevelILDivs(Signed, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILDivs_dp(Signed, BinaryOperation, DoublePrecision): +class HighLevelILDivs_dp(Signed, HighLevelILBinaryBase, DoublePrecision): pass @dataclass(frozen=True, repr=False) -class HighLevelILModu(Arithmetic, BinaryOperation): +class HighLevelILModu(Arithmetic, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILModu_dp(BinaryOperation, DoublePrecision): +class HighLevelILModu_dp(HighLevelILBinaryBase, DoublePrecision): pass @dataclass(frozen=True, repr=False) -class HighLevelILMods(Signed, BinaryOperation): +class HighLevelILMods(Signed, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILMods_dp(Signed, BinaryOperation, DoublePrecision): +class HighLevelILMods_dp(Signed, HighLevelILBinaryBase, DoublePrecision): pass @dataclass(frozen=True, repr=False) -class HighLevelILNeg(Arithmetic, UnaryOperation): +class HighLevelILNeg(Arithmetic, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILNot(Arithmetic, UnaryOperation): +class HighLevelILNot(Arithmetic, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILSx(Arithmetic, UnaryOperation): +class HighLevelILSx(Arithmetic, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILZx(Arithmetic, UnaryOperation): +class HighLevelILZx(Arithmetic, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILLow_part(Arithmetic, UnaryOperation): +class HighLevelILLow_part(Arithmetic, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILCall(Call): +class HighLevelILCall(Call, HighLevelILInstruction): @property def dest(self) -> HighLevelILInstruction: @@ -1834,7 +1755,7 @@ class HighLevelILCall(Call): @dataclass(frozen=True, repr=False) -class HighLevelILCall_ssa(Call, SSA): +class HighLevelILCall_ssa(Call, SSA, HighLevelILInstruction): @property def dest(self) -> HighLevelILInstruction: @@ -1866,72 +1787,72 @@ class HighLevelILCall_ssa(Call, SSA): @dataclass(frozen=True, repr=False) -class HighLevelILCmp_e(Comparison): +class HighLevelILCmp_e(Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILCmp_ne(Comparison): +class HighLevelILCmp_ne(Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILCmp_slt(Comparison, Signed): +class HighLevelILCmp_slt(Comparison, Signed, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILCmp_ult(Comparison): +class HighLevelILCmp_ult(Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILCmp_sle(Comparison, Signed): +class HighLevelILCmp_sle(Comparison, Signed, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILCmp_ule(Comparison): +class HighLevelILCmp_ule(Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILCmp_sge(Comparison, Signed): +class HighLevelILCmp_sge(Comparison, Signed, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILCmp_uge(Comparison): +class HighLevelILCmp_uge(Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILCmp_sgt(Comparison, Signed): +class HighLevelILCmp_sgt(Comparison, Signed, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILCmp_ugt(Comparison): +class HighLevelILCmp_ugt(Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILTest_bit(Comparison): +class HighLevelILTest_bit(Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILBool_to_int(UnaryOperation): +class HighLevelILBool_to_int(HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILAdd_overflow(Arithmetic, BinaryOperation): +class HighLevelILAdd_overflow(Arithmetic, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILSyscall(Syscall): +class HighLevelILSyscall(Syscall, HighLevelILInstruction): @property def params(self) -> List[HighLevelILInstruction]: @@ -1951,7 +1872,7 @@ class HighLevelILSyscall(Syscall): @dataclass(frozen=True, repr=False) -class HighLevelILSyscall_ssa(Syscall, SSA): +class HighLevelILSyscall_ssa(Syscall, SSA, HighLevelILInstruction): @property def params(self) -> List[HighLevelILInstruction]: @@ -1979,7 +1900,7 @@ class HighLevelILSyscall_ssa(Syscall, SSA): @dataclass(frozen=True, repr=False) -class HighLevelILTailcall(Tailcall): +class HighLevelILTailcall(Tailcall, HighLevelILInstruction): @property def dest(self) -> HighLevelILInstruction: @@ -2004,12 +1925,12 @@ class HighLevelILTailcall(Tailcall): @dataclass(frozen=True, repr=False) -class HighLevelILBp(Terminal): +class HighLevelILBp(Terminal, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILTrap(Terminal): +class HighLevelILTrap(Terminal, HighLevelILInstruction): @property def vector(self) -> int: @@ -2045,7 +1966,7 @@ class HighLevelILIntrinsic(HighLevelILInstruction): @dataclass(frozen=True, repr=False) -class HighLevelILIntrinsic_ssa(SSA): +class HighLevelILIntrinsic_ssa(SSA, HighLevelILInstruction): @property def intrinsic(self) -> 'lowlevelil.ILIntrinsic': @@ -2077,7 +1998,7 @@ class HighLevelILIntrinsic_ssa(SSA): @dataclass(frozen=True, repr=False) -class HighLevelILUndef(Terminal): +class HighLevelILUndef(Terminal, HighLevelILInstruction): pass @@ -2087,117 +2008,117 @@ class HighLevelILUnimpl(HighLevelILInstruction): @dataclass(frozen=True, repr=False) -class HighLevelILUnimpl_mem(Memory, UnaryOperation): +class HighLevelILUnimpl_mem(Memory, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILFadd(FloatingPoint, BinaryOperation): +class HighLevelILFadd(FloatingPoint, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILFsub(FloatingPoint, BinaryOperation): +class HighLevelILFsub(FloatingPoint, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILFmul(FloatingPoint, BinaryOperation): +class HighLevelILFmul(FloatingPoint, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILFdiv(FloatingPoint, BinaryOperation): +class HighLevelILFdiv(FloatingPoint, HighLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILFsqrt(FloatingPoint, UnaryOperation): +class HighLevelILFsqrt(FloatingPoint, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILFneg(FloatingPoint, UnaryOperation): +class HighLevelILFneg(FloatingPoint, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILFabs(FloatingPoint, UnaryOperation): +class HighLevelILFabs(FloatingPoint, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILFloat_to_int(FloatingPoint, UnaryOperation): +class HighLevelILFloat_to_int(FloatingPoint, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILInt_to_float(FloatingPoint, UnaryOperation): +class HighLevelILInt_to_float(FloatingPoint, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILFloat_conv(FloatingPoint, UnaryOperation): +class HighLevelILFloat_conv(FloatingPoint, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILRound_to_int(FloatingPoint, UnaryOperation): +class HighLevelILRound_to_int(FloatingPoint, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILFloor(FloatingPoint, UnaryOperation): +class HighLevelILFloor(FloatingPoint, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILCeil(FloatingPoint, UnaryOperation): +class HighLevelILCeil(FloatingPoint, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILFtrunc(FloatingPoint, UnaryOperation): +class HighLevelILFtrunc(FloatingPoint, HighLevelILUnaryBase): pass @dataclass(frozen=True, repr=False) -class HighLevelILFcmp_e(FloatingPoint, Comparison): +class HighLevelILFcmp_e(FloatingPoint, Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILFcmp_ne(FloatingPoint, Comparison): +class HighLevelILFcmp_ne(FloatingPoint, Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILFcmp_lt(FloatingPoint, Comparison): +class HighLevelILFcmp_lt(FloatingPoint, Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILFcmp_le(FloatingPoint, Comparison): +class HighLevelILFcmp_le(FloatingPoint, Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILFcmp_ge(FloatingPoint, Comparison): +class HighLevelILFcmp_ge(FloatingPoint, Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILFcmp_gt(FloatingPoint, Comparison): +class HighLevelILFcmp_gt(FloatingPoint, Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILFcmp_o(FloatingPoint, Comparison): +class HighLevelILFcmp_o(FloatingPoint, Comparison, HighLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class HighLevelILFcmp_uo(FloatingPoint, Comparison): +class HighLevelILFcmp_uo(FloatingPoint, Comparison, HighLevelILInstruction): pass diff --git a/python/lowlevelil.py b/python/lowlevelil.py index ae590c21..dc983362 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -19,9 +19,8 @@ # IN THE SOFTWARE. import ctypes -from enum import Flag import struct -from typing import Generator, List, Optional, Mapping, Union, Tuple, NewType +from typing import Generator, List, Optional, Mapping, Union, Tuple, NewType, ClassVar from dataclasses import dataclass # Binary Ninja components @@ -36,6 +35,9 @@ from . import variable from . import binaryview from . import architecture from . import types +from .commonil import (Constant, BinaryOperation, UnaryOperation, Comparison, SSA, + Phi, FloatingPoint, ControlFlow, Terminal, Call, StackOperation, Return, + Signed, Arithmetic, Carry, DoublePrecision, Memory, Load, Store, RegisterStack, SetReg) ExpressionIndex = NewType('ExpressionIndex', int) InstructionIndex = NewType('InstructionIndex', int) @@ -46,6 +48,31 @@ ILRegisterType = Union[str, 'ILRegister', int] LLILInstructionsType = Generator['LowLevelILInstruction', None, None] LLILBasicBlocksType = Generator['LowLevelILBasicBlock', None, None] OperandsType = Tuple[ExpressionIndex, ExpressionIndex, ExpressionIndex, ExpressionIndex] +LowLevelILOperandType = Union[ + 'LowLevelILOperationAndSize', + 'ILRegister', + 'ILFlag', + 'ILIntrinsic', + 'ILRegisterStack', + int, + Mapping[int, int], + float, + 'LowLevelILInstruction', + Mapping['architecture.RegisterStackName', int], + 'SSAFlag', + 'SSARegister', + 'SSARegisterStack', + 'ILSemanticFlagClass', + 'ILSemanticFlagGroup', + 'LowLevelILFlagCondition', + List[int], + List['LowLevelILInstruction'], + List[Union['ILFlag', 'ILRegister']], + List['SSARegister'], + List['SSARegisterStack'], + List['SSAFlag'], + List['SSARegisterOrFlag'], +] class LowLevelILLabel: def __init__(self, handle:core.BNLowLevelILLabel=None): @@ -132,7 +159,7 @@ class ILFlag: return self.index @property - def temp(self): + def temp(self) -> bool: return (self.index & 0x80000000) != 0 @property @@ -253,31 +280,6 @@ class LowLevelILOperationAndSize: return f"<{self.operation.name}>" return f"<{self.operation.name} {self.size}>" -LowLevelILOperandType = Union[ - LowLevelILOperationAndSize, - ILRegister, - ILFlag, - ILIntrinsic, - ILRegisterStack, - int, - Mapping[int, int], - float, - 'LowLevelILInstruction', - Mapping['architecture.RegisterStackName', int], - SSAFlag, - SSARegister, - SSARegisterStack, - ILSemanticFlagClass, - ILSemanticFlagGroup, - LowLevelILFlagCondition, - List[int], - List['LowLevelILInstruction'], - List[Union[ILFlag, ILRegister]], - List[SSARegister], - List[SSARegisterStack], - List[SSAFlag], - List[SSARegisterOrFlag], -] @dataclass(frozen=True) class CoreLowLevelILInstruction: @@ -306,7 +308,143 @@ class LowLevelILInstruction: expr_index:ExpressionIndex instr:CoreLowLevelILInstruction instr_index:Optional[InstructionIndex] - operand_names = tuple() + ILOperations:ClassVar[Mapping[LowLevelILOperation, List[Tuple[str,str]]]] = { + LowLevelILOperation.LLIL_NOP: [], + LowLevelILOperation.LLIL_SET_REG: [("dest", "reg"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_SPLIT: [("hi", "reg"), ("lo", "reg"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_STACK_REL: [("stack", "reg_stack"), ("dest", "expr"), ("src", "expr")], + LowLevelILOperation.LLIL_REG_STACK_PUSH: [("stack", "reg_stack"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_FLAG: [("dest", "flag"), ("src", "expr")], + LowLevelILOperation.LLIL_LOAD: [("src", "expr")], + LowLevelILOperation.LLIL_STORE: [("dest", "expr"), ("src", "expr")], + LowLevelILOperation.LLIL_PUSH: [("src", "expr")], + LowLevelILOperation.LLIL_POP: [], + LowLevelILOperation.LLIL_REG: [("src", "reg")], + LowLevelILOperation.LLIL_REG_SPLIT: [("hi", "reg"), ("lo", "reg")], + LowLevelILOperation.LLIL_REG_STACK_REL: [("stack", "reg_stack"), ("src", "expr")], + LowLevelILOperation.LLIL_REG_STACK_POP: [("stack", "reg_stack")], + LowLevelILOperation.LLIL_REG_STACK_FREE_REG: [("dest", "reg")], + LowLevelILOperation.LLIL_REG_STACK_FREE_REL: [("stack", "reg_stack"), ("dest", "expr")], + LowLevelILOperation.LLIL_CONST: [("constant", "int")], + LowLevelILOperation.LLIL_CONST_PTR: [("constant", "int")], + LowLevelILOperation.LLIL_EXTERN_PTR: [("constant", "int"), ("offset", "int")], + LowLevelILOperation.LLIL_FLOAT_CONST: [("constant", "float")], + LowLevelILOperation.LLIL_FLAG: [("src", "flag")], + LowLevelILOperation.LLIL_FLAG_BIT: [("src", "flag"), ("bit", "int")], + LowLevelILOperation.LLIL_ADD: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_ADC: [("left", "expr"), ("right", "expr"), ("carry", "expr")], + LowLevelILOperation.LLIL_SUB: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_SBB: [("left", "expr"), ("right", "expr"), ("carry", "expr")], + LowLevelILOperation.LLIL_AND: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_OR: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_XOR: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_LSL: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_LSR: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_ASR: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_ROL: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_RLC: [("left", "expr"), ("right", "expr"), ("carry", "expr")], + LowLevelILOperation.LLIL_ROR: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_RRC: [("left", "expr"), ("right", "expr"), ("carry", "expr")], + LowLevelILOperation.LLIL_MUL: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MULU_DP: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MULS_DP: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_DIVU: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_DIVU_DP: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_DIVS: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_DIVS_DP: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MODU: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MODU_DP: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MODS: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MODS_DP: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_NEG: [("src", "expr")], + LowLevelILOperation.LLIL_NOT: [("src", "expr")], + LowLevelILOperation.LLIL_SX: [("src", "expr")], + LowLevelILOperation.LLIL_ZX: [("src", "expr")], + LowLevelILOperation.LLIL_LOW_PART: [("src", "expr")], + LowLevelILOperation.LLIL_JUMP: [("dest", "expr")], + LowLevelILOperation.LLIL_JUMP_TO: [("dest", "expr"), ("targets", "target_map")], + 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")], + LowLevelILOperation.LLIL_GOTO: [("dest", "int")], + LowLevelILOperation.LLIL_FLAG_COND: [("condition", "cond"), ("semantic_class", "sem_class")], + LowLevelILOperation.LLIL_FLAG_GROUP: [("semantic_group", "sem_group")], + LowLevelILOperation.LLIL_CMP_E: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_NE: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_SLT: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_ULT: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_SLE: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_ULE: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_SGE: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_UGE: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_SGT: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_UGT: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_TEST_BIT: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_BOOL_TO_INT: [("src", "expr")], + LowLevelILOperation.LLIL_ADD_OVERFLOW: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_SYSCALL: [], + LowLevelILOperation.LLIL_INTRINSIC: [("output", "reg_or_flag_list"), ("intrinsic", "intrinsic"), ("param", "expr")], + LowLevelILOperation.LLIL_INTRINSIC_SSA: [("output", "reg_or_flag_ssa_list"), ("intrinsic", "intrinsic"), ("param", "expr")], + LowLevelILOperation.LLIL_BP: [], + LowLevelILOperation.LLIL_TRAP: [("vector", "int")], + LowLevelILOperation.LLIL_UNDEF: [], + LowLevelILOperation.LLIL_UNIMPL: [], + LowLevelILOperation.LLIL_UNIMPL_MEM: [("src", "expr")], + LowLevelILOperation.LLIL_FADD: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FSUB: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FMUL: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FDIV: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FSQRT: [("src", "expr")], + LowLevelILOperation.LLIL_FNEG: [("src", "expr")], + LowLevelILOperation.LLIL_FABS: [("src", "expr")], + LowLevelILOperation.LLIL_FLOAT_TO_INT: [("src", "expr")], + LowLevelILOperation.LLIL_INT_TO_FLOAT: [("src", "expr")], + LowLevelILOperation.LLIL_FLOAT_CONV: [("src", "expr")], + LowLevelILOperation.LLIL_ROUND_TO_INT: [("src", "expr")], + LowLevelILOperation.LLIL_FLOOR: [("src", "expr")], + LowLevelILOperation.LLIL_CEIL: [("src", "expr")], + LowLevelILOperation.LLIL_FTRUNC: [("src", "expr")], + LowLevelILOperation.LLIL_FCMP_E: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_NE: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_LT: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_LE: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_GE: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_GT: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_O: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_UO: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_SET_REG_SSA: [("dest", "reg_ssa"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_SSA_PARTIAL: [("full_reg", "reg_ssa"), ("dest", "reg"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_SPLIT_SSA: [("hi", "expr"), ("lo", "expr"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_STACK_REL_SSA: [("stack", "expr"), ("dest", "expr"), ("top", "expr"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_STACK_ABS_SSA: [("stack", "expr"), ("dest", "reg"), ("src", "expr")], + LowLevelILOperation.LLIL_REG_SPLIT_DEST_SSA: [("dest", "reg_ssa")], + LowLevelILOperation.LLIL_REG_STACK_DEST_SSA: [("src", "reg_stack_ssa_dest_and_src")], + LowLevelILOperation.LLIL_REG_SSA: [("src", "reg_ssa")], + LowLevelILOperation.LLIL_REG_SSA_PARTIAL: [("full_reg", "reg_ssa"), ("src", "reg")], + LowLevelILOperation.LLIL_REG_SPLIT_SSA: [("hi", "reg_ssa"), ("lo", "reg_ssa")], + LowLevelILOperation.LLIL_REG_STACK_REL_SSA: [("stack", "reg_stack_ssa"), ("src", "expr"), ("top", "expr")], + LowLevelILOperation.LLIL_REG_STACK_ABS_SSA: [("stack", "reg_stack_ssa"), ("src", "reg")], + LowLevelILOperation.LLIL_REG_STACK_FREE_REL_SSA: [("stack", "expr"), ("dest", "expr"), ("top", "expr")], + LowLevelILOperation.LLIL_REG_STACK_FREE_ABS_SSA: [("stack", "expr"), ("dest", "reg")], + LowLevelILOperation.LLIL_SET_FLAG_SSA: [("dest", "flag_ssa"), ("src", "expr")], + LowLevelILOperation.LLIL_FLAG_SSA: [("src", "flag_ssa")], + 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")], + LowLevelILOperation.LLIL_LOAD_SSA: [("src", "expr"), ("src_memory", "int")], + LowLevelILOperation.LLIL_STORE_SSA: [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], + LowLevelILOperation.LLIL_REG_PHI: [("dest", "reg_ssa"), ("src", "reg_ssa_list")], + LowLevelILOperation.LLIL_REG_STACK_PHI: [("dest", "reg_stack_ssa"), ("src", "reg_stack_ssa_list")], + LowLevelILOperation.LLIL_FLAG_PHI: [("dest", "flag_ssa"), ("src", "flag_ssa_list")], + LowLevelILOperation.LLIL_MEM_PHI: [("dest_memory", "int"), ("src_memory", "int_list")] + } @classmethod def create(cls, func:'LowLevelILFunction', expr_index:ExpressionIndex, instr_index:Optional[InstructionIndex]=None) -> 'LowLevelILInstruction': @@ -489,10 +627,8 @@ class LowLevelILInstruction: return result @property - def operands(self) -> Generator[LowLevelILOperandType, None, None]: - for operand_name in self.operand_names: - assert hasattr(self, operand_name), f"No operand '{operand_name}' for instruction {repr(self)}({self.operation})" - yield self.__getattribute__(operand_name) + def operands(self) -> List[LowLevelILOperandType]: + return [] @property def prefix_operands(self) -> List[LowLevelILOperandType]: @@ -840,13 +976,7 @@ class LowLevelILInstruction: @dataclass(frozen=True, repr=False) -class Terminal(LowLevelILInstruction): - """This class indicates that the instruction ends a BasicBlock""" - pass - -@dataclass(frozen=True, repr=False) -class BinaryOperation(LowLevelILInstruction): - operand_names = tuple(['left', 'right']) +class LowLevelILBinaryBase(LowLevelILInstruction, BinaryOperation): @property def left(self) -> LowLevelILInstruction: @@ -856,41 +986,50 @@ class BinaryOperation(LowLevelILInstruction): def right(self) -> LowLevelILInstruction: return self.get_expr(1) - -@dataclass(frozen=True, repr=False) -class UnaryOperation(LowLevelILInstruction): - operand_names = tuple(['src']) - @property - def src(self) -> LowLevelILInstruction: - return self.get_expr(0) + def operands(self) -> List[LowLevelILOperandType]: + return [self.left, self.right] @dataclass(frozen=True, repr=False) -class Arithmetic(LowLevelILInstruction): +class LowLevelILComparisonBase(LowLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class Signed(LowLevelILInstruction): - """The operation is a signed operation""" - pass +class LowLevelILCarryBase(LowLevelILInstruction, Carry): + @property + def left(self) -> LowLevelILInstruction: + return self.get_expr(0) -@dataclass(frozen=True, repr=False) -class Carry(LowLevelILInstruction): - """Arithmetic with carry operation""" - pass + @property + def right(self) -> LowLevelILInstruction: + return self.get_expr(1) + + @property + def carry(self) -> LowLevelILInstruction: + return self.get_expr(2) + + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.left, self.right, self.carry] @dataclass(frozen=True, repr=False) -class Comparison(BinaryOperation): - pass +class LowLevelILUnaryBase(LowLevelILInstruction, UnaryOperation): + + @property + def src(self) -> LowLevelILInstruction: + return self.get_expr(0) + + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] @dataclass(frozen=True, repr=False) -class Constant(LowLevelILInstruction): - operand_names = tuple(['constant']) +class LowLevelILConstantBase(LowLevelILInstruction, Constant): def __int__(self): return self.constant @@ -899,1350 +1038,1467 @@ class Constant(LowLevelILInstruction): return self.constant != 0 def __eq__(self, other): - return int(self) == int(other) + return self.constant == other.constant def __ne__(self, other): - return int(self) != int(other) + return self.constant != other.constant def __lt__(self, other): - return int(self) < int(other) + return self.constant < other.constant def __gt__(self, other): - return int(self) > int(other) + return self.constant > other.constant def __le__(self, other): - return int(self) <= int(other) + return self.constant <= other.constant def __ge__(self, other): - return int(self) >= int(other) + return self.constant >= other.constant @property def constant(self) -> int: return self.get_int(0) - -@dataclass(frozen=True, repr=False) -class FloatingPoint(LowLevelILInstruction): - pass + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.constant] @dataclass(frozen=True, repr=False) -class ControlFlow(LowLevelILInstruction): +class LowLevelILNop(LowLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class Memory(LowLevelILInstruction): +class LowLevelILPop(LowLevelILInstruction, StackOperation): pass @dataclass(frozen=True, repr=False) -class Return(Terminal): +class LowLevelILNoret(LowLevelILInstruction, Terminal): pass @dataclass(frozen=True, repr=False) -class RegisterStack(LowLevelILInstruction): +class LowLevelILSyscall(LowLevelILInstruction, Call): pass @dataclass(frozen=True, repr=False) -class SSA(LowLevelILInstruction): +class LowLevelILBp(LowLevelILInstruction, Terminal): pass @dataclass(frozen=True, repr=False) -class StackOperation(LowLevelILInstruction): +class LowLevelILUndef(LowLevelILInstruction, Terminal): pass @dataclass(frozen=True, repr=False) -class SetReg(LowLevelILInstruction): +class LowLevelILUnimpl(LowLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class DoublePrecision(LowLevelILInstruction): +class LowLevelILNeg(LowLevelILUnaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class Store(Memory): +class LowLevelILNot(LowLevelILUnaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class Load(Memory): +class LowLevelILSx(LowLevelILUnaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class Call(LowLevelILInstruction): +class LowLevelILZx(LowLevelILUnaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class LowLevelILNop(LowLevelILInstruction): - operand_names = tuple() +class LowLevelILLow_part(LowLevelILUnaryBase, Arithmetic): + pass @dataclass(frozen=True, repr=False) -class LowLevelILPop(StackOperation): - operand_names = tuple() +class LowLevelILJump(LowLevelILInstruction, Terminal): + @property + def dest(self) -> LowLevelILInstruction: + return self.get_expr(0) -@dataclass(frozen=True, repr=False) -class LowLevelILNoret(Terminal): - operand_names = tuple() + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest] @dataclass(frozen=True, repr=False) -class LowLevelILSyscall(Call): - operand_names = tuple() +class LowLevelILCall(LowLevelILInstruction, Call): + @property + def dest(self) -> LowLevelILInstruction: + return self.get_expr(0) -@dataclass(frozen=True, repr=False) -class LowLevelILBp(Terminal): - operand_names = tuple() + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest] @dataclass(frozen=True, repr=False) -class LowLevelILUndef(Terminal): - operand_names = tuple() +class LowLevelILTailcall(LowLevelILInstruction, Call): + @property + def dest(self) -> LowLevelILInstruction: + return self.get_expr(0) -@dataclass(frozen=True, repr=False) -class LowLevelILUnimpl(LowLevelILInstruction): - operand_names = tuple() + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest] @dataclass(frozen=True, repr=False) -class LowLevelILNeg(UnaryOperation, Arithmetic): - pass +class LowLevelILRet(LowLevelILInstruction, Return): + @property + def dest(self) -> LowLevelILInstruction: + return self.get_expr(0) -@dataclass(frozen=True, repr=False) -class LowLevelILNot(UnaryOperation, Arithmetic): - pass - + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest] -@dataclass(frozen=True, repr=False) -class LowLevelILSx(UnaryOperation, Arithmetic): - pass @dataclass(frozen=True, repr=False) -class LowLevelILZx(UnaryOperation, Arithmetic): - pass +class LowLevelILUnimpl_mem(LowLevelILInstruction, Memory): + @property + def src(self) -> LowLevelILInstruction: + return self.get_expr(0) -@dataclass(frozen=True, repr=False) -class LowLevelILLow_part(UnaryOperation, Arithmetic): - pass + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] @dataclass(frozen=True, repr=False) -class LowLevelILJump(ControlFlow, Terminal): - operand_names = tuple(["dest"]) +class LowLevelILFsqrt(LowLevelILInstruction, FloatingPoint, Arithmetic): @property - def dest(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) - -@dataclass(frozen=True, repr=False) -class LowLevelILCall(Call): - operand_names = tuple(["dest"]) - @property - def dest(self): - return self.get_expr(0) + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] @dataclass(frozen=True, repr=False) -class LowLevelILTailcall(Call): - operand_names = tuple(["dest"]) +class LowLevelILFneg(LowLevelILInstruction, FloatingPoint, Arithmetic): @property - def dest(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) - -@dataclass(frozen=True, repr=False) -class LowLevelILRet(Return): - operand_names = tuple(["dest"]) - @property - def dest(self): - return self.get_expr(0) + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] @dataclass(frozen=True, repr=False) -class LowLevelILUnimpl_mem(Memory): - operand_names = tuple(["src"]) +class LowLevelILFabs(LowLevelILInstruction, FloatingPoint, Arithmetic): @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) - -@dataclass(frozen=True, repr=False) -class LowLevelILFsqrt(FloatingPoint, Arithmetic): - operand_names = tuple(["src"]) - @property - def src(self): - return self.get_expr(0) + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] @dataclass(frozen=True, repr=False) -class LowLevelILFneg(FloatingPoint, Arithmetic): - operand_names = tuple(["src"]) +class LowLevelILFloat_to_int(LowLevelILInstruction, FloatingPoint, Arithmetic): @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) - -@dataclass(frozen=True, repr=False) -class LowLevelILFabs(FloatingPoint, Arithmetic): - operand_names = tuple(["src"]) - @property - def src(self): - return self.get_expr(0) + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] @dataclass(frozen=True, repr=False) -class LowLevelILFloat_to_int(FloatingPoint, Arithmetic): - operand_names = tuple(["src"]) +class LowLevelILInt_to_float(LowLevelILInstruction, FloatingPoint, Arithmetic): @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) - -@dataclass(frozen=True, repr=False) -class LowLevelILInt_to_float(FloatingPoint, Arithmetic): - operand_names = tuple(["src"]) - @property - def src(self): - return self.get_expr(0) + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] @dataclass(frozen=True, repr=False) -class LowLevelILFloat_conv(FloatingPoint, Arithmetic): - operand_names = tuple(["src"]) +class LowLevelILFloat_conv(LowLevelILInstruction, FloatingPoint, Arithmetic): @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILRound_to_int(FloatingPoint, Arithmetic): - operand_names = tuple(["src"]) +class LowLevelILRound_to_int(LowLevelILInstruction, FloatingPoint, Arithmetic): @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILFloor(FloatingPoint, Arithmetic): - operand_names = tuple(["src"]) +class LowLevelILFloor(LowLevelILInstruction, FloatingPoint, Arithmetic): @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILCeil(FloatingPoint, Arithmetic): - operand_names = tuple(["src"]) +class LowLevelILCeil(LowLevelILInstruction, FloatingPoint, Arithmetic): @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILFtrunc(FloatingPoint, Arithmetic): - operand_names = tuple(["src"]) +class LowLevelILFtrunc(LowLevelILInstruction, FloatingPoint, Arithmetic): @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILLoad(Load): - operand_names = tuple(["src"]) +class LowLevelILLoad(LowLevelILInstruction, Load): @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILPush(StackOperation): - operand_names = tuple(["src"]) +class LowLevelILPush(LowLevelILInstruction, StackOperation): @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] + @dataclass(frozen=True, repr=False) class LowLevelILReg(LowLevelILInstruction): - operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> ILRegister: return self.get_reg(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_stack_pop(RegisterStack): - operand_names = tuple(["stack"]) +class LowLevelILReg_stack_pop(LowLevelILInstruction, RegisterStack): @property - def stack(self): + def stack(self) -> ILRegisterStack: return self.get_reg_stack(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.stack] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_stack_free_reg(RegisterStack): - operand_names = tuple(["dest"]) +class LowLevelILReg_stack_free_reg(LowLevelILInstruction, RegisterStack): @property - def dest(self): + def dest(self) -> ILRegister: return self.get_reg(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest] + @dataclass(frozen=True, repr=False) -class LowLevelILConst(Constant): +class LowLevelILConst(LowLevelILConstantBase): pass @dataclass(frozen=True, repr=False) -class LowLevelILConst_ptr(Constant): +class LowLevelILConst_ptr(LowLevelILConstantBase): pass @dataclass(frozen=True, repr=False) -class LowLevelILFloat_const(Constant, FloatingPoint): +class LowLevelILFloat_const(LowLevelILConstantBase, FloatingPoint): @property def constant(self) -> float: return self.get_float(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.constant] + @dataclass(frozen=True, repr=False) class LowLevelILFlag(LowLevelILInstruction): - operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> ILFlag: return self.get_flag(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILGoto(Terminal): - operand_names = tuple(["dest"]) +class LowLevelILGoto(LowLevelILInstruction, Terminal): @property - def dest(self): + def dest(self) -> int: return self.get_int(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest] + @dataclass(frozen=True, repr=False) class LowLevelILFlag_group(LowLevelILInstruction): - operand_names = tuple(["semantic_group"]) @property - def semantic_group(self): + def semantic_group(self) -> ILSemanticFlagGroup: return self.get_sem_group(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.semantic_group] + @dataclass(frozen=True, repr=False) class LowLevelILBool_to_int(LowLevelILInstruction): - operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILTrap(Terminal): - operand_names = tuple(["vector"]) +class LowLevelILTrap(LowLevelILInstruction, Terminal): @property - def vector(self): + def vector(self) -> int: return self.get_int(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.vector] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_split_dest_ssa(SSA): - operand_names = tuple(["dest"]) +class LowLevelILReg_split_dest_ssa(LowLevelILInstruction, SSA): @property - def dest(self): + def dest(self) -> SSARegister: return self.get_reg_ssa(0, 1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_stack_dest_ssa(RegisterStack, SSA): - operand_names = tuple(["dest", "src"]) +class LowLevelILReg_stack_dest_ssa(LowLevelILInstruction, RegisterStack, SSA): @property - def dest(self): + def dest(self) -> SSARegisterStack: return self.get_reg_stack_ssa(0, 1) @property - def src(self): + def src(self) -> SSARegisterStack: return self.get_reg_stack_ssa(0, 2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_ssa(SSA): - operand_names = tuple(["src"]) +class LowLevelILReg_ssa(LowLevelILInstruction, SSA): @property - def src(self): + def src(self) -> SSARegister: return self.get_reg_ssa(0, 1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILFlag_ssa(SSA): - operand_names = tuple(["src"]) +class LowLevelILFlag_ssa(LowLevelILInstruction, SSA): @property - def src(self): + def src(self) -> SSAFlag: return self.get_flag_ssa(0, 1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILCall_param(SSA): - operand_names = tuple(["src"]) +class LowLevelILCall_param(LowLevelILInstruction, SSA): @property - def src(self): + def src(self) -> List['LowLevelILInstruction']: return self.get_expr_list(0) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILMem_phi(Memory, SSA): - operand_names = tuple(["dest_memory", "src_memory"]) +class LowLevelILMem_phi(LowLevelILInstruction, Memory, SSA): @property - def dest_memory(self): + def dest_memory(self) -> int: return self.get_int(0) @property - def src_memory(self): + def src_memory(self) -> List[int]: return self.get_int_list(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest_memory, self.src_memory] + @dataclass(frozen=True, repr=False) -class LowLevelILSet_reg(SetReg): - operand_names = tuple(["dest", "src"]) +class LowLevelILSet_reg(LowLevelILInstruction, SetReg): @property - def dest(self): + def dest(self) -> ILRegister: return self.get_reg(0) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_stack_push(RegisterStack): - operand_names = tuple(["stack", "src"]) +class LowLevelILReg_stack_push(LowLevelILInstruction, RegisterStack): @property - def stack(self): + def stack(self) -> ILRegisterStack: return self.get_reg_stack(0) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.stack, self.src] + @dataclass(frozen=True, repr=False) class LowLevelILSet_flag(LowLevelILInstruction): - operand_names = tuple(["dest", "src"]) @property - def dest(self): + def dest(self) -> ILFlag: return self.get_flag(0) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILStore(Store): - operand_names = tuple(["dest", "src"]) +class LowLevelILStore(LowLevelILInstruction, Store): @property - def dest(self): + def dest(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest, self.src] + @dataclass(frozen=True, repr=False) class LowLevelILReg_split(LowLevelILInstruction): - operand_names = tuple(["hi", "lo"]) @property - def hi(self): + def hi(self) -> ILRegister: return self.get_reg(0) @property - def lo(self): + def lo(self) -> ILRegister: return self.get_reg(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.hi, self.lo] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_stack_rel(RegisterStack): - operand_names = tuple(["stack", "src"]) +class LowLevelILReg_stack_rel(LowLevelILInstruction, RegisterStack): @property - def stack(self): + def stack(self) -> ILRegisterStack: return self.get_reg_stack(0) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.stack, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_stack_free_rel(RegisterStack): - operand_names = tuple(["stack", "dest"]) +class LowLevelILReg_stack_free_rel(LowLevelILInstruction, RegisterStack): @property - def stack(self): + def stack(self) -> ILRegisterStack: return self.get_reg_stack(0) @property - def dest(self): + def dest(self) -> LowLevelILInstruction: return self.get_expr(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.stack, self.dest] + @dataclass(frozen=True, repr=False) -class LowLevelILExtern_ptr(Constant): - operand_names = tuple(["constant", "offset"]) +class LowLevelILExtern_ptr(LowLevelILConstantBase): @property - def constant(self): + def constant(self) -> int: return self.get_int(0) @property - def offset(self): + def offset(self) -> int: return self.get_int(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.constant, self.offset] + @dataclass(frozen=True, repr=False) class LowLevelILFlag_bit(LowLevelILInstruction): - operand_names = tuple(["src", "bit"]) @property - def src(self): + def src(self) -> ILFlag: return self.get_flag(0) @property - def bit(self): + def bit(self) -> int: return self.get_int(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src, self.bit] + @dataclass(frozen=True, repr=False) -class LowLevelILAdd(BinaryOperation, Arithmetic): +class LowLevelILAdd(LowLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class LowLevelILSub(BinaryOperation, Arithmetic): +class LowLevelILSub(LowLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class LowLevelILAnd(BinaryOperation, Arithmetic): +class LowLevelILAnd(LowLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class LowLevelILOr(BinaryOperation, Arithmetic): +class LowLevelILOr(LowLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class LowLevelILXor(BinaryOperation, Arithmetic): +class LowLevelILXor(LowLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class LowLevelILLsl(BinaryOperation, Arithmetic): +class LowLevelILLsl(LowLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class LowLevelILLsr(BinaryOperation, Arithmetic): +class LowLevelILLsr(LowLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class LowLevelILAsr(BinaryOperation, Arithmetic): +class LowLevelILAsr(LowLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class LowLevelILRol(BinaryOperation, Arithmetic): +class LowLevelILRol(LowLevelILBinaryBase, Arithmetic): pass + @dataclass(frozen=True, repr=False) -class LowLevelILRor(BinaryOperation, Arithmetic): +class LowLevelILRor(LowLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class LowLevelILMul(BinaryOperation, Arithmetic): +class LowLevelILMul(LowLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class LowLevelILMulu_dp(BinaryOperation, DoublePrecision): +class LowLevelILMulu_dp(LowLevelILBinaryBase, DoublePrecision): pass + @dataclass(frozen=True, repr=False) -class LowLevelILMuls_dp(BinaryOperation, DoublePrecision): +class LowLevelILMuls_dp(LowLevelILBinaryBase, DoublePrecision): pass @dataclass(frozen=True, repr=False) -class LowLevelILDivu(BinaryOperation, Arithmetic): +class LowLevelILDivu(LowLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class LowLevelILDivu_dp(BinaryOperation, DoublePrecision): +class LowLevelILDivu_dp(LowLevelILBinaryBase, DoublePrecision): pass @dataclass(frozen=True, repr=False) -class LowLevelILDivs(BinaryOperation, Arithmetic, Signed): +class LowLevelILDivs(LowLevelILBinaryBase, Arithmetic, Signed): pass @dataclass(frozen=True, repr=False) -class LowLevelILDivs_dp(BinaryOperation, DoublePrecision, Signed): +class LowLevelILDivs_dp(LowLevelILBinaryBase, DoublePrecision, Signed): pass @dataclass(frozen=True, repr=False) -class LowLevelILModu(BinaryOperation, Arithmetic): +class LowLevelILModu(LowLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class LowLevelILModu_dp(BinaryOperation, DoublePrecision): +class LowLevelILModu_dp(LowLevelILBinaryBase, DoublePrecision): pass + @dataclass(frozen=True, repr=False) -class LowLevelILMods(BinaryOperation, Arithmetic, Signed): +class LowLevelILMods(LowLevelILBinaryBase, Arithmetic, Signed): pass @dataclass(frozen=True, repr=False) -class LowLevelILMods_dp(BinaryOperation, DoublePrecision, Signed): +class LowLevelILMods_dp(LowLevelILBinaryBase, DoublePrecision, Signed): pass @dataclass(frozen=True, repr=False) -class LowLevelILCmp_e(Comparison): +class LowLevelILCmp_e(LowLevelILComparisonBase): pass @dataclass(frozen=True, repr=False) -class LowLevelILCmp_ne(Comparison): +class LowLevelILCmp_ne(LowLevelILComparisonBase): pass @dataclass(frozen=True, repr=False) -class LowLevelILCmp_slt(Comparison, Signed): +class LowLevelILCmp_slt(LowLevelILComparisonBase, Signed): pass @dataclass(frozen=True, repr=False) -class LowLevelILCmp_ult(Comparison): +class LowLevelILCmp_ult(LowLevelILComparisonBase): pass @dataclass(frozen=True, repr=False) -class LowLevelILCmp_sle(Comparison,Signed): +class LowLevelILCmp_sle(LowLevelILComparisonBase,Signed): pass @dataclass(frozen=True, repr=False) -class LowLevelILCmp_ule(Comparison): +class LowLevelILCmp_ule(LowLevelILComparisonBase): pass @dataclass(frozen=True, repr=False) -class LowLevelILCmp_sge(Comparison, Signed): +class LowLevelILCmp_sge(LowLevelILComparisonBase, Signed): pass @dataclass(frozen=True, repr=False) -class LowLevelILCmp_uge(Comparison): +class LowLevelILCmp_uge(LowLevelILComparisonBase): pass @dataclass(frozen=True, repr=False) -class LowLevelILCmp_sgt(Comparison, Signed): +class LowLevelILCmp_sgt(LowLevelILComparisonBase, Signed): pass @dataclass(frozen=True, repr=False) -class LowLevelILCmp_ugt(Comparison): +class LowLevelILCmp_ugt(LowLevelILComparisonBase): pass @dataclass(frozen=True, repr=False) -class LowLevelILTest_bit(BinaryOperation, Arithmetic, FloatingPoint): +class LowLevelILTest_bit(LowLevelILBinaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class LowLevelILFadd(BinaryOperation, Arithmetic, FloatingPoint): +class LowLevelILFadd(LowLevelILBinaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class LowLevelILFsub(BinaryOperation, Arithmetic, FloatingPoint): +class LowLevelILFsub(LowLevelILBinaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class LowLevelILFmul(BinaryOperation, Arithmetic, FloatingPoint): +class LowLevelILFmul(LowLevelILBinaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class LowLevelILFdiv(BinaryOperation, Arithmetic, FloatingPoint): +class LowLevelILFdiv(LowLevelILBinaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class LowLevelILFcmp_e(Comparison, FloatingPoint): +class LowLevelILFcmp_e(LowLevelILInstruction, Comparison, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class LowLevelILFcmp_ne(Comparison, FloatingPoint): +class LowLevelILFcmp_ne(LowLevelILInstruction, Comparison, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class LowLevelILFcmp_lt(Comparison, FloatingPoint): +class LowLevelILFcmp_lt(LowLevelILInstruction, Comparison, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class LowLevelILFcmp_le(Comparison, FloatingPoint): +class LowLevelILFcmp_le(LowLevelILInstruction, Comparison, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class LowLevelILFcmp_ge(Comparison, FloatingPoint): +class LowLevelILFcmp_ge(LowLevelILInstruction, Comparison, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class LowLevelILFcmp_gt(Comparison, FloatingPoint): +class LowLevelILFcmp_gt(LowLevelILInstruction, Comparison, FloatingPoint): pass + @dataclass(frozen=True, repr=False) -class LowLevelILFcmp_o(Comparison, FloatingPoint): +class LowLevelILFcmp_o(LowLevelILInstruction, Comparison, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class LowLevelILFcmp_uo(Comparison, FloatingPoint): +class LowLevelILFcmp_uo(LowLevelILInstruction, Comparison, FloatingPoint): pass @dataclass(frozen=True, repr=False) class LowLevelILJump_to(LowLevelILInstruction): - operand_names = tuple(["dest", "targets"]) @property - def dest(self): + def dest(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def targets(self): + def targets(self) -> Mapping[int, int]: return self.get_target_map(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest, self.targets] + @dataclass(frozen=True, repr=False) class LowLevelILFlag_cond(LowLevelILInstruction): - operand_names = tuple(["condition", "semantic_class"]) @property - def condition(self): + def condition(self) -> LowLevelILFlagCondition: return self.get_cond(0) @property - def semantic_class(self): + def semantic_class(self) -> ILSemanticFlagClass: return self.get_sem_class(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.condition, self.semantic_class] + @dataclass(frozen=True, repr=False) -class LowLevelILAdd_overflow(BinaryOperation, Arithmetic): - operand_names = tuple(["left", "right"]) +class LowLevelILAdd_overflow(LowLevelILBinaryBase, Arithmetic): @property - def left(self): + def left(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> LowLevelILInstruction: return self.get_expr(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.left, self.right] + @dataclass(frozen=True, repr=False) -class LowLevelILSet_reg_ssa(SetReg, SSA): - operand_names = tuple(["dest", "src"]) +class LowLevelILSet_reg_ssa(LowLevelILInstruction, SetReg, SSA): @property - def dest(self): + def dest(self) -> SSARegister: return self.get_reg_ssa(0, 1) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_ssa_partial(SetReg, SSA): - operand_names = tuple(["full_reg", "src"]) +class LowLevelILReg_ssa_partial(LowLevelILInstruction, SetReg, SSA): @property - def full_reg(self): + def full_reg(self) -> SSARegister: return self.get_reg_ssa(0, 1) @property - def src(self): + def src(self) -> ILRegister: return self.get_reg(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.full_reg, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_split_ssa(SetReg, SSA): - operand_names = tuple(["hi", "lo"]) +class LowLevelILReg_split_ssa(LowLevelILInstruction, SetReg, SSA): @property - def hi(self): + def hi(self) -> SSARegister: return self.get_reg_ssa(0, 1) @property - def lo(self): + def lo(self) -> SSARegister: return self.get_reg_ssa(2, 3) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.hi, self.lo] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_stack_abs_ssa(RegisterStack, SSA): - operand_names = tuple(["stack", "src"]) +class LowLevelILReg_stack_abs_ssa(LowLevelILInstruction, RegisterStack, SSA): @property - def stack(self): + def stack(self) -> SSARegisterStack: return self.get_reg_stack_ssa(0, 1) @property - def src(self): + def src(self) -> ILRegister: return self.get_reg(2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.stack, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_stack_free_abs_ssa(RegisterStack): - operand_names = tuple(["stack", "dest"]) +class LowLevelILReg_stack_free_abs_ssa(LowLevelILInstruction, RegisterStack): @property - def stack(self): + def stack(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def dest(self): + def dest(self) -> ILRegister: return self.get_reg(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.stack, self.dest] + @dataclass(frozen=True, repr=False) -class LowLevelILSet_flag_ssa(SSA): - operand_names = tuple(["dest", "src"]) +class LowLevelILSet_flag_ssa(LowLevelILInstruction, SSA): @property - def dest(self): + def dest(self) -> SSAFlag: return self.get_flag_ssa(0, 1) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILFlag_bit_ssa(SSA): - operand_names = tuple(["src", "bit"]) +class LowLevelILFlag_bit_ssa(LowLevelILInstruction, SSA): @property - def src(self): + def src(self) -> SSAFlag: return self.get_flag_ssa(0, 1) @property - def bit(self): + def bit(self) -> int: return self.get_int(2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src, self.bit] + @dataclass(frozen=True, repr=False) -class LowLevelILCall_output_ssa(SSA): - operand_names = tuple(["dest_memory", "dest"]) +class LowLevelILCall_output_ssa(LowLevelILInstruction, SSA): @property - def dest_memory(self): + def dest_memory(self) -> int: return self.get_int(0) @property - def dest(self): + def dest(self) -> List[SSARegister]: return self.get_reg_ssa_list(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest_memory, self.dest] + @dataclass(frozen=True, repr=False) -class LowLevelILCall_stack_ssa(SSA): - operand_names = tuple(["src", "src_memory"]) +class LowLevelILCall_stack_ssa(LowLevelILInstruction, SSA): @property - def src(self): + def src(self) -> SSARegister: return self.get_reg_ssa(0, 1) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src, self.src_memory] + @dataclass(frozen=True, repr=False) -class LowLevelILLoad_ssa(Load, SSA): - operand_names = tuple(["src", "src_memory"]) +class LowLevelILLoad_ssa(LowLevelILInstruction, Load, SSA): @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(1) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.src, self.src_memory] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_phi(SSA): - operand_names = tuple(["dest", "src"]) +class LowLevelILReg_phi(LowLevelILInstruction, SSA): @property - def dest(self): + def dest(self) -> SSARegister: return self.get_reg_ssa(0, 1) @property - def src(self): + def src(self) -> List[SSARegister]: return self.get_reg_ssa_list(2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_stack_phi(RegisterStack, SSA): - operand_names = tuple(["dest", "src"]) +class LowLevelILReg_stack_phi(LowLevelILInstruction, RegisterStack, SSA): @property - def dest(self): + def dest(self) -> SSARegisterStack: return self.get_reg_stack_ssa(0, 1) @property - def src(self): + def src(self) -> List[SSARegisterStack]: return self.get_reg_stack_ssa_list(2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILFlag_phi(SSA): - operand_names = tuple(["dest", "src"]) +class LowLevelILFlag_phi(LowLevelILInstruction, SSA): @property - def dest(self): + def dest(self) -> SSAFlag: return self.get_flag_ssa(0, 1) @property - def src(self): + def src(self) -> List[SSAFlag]: return self.get_flag_ssa_list(2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILSet_reg_split(SetReg): - operand_names = tuple(["hi", "lo", "src"]) +class LowLevelILSet_reg_split(LowLevelILInstruction, SetReg): @property - def hi(self): + def hi(self) -> ILRegister: return self.get_reg(0) @property - def lo(self): + def lo(self) -> ILRegister: return self.get_reg(1) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(2) - -@dataclass(frozen=True, repr=False) -class LowLevelILSet_reg_stack_rel(RegisterStack): - operand_names = tuple(["stack", "dest", "src"]) - - @property - def stack(self): - return self.get_reg_stack(0) - - @property - def dest(self): - return self.get_expr(1) - @property - def src(self): - return self.get_expr(2) + def operands(self) -> List[LowLevelILOperandType]: + return [self.hi, self.lo, self.src] @dataclass(frozen=True, repr=False) -class LowLevelILSbb(Carry): - operand_names = tuple(["left", "right", "carry"]) +class LowLevelILSet_reg_stack_rel(LowLevelILInstruction, RegisterStack): @property - def left(self): - return self.get_expr(0) + def stack(self) -> ILRegisterStack: + return self.get_reg_stack(0) @property - def right(self): + def dest(self) -> LowLevelILInstruction: return self.get_expr(1) @property - def carry(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(2) - -@dataclass(frozen=True, repr=False) -class LowLevelILAdc(Carry): - operand_names = tuple(["left", "right", "carry"]) - - @property - def left(self): - return self.get_expr(0) - @property - def right(self): - return self.get_expr(1) - - @property - def carry(self): - return self.get_expr(2) + def operands(self) -> List[LowLevelILOperandType]: + return [self.stack, self.dest, self.src] @dataclass(frozen=True, repr=False) -class LowLevelILRlc(Carry): - operand_names = tuple(["left", "right", "carry"]) - - @property - def left(self): - return self.get_expr(0) +class LowLevelILSbb(LowLevelILCarryBase): + pass - @property - def right(self): - return self.get_expr(1) - @property - def carry(self): - return self.get_expr(2) +@dataclass(frozen=True, repr=False) +class LowLevelILAdc(LowLevelILCarryBase): + pass @dataclass(frozen=True, repr=False) -class LowLevelILRrc(Carry): - operand_names = tuple(["left", "right", "carry"]) +class LowLevelILRlc(LowLevelILCarryBase): + pass - @property - def left(self): - return self.get_expr(0) - @property - def right(self): - return self.get_expr(1) - - @property - def carry(self): - return self.get_expr(2) +@dataclass(frozen=True, repr=False) +class LowLevelILRrc(LowLevelILCarryBase): + pass @dataclass(frozen=True, repr=False) -class LowLevelILCall_stack_adjust(Call): - operand_names = tuple(["dest", "stack_adjustment", "reg_stack_adjustments"]) +class LowLevelILCall_stack_adjust(LowLevelILInstruction, Call): @property - def dest(self): + def dest(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def stack_adjustment(self): + def stack_adjustment(self) -> int: return self.get_int(1) @property - def reg_stack_adjustments(self): + def reg_stack_adjustments(self) -> Mapping['architecture.RegisterStackName', int]: return self.get_reg_stack_adjust(2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest, self.stack_adjustment, self.reg_stack_adjustments] + @dataclass(frozen=True, repr=False) -class LowLevelILIf(Terminal): - operand_names = tuple(["condition", "true", "false"]) +class LowLevelILIf(LowLevelILInstruction, ControlFlow): @property - def condition(self): + def condition(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def true(self): + def true(self) -> int: return self.get_int(1) @property - def false(self): + def false(self) -> int: return self.get_int(2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.condition, self.true, self.false] + @dataclass(frozen=True, repr=False) class LowLevelILIntrinsic(LowLevelILInstruction): - operand_names = tuple(["output", "intrinsic", "param"]) @property - def output(self): + def output(self) -> List[Union[ILFlag, ILRegister]]: return self.get_reg_or_flag_list(0) @property - def intrinsic(self): + def intrinsic(self) -> ILIntrinsic: return self.get_intrinsic(2) @property - def param(self): + def param(self) -> LowLevelILInstruction: return self.get_expr(3) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.output, self.intrinsic, self.param] + @dataclass(frozen=True, repr=False) -class LowLevelILIntrinsic_ssa(SSA): - operand_names = tuple(["output", "intrinsic", "param"]) +class LowLevelILIntrinsic_ssa(LowLevelILInstruction, SSA): @property - def output(self): + def output(self) -> List[SSARegisterOrFlag]: return self.get_reg_or_flag_ssa_list(0) @property - def intrinsic(self): + def intrinsic(self) -> ILIntrinsic: return self.get_intrinsic(2) @property - def param(self): + def param(self) -> LowLevelILInstruction: return self.get_expr(3) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.output, self.intrinsic, self.param] + @dataclass(frozen=True, repr=False) -class LowLevelILSet_reg_ssa_partial(SetReg, SSA): - operand_names = tuple(["full_reg", "dest", "src"]) +class LowLevelILSet_reg_ssa_partial(LowLevelILInstruction, SetReg, SSA): @property - def full_reg(self): + def full_reg(self) -> SSARegister: return self.get_reg_ssa(0, 1) @property - def dest(self): + def dest(self) -> ILRegister: return self.get_reg(2) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(3) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.full_reg, self.dest, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILSet_reg_split_ssa(SetReg, SSA): - operand_names = tuple(["hi", "lo", "src"]) +class LowLevelILSet_reg_split_ssa(LowLevelILInstruction, SetReg, SSA): @property - def hi(self): + def hi(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def lo(self): + def lo(self) -> LowLevelILInstruction: return self.get_expr(1) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.hi, self.lo, self.src] -@dataclass(frozen=True, repr=False) -class LowLevelILSet_reg_stack_abs_ssa(RegisterStack, SSA): - operand_names = tuple(["stack", "dest", "src"]) +@dataclass(frozen=True, repr=False) +class LowLevelILSet_reg_stack_abs_ssa(LowLevelILInstruction, RegisterStack, SSA): @property - def stack(self): + def stack(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def dest(self): + def dest(self) -> ILRegister: return self.get_reg(1) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.stack, self.dest, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_stack_rel_ssa(RegisterStack, SSA): - operand_names = tuple(["stack", "src", "top"]) +class LowLevelILReg_stack_rel_ssa(LowLevelILInstruction, RegisterStack, SSA): @property - def stack(self): + def stack(self) -> SSARegisterStack: return self.get_reg_stack_ssa(0, 1) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(2) @property - def top(self): + def top(self) -> LowLevelILInstruction: return self.get_expr(3) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.stack, self.src, self.top] + @dataclass(frozen=True, repr=False) -class LowLevelILReg_stack_free_rel_ssa(RegisterStack, SSA): - operand_names = tuple(["stack", "dest", "top"]) +class LowLevelILReg_stack_free_rel_ssa(LowLevelILInstruction, RegisterStack, SSA): @property - def stack(self): + def stack(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def dest(self): + def dest(self) -> LowLevelILInstruction: return self.get_expr(1) @property - def top(self): + def top(self) -> LowLevelILInstruction: return self.get_expr(2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.stack, self.dest, self.top] + @dataclass(frozen=True, repr=False) -class LowLevelILSyscall_ssa(Call, SSA): - operand_names = tuple(["output", "stack", "param"]) +class LowLevelILSyscall_ssa(LowLevelILInstruction, Call, SSA): @property - def output(self): + def output(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def stack(self): + def stack(self) -> LowLevelILInstruction: return self.get_expr(1) @property - def param(self): + def param(self) -> LowLevelILInstruction: return self.get_expr(2) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.output, self.stack, self.param] + @dataclass(frozen=True, repr=False) -class LowLevelILSet_reg_stack_rel_ssa(RegisterStack, SSA): - operand_names = tuple(["stack", "dest", "top", "src"]) +class LowLevelILSet_reg_stack_rel_ssa(LowLevelILInstruction, RegisterStack, SSA): @property - def stack(self): + def stack(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def dest(self): + def dest(self) -> LowLevelILInstruction: return self.get_expr(1) @property - def top(self): + def top(self) -> LowLevelILInstruction: return self.get_expr(2) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(3) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.stack, self.dest, self.top, self.src] + @dataclass(frozen=True, repr=False) -class LowLevelILCall_ssa(Call, SSA): - operand_names = tuple(["output", "dest", "stack", "param"]) +class LowLevelILCall_ssa(LowLevelILInstruction, Call, SSA): @property - def output(self): + def output(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def dest(self): + def dest(self) -> LowLevelILInstruction: return self.get_expr(1) @property - def stack(self): + def stack(self) -> LowLevelILInstruction: return self.get_expr(2) @property - def param(self): + def param(self) -> LowLevelILInstruction: return self.get_expr(3) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.output, self.dest, self.stack, self.param] + @dataclass(frozen=True, repr=False) -class LowLevelILTailcall_ssa(Call, SSA, Terminal): - operand_names = tuple(["output", "dest", "stack", "param"]) +class LowLevelILTailcall_ssa(LowLevelILInstruction, Call, SSA, Terminal): @property - def output(self): + def output(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def dest(self): + def dest(self) -> LowLevelILInstruction: return self.get_expr(1) @property - def stack(self): + def stack(self) -> LowLevelILInstruction: return self.get_expr(2) @property - def param(self): + def param(self) -> LowLevelILInstruction: return self.get_expr(3) + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.output, self.dest, self.stack, self.param] + @dataclass(frozen=True, repr=False) -class LowLevelILStore_ssa(Store, SSA): - operand_names = tuple(["dest", "dest_memory", "src_memory", "src"]) +class LowLevelILStore_ssa(LowLevelILInstruction, Store, SSA): @property - def dest(self): + def dest(self) -> LowLevelILInstruction: return self.get_expr(0) @property - def dest_memory(self): + def dest_memory(self) -> int: return self.get_int(1) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(2) @property - def src(self): + def src(self) -> LowLevelILInstruction: return self.get_expr(3) - - + @property + def operands(self) -> List[LowLevelILOperandType]: + return [self.dest, self.dest_memory, self.src_memory, self.src] ILInstruction:Mapping[LowLevelILOperation, LowLevelILInstruction] = { # type: ignore @@ -2509,12 +2765,12 @@ class LowLevelILFunction: def current_address(self, value:int) -> None: core.BNLowLevelILSetCurrentAddress(self.handle, self.arch.handle, value) - def set_current_address(self, value:int, arch:Optional['architecture.Architecture']=None): + def set_current_address(self, value:int, arch:Optional['architecture.Architecture']=None) -> None: if arch is None: arch = self.arch core.BNLowLevelILSetCurrentAddress(self.handle, arch.handle, value) - def set_current_source_block(self, block): + def set_current_source_block(self, block) -> None: core.BNLowLevelILSetCurrentSourceBlock(self.handle, block.handle) @property @@ -3611,7 +3867,7 @@ class LowLevelILFunction: assert isinstance(class_index, architecture.SemanticClassIndex) return self.expr(LowLevelILOperation.LLIL_FLAG_COND, cond, class_index) - def flag_group(self, sem_group): + def flag_group(self, sem_group) -> ExpressionIndex: """ ``flag_group`` returns a flag_group expression for the given semantic flag group @@ -4198,7 +4454,7 @@ class LowLevelILFunction: """ core.BNFinalizeLowLevelILFunction(self.handle) - def generate_ssa_form(self): + def generate_ssa_form(self) -> None: """ ``generate_ssa_form`` generate SSA form given the current LLIL diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 30ef7f13..e12d8fe1 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -20,7 +20,7 @@ import ctypes import struct -from typing import Optional, List, Union, Mapping, Generator, NewType, Tuple +from typing import Optional, List, Union, Mapping, Generator, NewType, Tuple, ClassVar from dataclasses import dataclass # Binary Ninja components @@ -35,6 +35,9 @@ from . import flowgraph from . import variable from . import architecture from . import binaryview +from .commonil import (Constant, BinaryOperation, UnaryOperation, Comparison, SSA, + Phi, FloatingPoint, ControlFlow, Terminal, Call, Syscall, Tailcall, Return, + Signed, Arithmetic, Carry, DoublePrecision, Memory, Load, Store, RegisterStack, SetVar) OptionalTokens = Optional[List['function.InstructionTextToken']] ExpressionIndex = NewType('ExpressionIndex', int) @@ -112,7 +115,139 @@ class MediumLevelILInstruction: expr_index:ExpressionIndex instr:CoreMediumLevelILInstruction instr_index:InstructionIndex - operand_names = tuple() + ILOperations:ClassVar[Mapping[MediumLevelILOperation, List[Tuple[str,str]]]] = { + MediumLevelILOperation.MLIL_NOP: [], + MediumLevelILOperation.MLIL_SET_VAR: [("dest", "var"), ("src", "expr")], + MediumLevelILOperation.MLIL_SET_VAR_FIELD: [("dest", "var"), ("offset", "int"), ("src", "expr")], + MediumLevelILOperation.MLIL_SET_VAR_SPLIT: [("high", "var"), ("low", "var"), ("src", "expr")], + MediumLevelILOperation.MLIL_LOAD: [("src", "expr")], + MediumLevelILOperation.MLIL_LOAD_STRUCT: [("src", "expr"), ("offset", "int")], + MediumLevelILOperation.MLIL_STORE: [("dest", "expr"), ("src", "expr")], + MediumLevelILOperation.MLIL_STORE_STRUCT: [("dest", "expr"), ("offset", "int"), ("src", "expr")], + MediumLevelILOperation.MLIL_VAR: [("src", "var")], + MediumLevelILOperation.MLIL_VAR_FIELD: [("src", "var"), ("offset", "int")], + MediumLevelILOperation.MLIL_VAR_SPLIT: [("high", "var"), ("low", "var")], + MediumLevelILOperation.MLIL_ADDRESS_OF: [("src", "var")], + MediumLevelILOperation.MLIL_ADDRESS_OF_FIELD: [("src", "var"), ("offset", "int")], + MediumLevelILOperation.MLIL_CONST: [("constant", "int")], + MediumLevelILOperation.MLIL_CONST_PTR: [("constant", "int")], + MediumLevelILOperation.MLIL_EXTERN_PTR: [("constant", "int"), ("offset", "int")], + MediumLevelILOperation.MLIL_FLOAT_CONST: [("constant", "float")], + MediumLevelILOperation.MLIL_IMPORT: [("constant", "int")], + MediumLevelILOperation.MLIL_ADD: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_ADC: [("left", "expr"), ("right", "expr"), ("carry", "expr")], + MediumLevelILOperation.MLIL_SUB: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_SBB: [("left", "expr"), ("right", "expr"), ("carry", "expr")], + MediumLevelILOperation.MLIL_AND: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_OR: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_XOR: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_LSL: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_LSR: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_ASR: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_ROL: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_RLC: [("left", "expr"), ("right", "expr"), ("carry", "expr")], + MediumLevelILOperation.MLIL_ROR: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_RRC: [("left", "expr"), ("right", "expr"), ("carry", "expr")], + MediumLevelILOperation.MLIL_MUL: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MULU_DP: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MULS_DP: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_DIVU: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_DIVU_DP: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_DIVS: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_DIVS_DP: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MODU: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MODU_DP: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MODS: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MODS_DP: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_NEG: [("src", "expr")], + MediumLevelILOperation.MLIL_NOT: [("src", "expr")], + MediumLevelILOperation.MLIL_SX: [("src", "expr")], + MediumLevelILOperation.MLIL_ZX: [("src", "expr")], + MediumLevelILOperation.MLIL_LOW_PART: [("src", "expr")], + MediumLevelILOperation.MLIL_JUMP: [("dest", "expr")], + MediumLevelILOperation.MLIL_JUMP_TO: [("dest", "expr"), ("targets", "target_map")], + MediumLevelILOperation.MLIL_RET_HINT: [("dest", "expr")], + MediumLevelILOperation.MLIL_CALL: [("output", "var_list"), ("dest", "expr"), ("params", "expr_list")], + MediumLevelILOperation.MLIL_CALL_UNTYPED: [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], + MediumLevelILOperation.MLIL_CALL_OUTPUT: [("dest", "var_list")], + MediumLevelILOperation.MLIL_CALL_PARAM: [("src", "var_list")], + MediumLevelILOperation.MLIL_RET: [("src", "expr_list")], + MediumLevelILOperation.MLIL_NORET: [], + MediumLevelILOperation.MLIL_IF: [("condition", "expr"), ("true", "int"), ("false", "int")], + MediumLevelILOperation.MLIL_GOTO: [("dest", "int")], + MediumLevelILOperation.MLIL_CMP_E: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_NE: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_SLT: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_ULT: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_SLE: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_ULE: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_SGE: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_UGE: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_SGT: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_UGT: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_TEST_BIT: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_BOOL_TO_INT: [("src", "expr")], + 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")], + MediumLevelILOperation.MLIL_INTRINSIC_SSA: [("output", "var_ssa_list"), ("intrinsic", "intrinsic"), ("params", "expr_list")], + MediumLevelILOperation.MLIL_FREE_VAR_SLOT: [("dest", "var")], + MediumLevelILOperation.MLIL_FREE_VAR_SLOT_SSA: [("prev", "var_ssa_dest_and_src")], + MediumLevelILOperation.MLIL_UNDEF: [], + MediumLevelILOperation.MLIL_UNIMPL: [], + MediumLevelILOperation.MLIL_UNIMPL_MEM: [("src", "expr")], + MediumLevelILOperation.MLIL_FADD: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_FSUB: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_FMUL: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_FDIV: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_FSQRT: [("src", "expr")], + MediumLevelILOperation.MLIL_FNEG: [("src", "expr")], + MediumLevelILOperation.MLIL_FABS: [("src", "expr")], + MediumLevelILOperation.MLIL_FLOAT_TO_INT: [("src", "expr")], + MediumLevelILOperation.MLIL_INT_TO_FLOAT: [("src", "expr")], + MediumLevelILOperation.MLIL_FLOAT_CONV: [("src", "expr")], + MediumLevelILOperation.MLIL_ROUND_TO_INT: [("src", "expr")], + MediumLevelILOperation.MLIL_FLOOR: [("src", "expr")], + MediumLevelILOperation.MLIL_CEIL: [("src", "expr")], + MediumLevelILOperation.MLIL_FTRUNC: [("src", "expr")], + MediumLevelILOperation.MLIL_FCMP_E: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_FCMP_NE: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_FCMP_LT: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_FCMP_LE: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_FCMP_GE: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_FCMP_GT: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_FCMP_O: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_FCMP_UO: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_SET_VAR_SSA: [("dest", "var_ssa"), ("src", "expr")], + MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD: [("prev", "var_ssa_dest_and_src"), ("offset", "int"), ("src", "expr")], + MediumLevelILOperation.MLIL_SET_VAR_SPLIT_SSA: [("high", "var_ssa"), ("low", "var_ssa"), ("src", "expr")], + MediumLevelILOperation.MLIL_SET_VAR_ALIASED: [("prev", "var_ssa_dest_and_src"), ("src", "expr")], + MediumLevelILOperation.MLIL_SET_VAR_ALIASED_FIELD: [("prev", "var_ssa_dest_and_src"), ("offset", "int"), ("src", "expr")], + MediumLevelILOperation.MLIL_VAR_SSA: [("src", "var_ssa")], + MediumLevelILOperation.MLIL_VAR_SSA_FIELD: [("src", "var_ssa"), ("offset", "int")], + MediumLevelILOperation.MLIL_VAR_ALIASED: [("src", "var_ssa")], + MediumLevelILOperation.MLIL_VAR_ALIASED_FIELD: [("src", "var_ssa"), ("offset", "int")], + MediumLevelILOperation.MLIL_VAR_SPLIT_SSA: [("high", "var_ssa"), ("low", "var_ssa")], + MediumLevelILOperation.MLIL_CALL_SSA: [("output", "expr"), ("dest", "expr"), ("params", "expr_list"), ("src_memory", "int")], + 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")], + MediumLevelILOperation.MLIL_LOAD_STRUCT_SSA: [("src", "expr"), ("offset", "int"), ("src_memory", "int")], + MediumLevelILOperation.MLIL_STORE_SSA: [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], + MediumLevelILOperation.MLIL_STORE_STRUCT_SSA: [("dest", "expr"), ("offset", "int"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], + MediumLevelILOperation.MLIL_VAR_PHI: [("dest", "var_ssa"), ("src", "var_ssa_list")], + MediumLevelILOperation.MLIL_MEM_PHI: [("dest_memory", "int"), ("src_memory", "int_list")] + } @classmethod def create(cls, func:'MediumLevelILFunction', expr_index:ExpressionIndex, instr_index:Optional[InstructionIndex]=None) -> 'MediumLevelILInstruction': @@ -311,15 +446,14 @@ class MediumLevelILInstruction: return result @property - def vars_written(self) -> List[Union[variable.Variable, SSAVariable]]: - """List of variables written by instruction""" + def operands(self) -> List[MediumLevelILOperandType]: + """Operands for the instruction""" return [] @property - def operands(self) -> Generator[MediumLevelILOperandType, None, None]: - for operand_name in self.operand_names: - assert hasattr(self, operand_name), f"No operand '{operand_name}' from '{self.operand_names}' for instruction {repr(self)}({self.operation})" - yield self.__getattribute__(operand_name) + def vars_written(self) -> List[Union[variable.Variable, SSAVariable]]: + """List of variables written by instruction""" + return [] @property def vars_read(self) -> List[Union[variable.Variable, SSAVariable]]: @@ -627,22 +761,12 @@ class MediumLevelILInstruction: @dataclass(frozen=True, repr=False) -class Arithmetic(MediumLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class Memory(MediumLevelILInstruction): +class MediumLevelILConstBase(MediumLevelILInstruction, Constant): pass @dataclass(frozen=True, repr=False) -class ControlFlow(MediumLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class Call(ControlFlow): +class MediumLevelILCallBase(MediumLevelILInstruction, Call): @property def output(self) -> List[Union[SSAVariable, variable.Variable]]: return NotImplemented @@ -667,31 +791,21 @@ class Call(ControlFlow): assert False, "Call.params returned object other than Variable, SSAVariable or MediumLevelILInstruction" return result -@dataclass(frozen=True, repr=False) -class UnaryOperation(MediumLevelILInstruction): - operand_names = tuple(["src"]) - - @property - def src(self) -> MediumLevelILInstruction: - return self.get_expr(0) - @dataclass(frozen=True, repr=False) -class BinaryOperation(MediumLevelILInstruction): - operand_names = tuple(["left", "right"]) +class MediumLevelILUnaryBase(MediumLevelILInstruction, UnaryOperation): @property - def left(self) -> MediumLevelILInstruction: + def src(self) -> MediumLevelILInstruction: return self.get_expr(0) @property - def right(self) -> MediumLevelILInstruction: - return self.get_expr(1) + def operands(self) -> List[MediumLevelILInstruction]: + return [self.src] @dataclass(frozen=True, repr=False) -class Carry(Arithmetic): - operand_names = tuple(["left", "right", "carry"]) +class MediumLevelILBinaryBase(MediumLevelILInstruction, BinaryOperation): @property def left(self) -> MediumLevelILInstruction: @@ -702,245 +816,195 @@ class Carry(Arithmetic): return self.get_expr(1) @property - def carry(self) -> MediumLevelILInstruction: - return self.get_expr(2) + def operands(self) -> List[MediumLevelILInstruction]: + return [self.left, self.right] @dataclass(frozen=True, repr=False) -class Comparison(BinaryOperation): +class MediumLevelILComparisonBase(MediumLevelILBinaryBase): pass @dataclass(frozen=True, repr=False) -class Constant(MediumLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class Store(Memory): - pass - +class MediumLevelILCarryBase(MediumLevelILInstruction, Carry): -@dataclass(frozen=True, repr=False) -class Load(Memory): - pass - - -@dataclass(frozen=True, repr=False) -class RegisterStack(MediumLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class SSA(MediumLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class Phi(SSA): - pass - - -@dataclass(frozen=True, repr=False) -class SetVar(MediumLevelILInstruction): @property - def src(self) -> Union[MediumLevelILInstruction, List[Union[SSAVariable, variable.Variable]]]: - return NotImplemented + def left(self) -> MediumLevelILInstruction: + return self.get_expr(0) @property - def dest(self) -> Union[SSAVariable, variable.Variable]: - return NotImplemented + def right(self) -> MediumLevelILInstruction: + return self.get_expr(1) @property - def vars_written(self) -> List[Union[SSAVariable, variable.Variable]]: - d = self.dest - if isinstance(d, list): - return d - return [d] + def carry(self) -> MediumLevelILInstruction: + return self.get_expr(2) @property - def vars_read(self) -> List[Union[SSAVariable, variable.Variable]]: - result = [] - src = self.src - if isinstance(src, MediumLevelILInstruction): - return src.vars_read - - for i in src: - if isinstance(i, (variable.Variable, SSAVariable)): - result.append(i) - else: - assert False, "SetVar.src returned object other than, Variable, SSAVariable" - return result + def operands(self) -> List[MediumLevelILInstruction]: + return [self.left, self.right, self.carry] @dataclass(frozen=True, repr=False) -class FloatingPoint(MediumLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class Terminal(ControlFlow): - pass - - -@dataclass(frozen=True, repr=False) -class Return(Terminal): - pass - - -@dataclass(frozen=True, repr=False) -class Signed(MediumLevelILInstruction): - pass - - -@dataclass(frozen=True, repr=False) -class DoublePrecision(Arithmetic): +class MediumLevelILNop(MediumLevelILInstruction): pass @dataclass(frozen=True, repr=False) -class Syscall(Call): +class MediumLevelILNoret(MediumLevelILInstruction, Terminal): pass @dataclass(frozen=True, repr=False) -class Tailcall(Call, Terminal): +class MediumLevelILBp(MediumLevelILInstruction, Terminal): pass -@dataclass(frozen=True, repr=False) -class MediumLevelILNop(MediumLevelILInstruction): - operand_names = tuple() - - -@dataclass(frozen=True, repr=False) -class MediumLevelILNoret(Terminal): - operand_names = tuple() - - -@dataclass(frozen=True, repr=False) -class MediumLevelILBp(Terminal): - operand_names = tuple() - @dataclass(frozen=True, repr=False) class MediumLevelILUndef(MediumLevelILInstruction): - operand_names = tuple() + pass @dataclass(frozen=True, repr=False) class MediumLevelILUnimpl(MediumLevelILInstruction): - operand_names = tuple() + pass @dataclass(frozen=True, repr=False) -class MediumLevelILLoad(Load): - operand_names = tuple(["src"]) +class MediumLevelILLoad(MediumLevelILInstruction, Load): @property def src(self) -> MediumLevelILInstruction: return self.get_expr(0) + @property + def operands(self) -> List[MediumLevelILInstruction]: + return [self.src] + @dataclass(frozen=True, repr=False) class MediumLevelILVar(MediumLevelILInstruction): - operand_names = tuple(["src"]) @property def src(self) -> variable.Variable: return self.get_var(0) + @property + def operands(self) -> List[variable.Variable]: + return [self.src] + @dataclass(frozen=True, repr=False) class MediumLevelILAddress_of(MediumLevelILInstruction): - operand_names = tuple(["src"]) @property def src(self) -> variable.Variable: return self.get_var(0) + @property + def operands(self) -> List[variable.Variable]: + return [self.src] + @dataclass(frozen=True, repr=False) -class MediumLevelILConst(Constant): - operand_names = tuple(["constant"]) +class MediumLevelILConst(MediumLevelILConstBase): @property def constant(self) -> int: return self.get_int(0) + @property + def operands(self) -> List[int]: + return [self.constant] + @dataclass(frozen=True, repr=False) -class MediumLevelILConst_ptr(Constant): - operand_names = tuple(["constant"]) +class MediumLevelILConst_ptr(MediumLevelILConstBase): @property def constant(self) -> int: return self.get_int(0) + @property + def operands(self) -> List[int]: + return [self.constant] + @dataclass(frozen=True, repr=False) -class MediumLevelILFloat_const(Constant, FloatingPoint): - operand_names = tuple(["constant"]) +class MediumLevelILFloat_const(MediumLevelILConstBase, FloatingPoint): @property def constant(self) -> float: return self.get_float(0) + @property + def operands(self) -> List[float]: + return [self.constant] + @dataclass(frozen=True, repr=False) -class MediumLevelILImport(Constant): - operand_names = tuple(["constant"]) +class MediumLevelILImport(MediumLevelILConstBase): @property def constant(self) -> int: return self.get_int(0) + @property + def operands(self) -> List[int]: + return [self.constant] + @dataclass(frozen=True, repr=False) -class MediumLevelILNeg(UnaryOperation, Arithmetic): +class MediumLevelILNeg(MediumLevelILUnaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILNot(UnaryOperation, Arithmetic): +class MediumLevelILNot(MediumLevelILUnaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILSx(UnaryOperation, Arithmetic): +class MediumLevelILSx(MediumLevelILUnaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILZx(UnaryOperation, Arithmetic): +class MediumLevelILZx(MediumLevelILUnaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILLow_part(UnaryOperation, Arithmetic): +class MediumLevelILLow_part(MediumLevelILUnaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILJump(Terminal): - operand_names = tuple(["dest"]) +class MediumLevelILJump(MediumLevelILInstruction, Terminal): @property def dest(self) -> MediumLevelILInstruction: return self.get_expr(0) + @property + def operands(self) -> List[MediumLevelILInstruction]: + return [self.dest] + @dataclass(frozen=True, repr=False) -class MediumLevelILRet_hint(ControlFlow): - operand_names = tuple(["dest"]) +class MediumLevelILRet_hint(MediumLevelILInstruction, ControlFlow): @property def dest(self) -> MediumLevelILInstruction: return self.get_expr(0) + @property + def operands(self) -> List[MediumLevelILInstruction]: + return [self.dest] + @dataclass(frozen=True, repr=False) class MediumLevelILCall_output(MediumLevelILInstruction): - operand_names = tuple(["dest"]) @property def dest(self) -> List[variable.Variable]: @@ -950,64 +1014,85 @@ class MediumLevelILCall_output(MediumLevelILInstruction): def vars_written(self) -> List[variable.Variable]: return self.dest + @property + def operands(self) -> List[variable.Variable]: + return self.dest + @dataclass(frozen=True, repr=False) class MediumLevelILCall_param(MediumLevelILInstruction): - operand_names = tuple(["src"]) @property def src(self) -> List[variable.Variable]: return self.get_var_list(0, 1) + @property + def operands(self) -> List[variable.Variable]: + return self.src + @dataclass(frozen=True, repr=False) -class MediumLevelILRet(Return): - operand_names = tuple(["src"]) +class MediumLevelILRet(MediumLevelILInstruction, Return): @property def src(self) -> List[MediumLevelILInstruction]: return self.get_expr_list(0, 1) + @property + def operands(self) -> List[MediumLevelILInstruction]: + return [self.src] # TODO: Expand output and params before regeneration + @dataclass(frozen=True, repr=False) -class MediumLevelILGoto(Terminal): - operand_names = tuple(["dest"]) +class MediumLevelILGoto(MediumLevelILInstruction, Terminal): @property def dest(self) -> int: return self.get_int(0) + @property + def operands(self) -> List[int]: + return [self.dest] + @dataclass(frozen=True, repr=False) class MediumLevelILBool_to_int(MediumLevelILInstruction): - operand_names = tuple(["src"]) @property def src(self) -> MediumLevelILInstruction: return self.get_expr(0) + @property + def operands(self) -> List[MediumLevelILInstruction]: + return [self.src] + @dataclass(frozen=True, repr=False) -class MediumLevelILFree_var_slot(RegisterStack): - operand_names = tuple(["dest"]) +class MediumLevelILFree_var_slot(MediumLevelILInstruction, RegisterStack): @property def dest(self) -> variable.Variable: return self.get_var(0) + @property + def operands(self) -> List[variable.Variable]: + return [self.dest] + @dataclass(frozen=True, repr=False) -class MediumLevelILTrap(Terminal): - operand_names = tuple(["vector"]) +class MediumLevelILTrap(MediumLevelILInstruction, Terminal): @property def vector(self) -> int: return self.get_int(0) + @property + def operands(self) -> List[int]: + return [self.vector] + @dataclass(frozen=True, repr=False) -class MediumLevelILFree_var_slot_ssa(RegisterStack): - operand_names = tuple(["dest", "prev"]) +class MediumLevelILFree_var_slot_ssa(MediumLevelILInstruction, SSA, RegisterStack): @property def dest(self) -> SSAVariable: @@ -1017,86 +1102,99 @@ class MediumLevelILFree_var_slot_ssa(RegisterStack): def prev(self) -> SSAVariable: return self.get_var_ssa_dest_and_src(0, 2) + @property + def operands(self) -> List[SSAVariable]: + return [self.dest, self.prev] + @dataclass(frozen=True, repr=False) -class MediumLevelILUnimpl_mem(Memory): - operand_names = tuple(["src"]) +class MediumLevelILUnimpl_mem(MediumLevelILInstruction, Memory): @property def src(self) -> MediumLevelILInstruction: return self.get_expr(0) + @property + def operands(self) -> List[MediumLevelILInstruction]: + return [self.src] + @dataclass(frozen=True, repr=False) -class MediumLevelILFsqrt(UnaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILFsqrt(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFneg(UnaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILFneg(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass + @dataclass(frozen=True, repr=False) -class MediumLevelILFabs(UnaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILFabs(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFloat_to_int(UnaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILFloat_to_int(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILInt_to_float(UnaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILInt_to_float(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFloat_conv(UnaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILFloat_conv(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILRound_to_int(UnaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILRound_to_int(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFloor(UnaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILFloor(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILCeil(UnaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILCeil(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFtrunc(UnaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILFtrunc(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILVar_ssa(SSA): - operand_names = tuple(["src"]) +class MediumLevelILVar_ssa(MediumLevelILInstruction, SSA): @property def src(self) -> SSAVariable: return self.get_var_ssa(0, 1) + @property + def operands(self) -> List[SSAVariable]: + return [self.src] + @dataclass(frozen=True, repr=False) -class MediumLevelILVar_aliased(SSA): - operand_names = tuple(["src"]) +class MediumLevelILVar_aliased(MediumLevelILInstruction, SSA): @property def src(self) -> SSAVariable: return self.get_var_ssa(0, 1) + @property + def operands(self) -> List[SSAVariable]: + return [self.src] + @dataclass(frozen=True, repr=False) -class MediumLevelILSet_var(SetVar): - operand_names = tuple(["dest", "src"]) +class MediumLevelILSet_var(MediumLevelILInstruction, SetVar): @property def dest(self) -> variable.Variable: @@ -1106,10 +1204,21 @@ class MediumLevelILSet_var(SetVar): def src(self) -> MediumLevelILInstruction: return self.get_expr(1) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.dest, self.src] + + @property + def vars_written(self) -> List[variable.Variable]: + return [self.dest] + + @property + def vars_read(self) -> List[Union[variable.Variable, SSAVariable]]: + return self.src.vars_read + @dataclass(frozen=True, repr=False) -class MediumLevelILLoad_struct(Load): - operand_names = tuple(["src", "offset"]) +class MediumLevelILLoad_struct(MediumLevelILInstruction, Load): @property def src(self) -> MediumLevelILInstruction: @@ -1119,10 +1228,13 @@ class MediumLevelILLoad_struct(Load): def offset(self) -> int: return self.get_int(1) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.src, self.offset] + @dataclass(frozen=True, repr=False) -class MediumLevelILStore(Store): - operand_names = tuple(["dest", "src"]) +class MediumLevelILStore(MediumLevelILInstruction, Store): @property def dest(self) -> MediumLevelILInstruction: @@ -1132,10 +1244,13 @@ class MediumLevelILStore(Store): def src(self) -> MediumLevelILInstruction: return self.get_expr(1) + @property + def operands(self) -> List[MediumLevelILInstruction]: + return [self.dest, self.src] + @dataclass(frozen=True, repr=False) class MediumLevelILVar_field(MediumLevelILInstruction): - operand_names = tuple(["src", "offset"]) @property def src(self) -> variable.Variable: @@ -1145,10 +1260,13 @@ class MediumLevelILVar_field(MediumLevelILInstruction): def offset(self) -> int: return self.get_int(1) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.src, self.offset] + @dataclass(frozen=True, repr=False) class MediumLevelILVar_split(MediumLevelILInstruction): - operand_names = tuple(["high", "low"]) @property def high(self) -> variable.Variable: @@ -1158,10 +1276,13 @@ class MediumLevelILVar_split(MediumLevelILInstruction): def low(self) -> variable.Variable: return self.get_var(1) + @property + def operands(self) -> List[variable.Variable]: + return [self.high, self.low] + @dataclass(frozen=True, repr=False) class MediumLevelILAddress_of_field(MediumLevelILInstruction): - operand_names = tuple(["src", "offset"]) @property def src(self) -> variable.Variable: @@ -1171,10 +1292,13 @@ class MediumLevelILAddress_of_field(MediumLevelILInstruction): def offset(self) -> int: return self.get_int(1) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.src, self.offset] + @dataclass(frozen=True, repr=False) -class MediumLevelILExtern_ptr(Constant): - operand_names = tuple(["constant", "offset"]) +class MediumLevelILExtern_ptr(MediumLevelILConstBase): @property def constant(self) -> int: @@ -1184,172 +1308,178 @@ class MediumLevelILExtern_ptr(Constant): def offset(self) -> int: return self.get_int(1) + @property + def operands(self) -> List[int]: + return [self.constant, self.offset] + @dataclass(frozen=True, repr=False) -class MediumLevelILAdd(BinaryOperation, Arithmetic): +class MediumLevelILAdd(MediumLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILSub(BinaryOperation, Arithmetic): +class MediumLevelILSub(MediumLevelILBinaryBase, Arithmetic): pass + @dataclass(frozen=True, repr=False) -class MediumLevelILAnd(BinaryOperation, Arithmetic): +class MediumLevelILAnd(MediumLevelILBinaryBase, Arithmetic): pass + @dataclass(frozen=True, repr=False) -class MediumLevelILOr(BinaryOperation, Arithmetic): +class MediumLevelILOr(MediumLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILXor(BinaryOperation, Arithmetic): +class MediumLevelILXor(MediumLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILLsl(BinaryOperation, Arithmetic): +class MediumLevelILLsl(MediumLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILLsr(BinaryOperation, Arithmetic): +class MediumLevelILLsr(MediumLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILAsr(BinaryOperation, Arithmetic): +class MediumLevelILAsr(MediumLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILRol(BinaryOperation, Arithmetic): +class MediumLevelILRol(MediumLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILRor(BinaryOperation, Arithmetic): +class MediumLevelILRor(MediumLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILMul(BinaryOperation, Arithmetic): +class MediumLevelILMul(MediumLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILMulu_dp(BinaryOperation, DoublePrecision): +class MediumLevelILMulu_dp(MediumLevelILBinaryBase, DoublePrecision): pass @dataclass(frozen=True, repr=False) -class MediumLevelILMuls_dp(BinaryOperation, DoublePrecision, Signed): +class MediumLevelILMuls_dp(MediumLevelILBinaryBase, DoublePrecision, Signed): pass @dataclass(frozen=True, repr=False) -class MediumLevelILDivu(BinaryOperation, Arithmetic): +class MediumLevelILDivu(MediumLevelILBinaryBase, Arithmetic): pass + @dataclass(frozen=True, repr=False) -class MediumLevelILDivu_dp(BinaryOperation, DoublePrecision): +class MediumLevelILDivu_dp(MediumLevelILBinaryBase, DoublePrecision): pass @dataclass(frozen=True, repr=False) -class MediumLevelILDivs(BinaryOperation, Arithmetic, Signed): +class MediumLevelILDivs(MediumLevelILBinaryBase, Arithmetic, Signed): pass @dataclass(frozen=True, repr=False) -class MediumLevelILDivs_dp(BinaryOperation, DoublePrecision, Signed): +class MediumLevelILDivs_dp(MediumLevelILBinaryBase, DoublePrecision, Signed): pass @dataclass(frozen=True, repr=False) -class MediumLevelILModu(BinaryOperation, Arithmetic): +class MediumLevelILModu(MediumLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILModu_dp(BinaryOperation, DoublePrecision): +class MediumLevelILModu_dp(MediumLevelILBinaryBase, DoublePrecision): pass @dataclass(frozen=True, repr=False) -class MediumLevelILMods(BinaryOperation, Arithmetic, Signed): +class MediumLevelILMods(MediumLevelILBinaryBase, Arithmetic, Signed): pass @dataclass(frozen=True, repr=False) -class MediumLevelILMods_dp(BinaryOperation, DoublePrecision, Signed): +class MediumLevelILMods_dp(MediumLevelILBinaryBase, DoublePrecision, Signed): pass @dataclass(frozen=True, repr=False) -class MediumLevelILCmp_e(Comparison): +class MediumLevelILCmp_e(MediumLevelILComparisonBase): pass @dataclass(frozen=True, repr=False) -class MediumLevelILCmp_ne(Comparison): +class MediumLevelILCmp_ne(MediumLevelILComparisonBase): pass @dataclass(frozen=True, repr=False) -class MediumLevelILCmp_slt(Comparison, Signed): +class MediumLevelILCmp_slt(MediumLevelILComparisonBase, Signed): pass @dataclass(frozen=True, repr=False) -class MediumLevelILCmp_ult(Comparison): +class MediumLevelILCmp_ult(MediumLevelILComparisonBase): pass @dataclass(frozen=True, repr=False) -class MediumLevelILCmp_sle(Comparison, Signed): +class MediumLevelILCmp_sle(MediumLevelILComparisonBase, Signed): pass @dataclass(frozen=True, repr=False) -class MediumLevelILCmp_ule(Comparison): +class MediumLevelILCmp_ule(MediumLevelILComparisonBase): pass @dataclass(frozen=True, repr=False) -class MediumLevelILCmp_sge(Comparison, Signed): +class MediumLevelILCmp_sge(MediumLevelILComparisonBase, Signed): pass @dataclass(frozen=True, repr=False) -class MediumLevelILCmp_uge(Comparison): +class MediumLevelILCmp_uge(MediumLevelILComparisonBase): pass @dataclass(frozen=True, repr=False) -class MediumLevelILCmp_sgt(Comparison, Signed): +class MediumLevelILCmp_sgt(MediumLevelILComparisonBase, Signed): pass @dataclass(frozen=True, repr=False) -class MediumLevelILCmp_ugt(Comparison): +class MediumLevelILCmp_ugt(MediumLevelILComparisonBase): pass @dataclass(frozen=True, repr=False) -class MediumLevelILTest_bit(Comparison): +class MediumLevelILTest_bit(MediumLevelILComparisonBase): pass @dataclass(frozen=True, repr=False) -class MediumLevelILAdd_overflow(BinaryOperation, Arithmetic): +class MediumLevelILAdd_overflow(MediumLevelILBinaryBase, Arithmetic): pass @dataclass(frozen=True, repr=False) -class MediumLevelILSyscall(Syscall): - operand_names = tuple(["output", "params"]) +class MediumLevelILSyscall(MediumLevelILInstruction, Syscall): @property def output(self) -> List[variable.Variable]: @@ -1359,10 +1489,13 @@ class MediumLevelILSyscall(Syscall): def params(self) -> List[MediumLevelILInstruction]: return self.get_expr_list(2, 3) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.output, self.params] # TODO: Expand output and params before regeneration + @dataclass(frozen=True, repr=False) -class MediumLevelILVar_ssa_field(SSA): - operand_names = tuple(["src", "offset"]) +class MediumLevelILVar_ssa_field(MediumLevelILInstruction, SSA): @property def src(self) -> SSAVariable: @@ -1372,10 +1505,13 @@ class MediumLevelILVar_ssa_field(SSA): def offset(self) -> int: return self.get_int(2) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.src, self.offset] + @dataclass(frozen=True, repr=False) -class MediumLevelILVar_aliased_field(SSA): - operand_names = tuple(["src", "offset"]) +class MediumLevelILVar_aliased_field(MediumLevelILInstruction, SSA): @property def src(self) -> SSAVariable: @@ -1385,10 +1521,13 @@ class MediumLevelILVar_aliased_field(SSA): def offset(self) -> int: return self.get_int(2) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.src, self.offset] + @dataclass(frozen=True, repr=False) -class MediumLevelILVar_split_ssa(SSA): - operand_names = tuple(["high", "low"]) +class MediumLevelILVar_split_ssa(MediumLevelILInstruction, SSA): @property def high(self) -> SSAVariable: @@ -1398,10 +1537,13 @@ class MediumLevelILVar_split_ssa(SSA): def low(self) -> SSAVariable: return self.get_var_ssa(2, 3) + @property + def operands(self) -> List[SSAVariable]: + return [self.high, self.low] + @dataclass(frozen=True, repr=False) -class MediumLevelILCall_output_ssa(SSA): - operand_names = tuple(["dest_memory", "dest"]) +class MediumLevelILCall_output_ssa(MediumLevelILInstruction, SSA): @property def dest_memory(self) -> int: @@ -1415,10 +1557,13 @@ class MediumLevelILCall_output_ssa(SSA): def vars_written(self) -> List[SSAVariable]: return self.dest + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.dest_memory, *self.dest] + @dataclass(frozen=True, repr=False) -class MediumLevelILCall_param_ssa(SSA): - operand_names = tuple(["src_memory", "src"]) +class MediumLevelILCall_param_ssa(MediumLevelILInstruction, SSA): @property def src_memory(self) -> int: @@ -1428,10 +1573,13 @@ class MediumLevelILCall_param_ssa(SSA): def src(self) -> List[SSAVariable]: return self.get_var_ssa_list(1, 2) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.src_memory, *self.src] + @dataclass(frozen=True, repr=False) -class MediumLevelILLoad_ssa(Load, SSA): - operand_names = tuple(["src", "src_memory"]) +class MediumLevelILLoad_ssa(MediumLevelILInstruction, Load, SSA): @property def src(self) -> MediumLevelILInstruction: @@ -1441,10 +1589,13 @@ class MediumLevelILLoad_ssa(Load, SSA): def src_memory(self) -> int: return self.get_int(1) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.src, self.src_memory] + @dataclass(frozen=True, repr=False) -class MediumLevelILVar_phi(Phi, SetVar, SSA): - operand_names = tuple(["dest", "src"]) +class MediumLevelILVar_phi(MediumLevelILInstruction, SetVar, Phi, SSA): @property def dest(self) -> SSAVariable: @@ -1454,10 +1605,17 @@ class MediumLevelILVar_phi(Phi, SetVar, SSA): def src(self) -> List[SSAVariable]: return self.get_var_ssa_list(2, 3) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.dest, *self.src] + + @property + def vars_read(self) -> List[SSAVariable]: + return self.src + @dataclass(frozen=True, repr=False) -class MediumLevelILMem_phi(Memory, Phi): - operand_names = tuple(["dest_memory", "src_memory"]) +class MediumLevelILMem_phi(MediumLevelILInstruction, Memory, Phi): @property def dest_memory(self) -> int: @@ -1467,10 +1625,13 @@ class MediumLevelILMem_phi(Memory, Phi): def src_memory(self) -> List[int]: return self.get_int_list(1) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.dest_memory, *self.src_memory] + @dataclass(frozen=True, repr=False) -class MediumLevelILSet_var_ssa(SetVar): - operand_names = tuple(["dest", "src"]) +class MediumLevelILSet_var_ssa(MediumLevelILInstruction, SetVar, SSA): @property def dest(self) -> SSAVariable: @@ -1480,83 +1641,97 @@ class MediumLevelILSet_var_ssa(SetVar): def src(self) -> MediumLevelILInstruction: return self.get_expr(2) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.dest, self.src] + + @property + def vars_read(self) -> List[Union[variable.Variable, SSAVariable]]: + return self.src.vars_read + + @property + def vars_written(self) -> List[SSAVariable]: + return [self.dest] + @dataclass(frozen=True, repr=False) -class MediumLevelILFcmp_e(Comparison, FloatingPoint): +class MediumLevelILFcmp_e(MediumLevelILComparisonBase, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFcmp_ne(Comparison, FloatingPoint): +class MediumLevelILFcmp_ne(MediumLevelILComparisonBase, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFcmp_lt(Comparison, FloatingPoint): +class MediumLevelILFcmp_lt(MediumLevelILComparisonBase, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFcmp_le(Comparison, FloatingPoint): +class MediumLevelILFcmp_le(MediumLevelILComparisonBase, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFcmp_ge(Comparison, FloatingPoint): +class MediumLevelILFcmp_ge(MediumLevelILComparisonBase, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFcmp_gt(Comparison, FloatingPoint): +class MediumLevelILFcmp_gt(MediumLevelILComparisonBase, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFcmp_o(Comparison, FloatingPoint): +class MediumLevelILFcmp_o(MediumLevelILComparisonBase, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFcmp_uo(Comparison, FloatingPoint): +class MediumLevelILFcmp_uo(MediumLevelILComparisonBase, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFadd(BinaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILFadd(MediumLevelILBinaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFsub(BinaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILFsub(MediumLevelILBinaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFmul(BinaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILFmul(MediumLevelILBinaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILFdiv(BinaryOperation, Arithmetic, FloatingPoint): +class MediumLevelILFdiv(MediumLevelILBinaryBase, Arithmetic, FloatingPoint): pass @dataclass(frozen=True, repr=False) -class MediumLevelILJump_to(Terminal): - operand_names = tuple(["dest", "targets"]) +class MediumLevelILJump_to(MediumLevelILInstruction, Terminal): @property def dest(self) -> MediumLevelILInstruction: return self.get_expr(0) @property - def targets(self): + def targets(self) -> Mapping[int, int]: return self.get_target_map(1, 2) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.dest, self.targets] + @dataclass(frozen=True, repr=False) -class MediumLevelILSet_var_aliased(SetVar, SSA): - operand_names = tuple(["dest", "prev", "src"]) +class MediumLevelILSet_var_aliased(MediumLevelILInstruction, SetVar, SSA): @property def dest(self) -> SSAVariable: @@ -1570,24 +1745,32 @@ class MediumLevelILSet_var_aliased(SetVar, SSA): def src(self) -> MediumLevelILInstruction: return self.get_expr(3) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.dest, self.prev, self.src] + + @property + def vars_read(self) -> List[Union[variable.Variable, SSAVariable]]: + return self.src.vars_read + + @property + def vars_written(self) -> List[SSAVariable]: + return [self.dest] + + @dataclass(frozen=True, repr=False) -class MediumLevelILSyscall_untyped(Syscall): - operand_names = tuple(["output", "params", "stack"]) +class MediumLevelILSyscall_untyped(MediumLevelILCallBase, Syscall): @property - def output(self): + def output(self) -> List[variable.Variable]: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output), "MediumLevelILCall_untyped return bad type for 'output'" return inst.dest @property - def dest(self) -> MediumLevelILInstruction: - return self.get_expr(1) - - @property - def params(self): - inst = self.get_expr(2) + def params(self) -> List[variable.Variable]: + inst = self.get_expr(1) assert isinstance(inst, MediumLevelILCall_param), "MediumLevelILCall_untyped return bad type for 'params'" return inst.src @@ -1595,10 +1778,13 @@ class MediumLevelILSyscall_untyped(Syscall): def stack(self) -> MediumLevelILInstruction: return self.get_expr(2) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [*self.output, *self.params, self.stack] + @dataclass(frozen=True, repr=False) class MediumLevelILIntrinsic(MediumLevelILInstruction): - operand_names = tuple(["output", "intrinsic", "params"]) @property def output(self) -> List[variable.Variable]: @@ -1623,11 +1809,13 @@ class MediumLevelILIntrinsic(MediumLevelILInstruction): def vars_written(self) -> List[variable.Variable]: return self.output + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.output, self.intrinsic, self.params] @dataclass(frozen=True, repr=False) -class MediumLevelILIntrinsic_ssa(SSA): - operand_names = tuple(["output", "intrinsic", "params"]) +class MediumLevelILIntrinsic_ssa(MediumLevelILInstruction, SSA): @property def output(self) -> List[SSAVariable]: @@ -1652,10 +1840,13 @@ class MediumLevelILIntrinsic_ssa(SSA): def vars_written(self) -> List[SSAVariable]: return self.output + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.output, self.intrinsic, self.params] # TODO: Expand output and params before regeneration + @dataclass(frozen=True, repr=False) -class MediumLevelILSet_var_ssa_field(SetVar): - operand_names = tuple(["dest", "prev", "offset", "src"]) +class MediumLevelILSet_var_ssa_field(MediumLevelILInstruction, SetVar, SSA): @property def dest(self) -> SSAVariable: @@ -1677,10 +1868,17 @@ class MediumLevelILSet_var_ssa_field(SetVar): def vars_read(self) -> List[SSAVariable]: return [self.prev, *self.src.vars_read] # type: ignore we're guaranteed not to return non-SSAVariables here + @property + def vars_written(self) -> List[SSAVariable]: + return [self.dest] + + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.dest, self.prev, self.offset, self.src] + @dataclass(frozen=True, repr=False) -class MediumLevelILSet_var_split_ssa(SetVar): - operand_names = tuple(["high", "low", "src"]) +class MediumLevelILSet_var_split_ssa(MediumLevelILInstruction, SetVar, SSA): @property def high(self) -> SSAVariable: @@ -1694,14 +1892,21 @@ class MediumLevelILSet_var_split_ssa(SetVar): def src(self) -> MediumLevelILInstruction: return self.get_expr(4) + @property + def vars_read(self) -> List[Union[variable.Variable, SSAVariable]]: + return self.src.vars_read + @property def vars_written(self) -> List[SSAVariable]: return [self.high, self.low] + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.high, self.low, self.src] + @dataclass(frozen=True, repr=False) -class MediumLevelILSet_var_aliased_field(SetVar, SSA): - operand_names = tuple(["dest", "prev", "offset", "src"]) +class MediumLevelILSet_var_aliased_field(MediumLevelILInstruction, SetVar, SSA): @property def dest(self) -> SSAVariable: @@ -1723,10 +1928,13 @@ class MediumLevelILSet_var_aliased_field(SetVar, SSA): def vars_read(self) -> List[SSAVariable]: return [self.prev, *self.src.vars_read] # type: ignore we're guaranteed not to return non-SSAVariables here + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.dest, self.prev, self.offset, self.src] + @dataclass(frozen=True, repr=False) -class MediumLevelILSyscall_ssa(Syscall, SSA): - operand_names = tuple(["output", "params", "src_memory"]) +class MediumLevelILSyscall_ssa(MediumLevelILCallBase, Syscall, SSA): @property def output(self) -> List[SSAVariable]: @@ -1748,10 +1956,13 @@ class MediumLevelILSyscall_ssa(Syscall, SSA): def src_memory(self) -> int: return self.get_int(3) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [*self.output, *self.params, self.src_memory] + @dataclass(frozen=True, repr=False) -class MediumLevelILSyscall_untyped_ssa(Syscall, SSA): - operand_names = tuple(["output", "params", "stack"]) +class MediumLevelILSyscall_untyped_ssa(MediumLevelILCallBase, Syscall, SSA): @property def output(self) -> List[SSAVariable]: @@ -1781,10 +1992,13 @@ class MediumLevelILSyscall_untyped_ssa(Syscall, SSA): def stack(self) -> MediumLevelILInstruction: return self.get_expr(2) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [*self.output, *self.params, self.stack] + @dataclass(frozen=True, repr=False) -class MediumLevelILLoad_struct_ssa(Load, SSA): - operand_names = tuple(["src", "offset", "src_memory"]) +class MediumLevelILLoad_struct_ssa(MediumLevelILInstruction, Load, SSA): @property def src(self) -> MediumLevelILInstruction: @@ -1798,10 +2012,13 @@ class MediumLevelILLoad_struct_ssa(Load, SSA): def src_memory(self) -> int: return self.get_int(2) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.src, self.offset, self.src_memory] + @dataclass(frozen=True, repr=False) -class MediumLevelILSet_var_field(SetVar): - operand_names = tuple(["dest", "offset", "src"]) +class MediumLevelILSet_var_field(MediumLevelILInstruction, SetVar): @property def dest(self) -> variable.Variable: @@ -1815,10 +2032,13 @@ class MediumLevelILSet_var_field(SetVar): def src(self) -> MediumLevelILInstruction: return self.get_expr(2) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.dest, self.offset, self.src] + @dataclass(frozen=True, repr=False) -class MediumLevelILSet_var_split(SetVar): - operand_names = tuple(["high", "low", "src"]) +class MediumLevelILSet_var_split(MediumLevelILInstruction, SetVar): @property def high(self) -> variable.Variable: @@ -1836,10 +2056,13 @@ class MediumLevelILSet_var_split(SetVar): def vars_written(self) -> List[variable.Variable]: return [self.high, self.low] + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.high, self.low, self.src] + @dataclass(frozen=True, repr=False) -class MediumLevelILStore_struct(Store): - operand_names = tuple(["dest", "offset", "src"]) +class MediumLevelILStore_struct(MediumLevelILInstruction, Store): @property def dest(self) -> MediumLevelILInstruction: @@ -1853,30 +2076,33 @@ class MediumLevelILStore_struct(Store): def src(self) -> MediumLevelILInstruction: return self.get_expr(2) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.dest, self.offset, self.src] + @dataclass(frozen=True, repr=False) -class MediumLevelILAdc(Carry): +class MediumLevelILAdc(MediumLevelILCarryBase): pass @dataclass(frozen=True, repr=False) -class MediumLevelILSbb(Carry): +class MediumLevelILSbb(MediumLevelILCarryBase): pass @dataclass(frozen=True, repr=False) -class MediumLevelILRlc(Carry): +class MediumLevelILRlc(MediumLevelILCarryBase): pass @dataclass(frozen=True, repr=False) -class MediumLevelILRrc(Carry): +class MediumLevelILRrc(MediumLevelILCarryBase): pass @dataclass(frozen=True, repr=False) -class MediumLevelILCall(Call): - operand_names = tuple(["output", "dest", "params"]) +class MediumLevelILCall(MediumLevelILCallBase): @property def output(self) -> List[variable.Variable]: @@ -1890,10 +2116,13 @@ class MediumLevelILCall(Call): def params(self) -> List[MediumLevelILInstruction]: return self.get_expr_list(3, 4) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.output, self.dest, self.params] # TODO: Expand output and params before regeneration + @dataclass(frozen=True, repr=False) -class MediumLevelILIf(Terminal): - operand_names = tuple(["condition", "true", "false"]) +class MediumLevelILIf(MediumLevelILInstruction, Terminal): @property def condition(self) -> MediumLevelILInstruction: @@ -1907,10 +2136,13 @@ class MediumLevelILIf(Terminal): def false(self) -> int: return self.get_int(2) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.condition, self.true, self.false] + @dataclass(frozen=True, repr=False) -class MediumLevelILTailcall_untyped(Tailcall): - operand_names = tuple(["output", "dest", "params", "stack"]) +class MediumLevelILTailcall_untyped(MediumLevelILCallBase, Tailcall): @property def output(self) -> List[variable.Variable]: @@ -1932,10 +2164,13 @@ class MediumLevelILTailcall_untyped(Tailcall): def stack(self) -> MediumLevelILInstruction: return self.get_expr(3) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [*self.output, self.dest, *self.params, self.stack] + @dataclass(frozen=True, repr=False) -class MediumLevelILCall_ssa(Call, SSA): - operand_names = tuple(["output", "dest", "params", "src_memory"]) +class MediumLevelILCall_ssa(MediumLevelILCallBase, SSA): @property def output(self) -> List[SSAVariable]: @@ -1961,10 +2196,13 @@ class MediumLevelILCall_ssa(Call, SSA): def src_memory(self) -> int: return self.get_int(4) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [*self.output, self.dest, *self.params, self.src_memory] + @dataclass(frozen=True, repr=False) -class MediumLevelILCall_untyped_ssa(Call, SSA): - operand_names = tuple(["output", "dest", "params", "stack"]) +class MediumLevelILCall_untyped_ssa(MediumLevelILCallBase, SSA): @property def output(self) -> List[SSAVariable]: @@ -1998,10 +2236,13 @@ class MediumLevelILCall_untyped_ssa(Call, SSA): def stack(self) -> MediumLevelILInstruction: return self.get_expr(3) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [*self.output, self.dest, *self.params, self.stack] + @dataclass(frozen=True, repr=False) -class MediumLevelILTailcall(Tailcall): - operand_names = tuple(["output", "dest", "params"]) +class MediumLevelILTailcall(MediumLevelILCallBase, Tailcall): @property def output(self) -> List[variable.Variable]: @@ -2015,10 +2256,13 @@ class MediumLevelILTailcall(Tailcall): def params(self) -> List[MediumLevelILInstruction]: return self.get_expr_list(3, 4) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.output, self.dest, self.params] # TODO: Expand output and params before regeneration + @dataclass(frozen=True, repr=False) -class MediumLevelILTailcall_ssa(Tailcall, SSA): - operand_names = tuple(["output", "dest", "params", "src_memory"]) +class MediumLevelILTailcall_ssa(MediumLevelILCallBase, Tailcall, SSA): @property def output(self) -> List[SSAVariable]: @@ -2044,10 +2288,13 @@ class MediumLevelILTailcall_ssa(Tailcall, SSA): def src_memory(self) -> int: return self.get_int(4) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [*self.output, self.dest, *self.params, self.src_memory] + @dataclass(frozen=True, repr=False) -class MediumLevelILTailcall_untyped_ssa(Tailcall, SSA): - operand_names = tuple(["output", "dest", "params", "stack"]) +class MediumLevelILTailcall_untyped_ssa(MediumLevelILCallBase, Tailcall, SSA): @property def output(self) -> List[SSAVariable]: @@ -2073,10 +2320,13 @@ class MediumLevelILTailcall_untyped_ssa(Tailcall, SSA): def stack(self) -> MediumLevelILInstruction: return self.get_expr(3) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [*self.output, self.dest, self.params, self.stack] + @dataclass(frozen=True, repr=False) -class MediumLevelILStore_ssa(Store, SSA): - operand_names = tuple(["dest", "dest_memory", "src_memory", "src"]) +class MediumLevelILStore_ssa(MediumLevelILInstruction, Store, SSA): @property def dest(self) -> MediumLevelILInstruction: @@ -2094,10 +2344,13 @@ class MediumLevelILStore_ssa(Store, SSA): def src(self) -> MediumLevelILInstruction: return self.get_expr(3) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.dest, self.dest_memory, self.src_memory, self.src] + @dataclass(frozen=True, repr=False) -class MediumLevelILCall_untyped(Call): - operand_names = tuple(["output", "dest", "params", "stack"]) +class MediumLevelILCall_untyped(MediumLevelILCallBase): @property def output(self) -> List[variable.Variable]: @@ -2119,10 +2372,13 @@ class MediumLevelILCall_untyped(Call): def stack(self) -> MediumLevelILInstruction: return self.get_expr(3) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [*self.output, self.dest, *self.params, self.stack] + @dataclass(frozen=True, repr=False) -class MediumLevelILStore_struct_ssa(Store, SSA): - operand_names = tuple(["dest", "offset", "dest_memory", "src_memory", "src"]) +class MediumLevelILStore_struct_ssa(MediumLevelILInstruction, Store, SSA): @property def dest(self) -> MediumLevelILInstruction: @@ -2144,6 +2400,11 @@ class MediumLevelILStore_struct_ssa(Store, SSA): def src(self) -> MediumLevelILInstruction: return self.get_expr(4) + @property + def operands(self) -> List[MediumLevelILOperandType]: + return [self.dest, self.offset, self.dest_memory, self.src_memory, self.src] + + ILInstruction = { MediumLevelILOperation.MLIL_NOP:MediumLevelILNop, # [], MediumLevelILOperation.MLIL_NORET:MediumLevelILNoret, # [], -- cgit v1.3.1