def int2i16(i: int) -> i16: if utils.is_all_real(i): i = i & 0xFFFF if i & 0x8000: return i - 0x10000 return i return z3.Extract(15, 0, i)
def u16(r: list): if utils.is_all_real(r[0], r[1]): return ctypes.c_uint16(r[0] + (r[1] << 8)).value else: for i in range(len(r)): r[i] = utils.to_symbolic(r[i], 8) return z3.Concat(r[1], r[0])
def int2i32(i: int) -> i32: if utils.is_all_real(i): i = i & 0xFFFFFFFF if i & 0x80000000: return i - 0x100000000 return i return z3.Extract(31, 0, i)
def int2i64(i: int) -> i64: if utils.is_all_real(i): i = i & 0xFFFFFFFFFFFFFFFF if i & 0x8000000000000000: return i - 0x10000000000000000 return i return z3.Extract(63, 0, i)
def int2i8(i: int) -> i8: if utils.is_all_real(i): i = i & 0xFF if i & 0x80: return i - 0x100 return i return z3.Extract(7, 0, i)
def i32(r: list): if utils.is_all_real(r[0], r[1], r[2], r[3]): return ctypes.c_int32(r[0] + (r[1] << 8) + (r[2] << 16) + (r[3] << 24)).value else: for i in range(len(r)): r[i] = utils.to_symbolic(r[i], 8) return z3.Concat(r[3], r[2], r[1], r[0])
def i64(r: list): if utils.is_all_real(r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]): return ctypes.c_int64(r[0] + (r[1] << 8) + (r[2] << 16) + (r[3] << 24) + (r[4] << 32) + (r[5] << 40) + (r[6] << 48) + (r[7] << 56)).value else: for i in range(len(r)): r[i] = utils.to_symbolic(r[i], 8) return z3.Concat(r[7], r[6], r[5], r[4], r[3], r[2], r[1], r[0])
def pack_f32(n: f32): if utils.is_all_real(n): float_bytes = struct.pack('<f', n) return [float_bytes for float_byte in float_bytes] f32_bv = z3.fpToIEEEBV(n) return [ z3.Extract(7, 0, f32_bv), z3.Extract(15, 8, f32_bv), z3.Extract(23, 16, f32_bv), z3.Extract(31, 24, f32_bv) ]
def fake_eos_analysis(store, frame, stack, expr, pc, solver=None): global_vars.pc = pc transfer_int64 = utils.eos_abi_to_int('transfer') action_param = 2 end = len(expr.data) if _check_n_call(expr, pc): local_number = expr.data[pc + 7].immediate_arguments frame.locals[local_number] = Value.from_i64( _get_encoding(expr.data[pc + 4].immediate_arguments)) pc = expr.composition[pc + 8][-1] elif expr.data[pc].code == bin_format.call and expr.data[ pc].immediate_arguments in global_vars.eosio_assert_addrs: cond = stack.data[-2].n if utils.is_all_real(cond): if not cond: pc = end else: solver.push() solver.add(z3.simplify(cond == 1)) if utils.check_sat(solver) == z3.unsat: pc = end solver.pop() elif ((expr.data[pc].code == bin_format.get_local and expr.data[pc].immediate_arguments == action_param and expr.data[pc + 1].code == bin_format.i64_const and expr.data[pc + 1].immediate_arguments == transfer_int64) or (expr.data[pc].code == bin_format.i64_const and expr.data[pc].immediate_arguments == transfer_int64 and expr.data[pc + 1].code == bin_format.get_local and expr.data[pc + 1].immediate_arguments == action_param)): if (expr.data[pc + 2].code in (bin_format.i64_eq, bin_format.i64_ne) and expr.data[pc + 3].code == bin_format.br_if): transfer_block_pc = (_get_branch_pc( expr.data[pc + 3].immediate_arguments, stack) if expr.data[pc + 2].code == bin_format.i64_eq else pc + 4) for i in range(transfer_block_pc, end - 2): if (expr.data[i].code == bin_format.call and expr.data[i + 1].code == bin_format.drop and expr.data[i + 2].code in (bin_format.br, bin_format.end)): global_vars.find_fake_eos_transfer() if expr.data[i].code not in (bin_format.get_local, bin_format.i32_const, bin_format.i32_store, bin_format.i64_load, bin_format.i64_store, bin_format.i32_add): break global_vars.pc = pc
def pack_u32(n: u32): if utils.is_all_real(n): return [ n & 0xFF, (n & 0xFF00) >> 8, (n & 0xFF0000) >> 16, (n & 0xFF000000) >> 24 ] else: return [ z3.Extract(7, 0, n), z3.Extract(15, 8, n), z3.Extract(23, 16, n), z3.Extract(31, 24, n) ]
def pack_f64(n: f64): if utils.is_all_real(n): double_bytes = struct.pack('<d', n) return [double_byte for double_byte in double_bytes] f64_bv = z3.fpToIEEEBV(n) return [ z3.Extract(7, 0, f64_bv), z3.Extract(15, 8, f64_bv), z3.Extract(23, 16, f64_bv), z3.Extract(31, 24, f64_bv), z3.Extract(39, 32, f64_bv), z3.Extract(47, 40, f64_bv), z3.Extract(55, 48, f64_bv), z3.Extract(63, 56, f64_bv) ]
def pack_u64(n: i64): if utils.is_all_real(n): return [ n & 0xFF, (n & 0xFF00) >> 8, (n & 0xFF0000) >> 16, (n & 0xFF000000) >> 24, (n & 0xFF00000000) >> 32, (n & 0xFF0000000000) >> 40, (n & 0xFF000000000000) >> 48, (n & 0xFF000000000000) >> 56 ] else: return [ z3.Extract(7, 0, n), z3.Extract(15, 8, n), z3.Extract(23, 16, n), z3.Extract(31, 24, n), z3.Extract(39, 32, n), z3.Extract(47, 40, n), z3.Extract(55, 48, n), z3.Extract(63, 56, n) ]
def f642i64(f: f64) -> i64: if utils.is_all_real(f): return struct.unpack('<q', struct.pack('<d', f))[0] return z3.fpToIEEEBV(f, z3.Float64())
def int2u8(i: int) -> u8: if utils.is_all_real(i): return i & 0xFF return z3.Extract(7, 0, i)
def f322i32(f: f32) -> i32: if utils.is_all_real(f): return struct.unpack('<i', struct.pack('<f', f))[0] return z3.fpToIEEEBV(f, z3.Float32())
def i642f64(i: i64) -> f64: if utils.is_all_real(i): i = int2i64(i) return struct.unpack('<i', struct.pack('<q', i))[0] return z3.fpToFP(i, z3.Float64())
def i8(r: list): if utils.is_all_real(r[0]): return ctypes.c_int8(r[0]).value else: return r[0]
def i322f32(i: i32) -> f32: if utils.is_all_real(i): i = int2i32(i) return struct.unpack('<f', struct.pack('<i', i))[0] return z3.fpToFP(i, z3.Float32())
def int2u64(i: int) -> u64: if utils.is_all_real(i): return i & 0xFFFFFFFFFFFFFFFF return z3.Extract(63, 0, i)
def int2u16(i: int) -> u16: if utils.is_all_real(i): return i & 0xFFFF return z3.Extract(15, 0, i)
def int2u32(i: int) -> u32: if utils.is_all_real(i): return i & 0xFFFFFFFF return z3.Extract(31, 0, i)
def pack_u8(n: u8): if utils.is_all_real(n): return [n & 0xFF] else: return [n]
def pack_u16(n: u16): if utils.is_all_real(n): return [n & 0xFF, (n & 0xFF00) >> 8] else: return [z3.Extract(7, 0, n), z3.Extract(15, 8, n)]