Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _ail_handle_Convert(self, expr):
to_conv = self._expr(expr.operand)
if type(to_conv) is int:
return to_conv
r = None
if expr.from_bits == to_conv.bits and \
isinstance(to_conv, DataSet):
if len(to_conv) == 1 and type(next(iter(to_conv.data))) is Undefined:
r = DataSet(to_conv.data.copy(), expr.to_bits)
elif all(isinstance(d, (ailment.Expr.Const, int)) for d in to_conv.data):
converted = set()
for d in to_conv.data:
if isinstance(d, ailment.Expr.Const):
converted.add(ailment.Expr.Const(d.idx, d.variable, d.value, expr.to_bits))
else: # isinstance(d, int)
converted.add(d)
r = DataSet(converted, expr.to_bits)
if r is None:
r = ailment.Expr.Convert(expr.idx, expr.from_bits, expr.to_bits, expr.is_signed,
to_conv)
r = DataSet(r, expr.to_bits)
return r
def _ail_handle_Convert(self, expr):
operand_expr = self._expr(expr.operand)
if type(operand_expr) is Expr.Convert:
if expr.from_bits == operand_expr.to_bits and expr.to_bits == operand_expr.from_bits:
# eliminate the redundant Convert
return operand_expr.operand
else:
return Expr.Convert(expr.idx, operand_expr.from_bits, expr.to_bits, expr.is_signed, operand_expr.operand)
elif type(operand_expr) is Expr.Const:
# do the conversion right away
value = operand_expr.value
mask = (2 ** expr.to_bits) - 1
value &= mask
return Expr.Const(expr.idx, operand_expr.variable, value, expr.to_bits)
converted = Expr.Convert(expr.idx, expr.from_bits, expr.to_bits, expr.is_signed, operand_expr)
return converted
def _ail_handle_Convert(self, expr):
if expr.from_bits == 128 and expr.to_bits == 64:
operand_expr = self._expr(expr.operand)
if isinstance(operand_expr, Expr.BinaryOp) \
and operand_expr.op == 'Mul' \
and isinstance(operand_expr.operands[1], Expr.Const) \
and isinstance(operand_expr.operands[0], Expr.BinaryOp):
if operand_expr.operands[0].op in {'Shr', 'DivMod'} \
and isinstance(operand_expr.operands[0].operands[1], Expr.Const):
if operand_expr.operands[0].op == 'Shr':
Y = operand_expr.operands[0].operands[1].value
else:
Y = int(math.log2(operand_expr.operands[0].operands[1].value))
C = operand_expr.operands[1].value
divisor = self._check_divisor(pow(2, 64+Y), C)
if divisor:
X = operand_expr.operands[0].operands[0]
new_const = Expr.Const(expr.idx, None, divisor, 64)
return Expr.BinaryOp(expr.idx, 'DivMod', [X, new_const], **expr.tags)
return super()._ail_handle_Convert(expr)
def _ail_handle_Sub(self, expr):
operand_0 = self._expr(expr.operands[0])
operand_1 = self._expr(expr.operands[1])
if isinstance(operand_0, Expr.Const) and isinstance(operand_1, Expr.Const):
return Expr.Const(expr.idx, None, operand_0.value - operand_1.value, expr.bits)
elif isinstance(operand_0, Expr.BasePointerOffset) and isinstance(operand_1, Expr.Const):
r = operand_0.copy()
r.offset -= operand_1.value
return r
return Expr.BinaryOp(expr.idx, 'Sub', [ operand_0 if operand_0 is not None else expr.operands[0],
operand_1 if operand_1 is not None else expr.operands[1]
])
def _goto_handle_block(self, block, successor): # pylint:disable=no-self-use
"""
:param ailment.Block block:
:return:
"""
if block.statements and isinstance(block.statements[-1], ailment.Stmt.Jump):
goto_stmt = block.statements[-1] # ailment.Stmt.Jump
if successor and isinstance(goto_stmt.target, ailment.Expr.Const) \
and goto_stmt.target.value == successor.addr:
# we can remove this statement
block.statements = block.statements[:-1]
def _ail_handle_Add(self, expr):
operand_0 = self._expr(expr.operands[0])
operand_1 = self._expr(expr.operands[1])
if isinstance(operand_0, Expr.Const) and isinstance(operand_1, Expr.Const):
return Expr.Const(expr.idx, None, operand_0.value + operand_1.value, expr.bits)
elif isinstance(operand_0, Expr.BasePointerOffset) and isinstance(operand_1, Expr.Const):
r = operand_0.copy()
r.offset += operand_1.value
return r
return Expr.BinaryOp(expr.idx, 'Add', [operand_0 if operand_0 is not None else expr.operands[0],
operand_1 if operand_1 is not None else expr.operands[1]
])
target = stmt.target
if isinstance(target, CConstant):
target_func = self.kb.functions.function(addr=target.value)
else:
target_func = None
args = [ ]
if target_func is not None and target_func.prototype is not None and stmt.args is not None:
for i, arg in enumerate(stmt.args):
if i < len(target_func.prototype.args):
type_ = target_func.prototype.args[i].with_arch(self.project.arch)
else:
type_ = None
reference_values = { }
if isinstance(arg, Expr.Const):
if isinstance(type_, SimTypePointer) and isinstance(type_.pts_to, SimTypeChar):
# char*
# Try to get a string
if self._cfg is not None:
if arg.value in self._cfg.memory_data and self._cfg.memory_data[arg.value].sort == 'string':
reference_values[type_] = self._cfg.memory_data[arg.value]
elif isinstance(type_, SimTypeInt):
# int
reference_values[type_] = arg.value
new_arg = CConstant(arg, type_, reference_values if reference_values else None)
else:
new_arg = self._handle(arg)
args.append(new_arg)
ret_expr = None
if stmt.ret_expr is not None:
'BoolV': lambda cond_: ailment.Expr.Const(None, None, True, 1) if cond_.args[0] is True
else ailment.Expr.Const(None, None, False, 1),
}
def _ail_handle_Convert(self, expr):
to_conv = self._expr(expr.operand)
if type(to_conv) is int:
return to_conv
r = None
if expr.from_bits == to_conv.bits and \
isinstance(to_conv, DataSet):
if len(to_conv) == 1 and type(next(iter(to_conv.data))) is Undefined:
r = DataSet(to_conv.data.copy(), expr.to_bits)
elif all(isinstance(d, (ailment.Expr.Const, int)) for d in to_conv.data):
converted = set()
for d in to_conv.data:
if isinstance(d, ailment.Expr.Const):
converted.add(ailment.Expr.Const(d.idx, d.variable, d.value, expr.to_bits))
else: # isinstance(d, int)
converted.add(d)
r = DataSet(converted, expr.to_bits)
if r is None:
r = ailment.Expr.Convert(expr.idx, expr.from_bits, expr.to_bits, expr.is_signed,
to_conv)
r = DataSet(r, expr.to_bits)
return r
if expr.op != "Xor":
continue
op0, op1 = expr.operands
if not isinstance(op0, ailment.Expr.Load):
continue
if not isinstance(op0.addr, ailment.Expr.StackBaseOffset):
continue
if op0.addr.offset != s2u(canary_value_stack_offset, self.project.arch.bits):
continue
if not isinstance(op1, ailment.Expr.Load):
continue
if not isinstance(op1.addr, ailment.Expr.BinaryOp):
continue
if not op1.addr.op == "Add":
continue
if not isinstance(op1.addr.operands[0], ailment.Expr.Const):
continue
if op1.addr.operands[0].value != 0x28:
continue
if not isinstance(op1.addr.operands[1], ailment.Expr.Register):
continue
if op1.addr.operands[1].reg_offset != self.project.arch.get_register_offset('fs'):
continue
# Found it
return idx
return None