Пример #1
0
    def test_instruction_semantics_call(self):
        # call #0xdead
        raw = b'\xb0\x12\xad\xde'
        ip = 0xc0de

        ins, _ = decode_instruction(ip, raw)

        state = blank_state()
        state.cpu.registers['R0'] = BitVecVal(ip + len(raw),
                                              16)  # ip preincrement
        state.cpu.registers['R1'] = BitVecVal(0x1234, 16)

        new_states = state.cpu.step_call(state, ins)

        self.assertEqual(len(new_states), 1)

        new_state = new_states[0]

        lo = new_state.memory[0x1232]
        hi = new_state.memory[0x1233]
        pushed_val = Concat(hi, lo)

        self.assertEqual(intval(pushed_val), ip + len(raw))
        self.assertEqual(intval(new_state.cpu.registers['R1']), 0x1232)
        self.assertEqual(intval(new_state.cpu.registers['R0']), 0xdead)
Пример #2
0
    def test_instruction_semantics_jl(self):
        # jl #0x124e
        raw = b'\x0c\x38'
        ip = 0x1234

        ins, ins_len = decode_instruction(ip, raw)

        state = blank_state()
        state.cpu.registers['R0'] = BitVecVal(
            ip + ins_len, 16)  # ip is always preincremented

        expected_taken = 0x124e
        expected_not_taken = 0x1236

        new_states = state.cpu.step_jl(state, ins)

        self.assertEqual(len(new_states), 2)

        taken_states = [
            st for st in new_states
            if intval(st.cpu.registers['R0']) == expected_taken
        ]
        not_taken_states = [
            st for st in new_states
            if intval(st.cpu.registers['R0']) == expected_not_taken
        ]

        self.assertEqual(len(taken_states), 1)
        self.assertEqual(len(not_taken_states), 1)
Пример #3
0
    def test_jmp_decode(self):
        # should be jmp #0x446a
        raw = b'\x06\x3c'
        ip = 0x445c

        instruction, _ = decode_instruction(ip, raw + b'\xFF\xFF\xFF')
        self.assertIsInstance(instruction, JumpInstruction)
        self.assertEqual(instruction.raw, list(raw))
        self.assertEqual(instruction.opcode, Opcode.JMP)
        target = instruction.target
        target = simplify(target).as_long()
        self.assertEqual(target, 0x446a)
Пример #4
0
    def test_jz_decode(self):

        raw = b'\x06\x24' # should be jz #0x4438
        ip = 0x442a

        instruction, _ = decode_instruction(ip, raw + b'\xFF\xFF\xFF')
        self.assertIsInstance(instruction, JumpInstruction)
        self.assertEqual(instruction.raw, list(raw))
        self.assertEqual(instruction.opcode, Opcode.JZ)
        target = instruction.target
        target = simplify(target).as_long()
        self.assertEqual(target, 0x4438)
Пример #5
0
    def test_reti_decode(self):
        # should be "reti pc"
        raw = b'\x00\x13'
        ip = 0x4484

        instruction, _ = decode_instruction(ip, raw + b'\xFF\xFF\xFF')
        self.assertIsInstance(instruction, SingleOperandInstruction)
        self.assertEqual(instruction.raw, list(raw))
        self.assertEqual(instruction.opcode, Opcode.RETI)
        self.assertEqual(instruction.width, OperandWidth.WORD)
        self.assertEqual(instruction.addressing_mode, AddressingMode.DIRECT)
        self.assertEqual(instruction.register, Register.R0)
        self.assertEqual(instruction.operand, None)
Пример #6
0
    def test_call_decode(self):
        raw = b'\xb0\x12\x58\x45'
        ip = 0x4458

        instruction, _ = decode_instruction(ip, raw + b'\xFF\xFF\xFF')
        self.assertIsInstance(instruction, SingleOperandInstruction)
        self.assertEqual(instruction.raw, list(raw))
        self.assertEqual(instruction.opcode, Opcode.CALL)
        self.assertEqual(instruction.width, OperandWidth.WORD)
        self.assertEqual(instruction.addressing_mode, AddressingMode.IMMEDIATE)
        operand = instruction.operand
        operand = simplify(operand).as_long()
        self.assertEqual(operand, 0x4558)
Пример #7
0
    def test_push_constant_generator_decode(self):
        # should be "push 0x2"
        raw = b'\x23\x12'
        ip = 0x454c

        instruction, _ = decode_instruction(ip, raw + b'\xFF\xFF\xFF')
        self.assertIsInstance(instruction, SingleOperandInstruction)
        self.assertEqual(instruction.raw, list(raw))
        self.assertEqual(instruction.opcode, Opcode.PUSH)
        self.assertEqual(instruction.width, OperandWidth.WORD)
        self.assertEqual(instruction.addressing_mode, AddressingMode.CONSTANT2)
        self.assertEqual(instruction.register, Register.R3)
        self.assertEqual(instruction.operand, None)
Пример #8
0
    def test_push_immediate_decode(self):
        # should be "push 0xa"
        raw = b'\x30\x12\x0a\x00'
        ip = 0x4472

        instruction, _ = decode_instruction(ip, raw + b'\xFF\xFF\xFF')
        self.assertIsInstance(instruction, SingleOperandInstruction)
        self.assertEqual(instruction.raw, list(raw))
        self.assertEqual(instruction.opcode, Opcode.PUSH)
        self.assertEqual(instruction.width, OperandWidth.WORD)
        self.assertEqual(instruction.addressing_mode, AddressingMode.IMMEDIATE)
        operand = instruction.operand
        operand = simplify(operand).as_long()
        self.assertEqual(operand, 0xa)
Пример #9
0
    def test_mov_reg_reg_decode(self):
        raw = b'\x0b\x4f' # should be mov r15, r11
        ip = 0x455a

        instruction, _ = decode_instruction(ip, raw + b'\xFF\xFF\xFF')
        self.assertIsInstance(instruction, DoubleOperandInstruction)
        self.assertEqual(instruction.raw, list(raw))
        self.assertEqual(instruction.opcode, Opcode.MOV)
        self.assertEqual(instruction.width, OperandWidth.WORD)
        self.assertEqual(instruction.source_addressing_mode, AddressingMode.DIRECT)
        self.assertEqual(instruction.source_register, Register.R15)
        self.assertEqual(instruction.source_operand, None)
        self.assertEqual(instruction.dest_addressing_mode, AddressingMode.DIRECT)
        self.assertEqual(instruction.dest_register, Register.R11)
        self.assertEqual(instruction.dest_operand, None)
Пример #10
0
    def test_instruction_semantics_mov(self):
        # mov #0xdead, r6
        raw = b'\x36\x40\xad\xde'
        ip = 0x1234

        ins, _ = decode_instruction(ip, raw)

        state = blank_state()

        new_states = state.cpu.step_mov(state, ins)

        self.assertEqual(len(new_states), 1)

        new_state = new_states[0]
        self.assertEqual(intval(new_state.cpu.registers['R6']), 0xdead)
Пример #11
0
    def test_instruction_semantics_jmp(self):
        # should be jmp #0x446a
        raw = b'\x06\x3c'
        ip = 0x445c

        ins, _ = decode_instruction(ip, raw)

        state = blank_state()

        new_states = state.cpu.step_jmp(state, ins)

        self.assertEqual(len(new_states), 1)
        new_ip = new_states[0].cpu.registers['R0']
        new_ip = simplify(new_ip).as_long()
        self.assertEqual(new_ip, 0x446a)
Пример #12
0
    def test_instruction_semantics_sub(self):
        # sub.b #0x21, r15
        raw = b'\x7f\x80\x21\x00'
        ip = 0x1234

        ins, _ = decode_instruction(ip, raw)

        state = blank_state()
        state.cpu.registers['R15'] = BitVecVal(0x80, 16)

        new_states = state.cpu.step_sub(state,
                                        ins,
                                        enable_unsound_optimizations=False)

        for st in new_states:
            self.assertEqual(intval(st.cpu.registers['R15']), 0x80 - 0x21)
Пример #13
0
    def test_instruction_semantics_add(self):
        # add #0xc0de, r15
        raw = b'\x3f\x50\xde\xc0'
        ip = 0x1234

        ins, _ = decode_instruction(ip, raw)

        state = blank_state()
        state.cpu.registers['R15'] = BitVecVal(0x1111, 16)

        new_states = state.cpu.step_add(state,
                                        ins,
                                        enable_unsound_optimizations=False)

        for st in new_states:
            self.assertEqual(intval(st.cpu.registers['R15']), 0xc0de + 0x1111)
Пример #14
0
    def test_instruction_semantics_swpb(self):
        # swpb r6
        raw = b'\x86\x10'
        ip = 0x1234

        ins, _ = decode_instruction(ip, raw)

        state = blank_state()
        state.cpu.registers['R6'] = BitVecVal(0xdead, 16)

        new_states = state.cpu.step_swpb(state, ins)

        self.assertEqual(len(new_states), 1)

        new_state = new_states[0]
        self.assertEqual(intval(new_state.cpu.registers['R6']), 0xadde)
Пример #15
0
    def test_instruction_semantics_bis(self):
        # bis #0x0f0f, r6
        raw = b'\x36\xd0\x0f\x0f'
        ip = 0x1234

        ins, _ = decode_instruction(ip, raw)

        state = blank_state()
        state.cpu.registers['R6'] = BitVecVal(0xdead, 16)

        new_states = state.cpu.step_bis(state, ins)

        self.assertEqual(len(new_states), 1)
        new_state = new_states[0]

        self.assertEqual(intval(new_state.cpu.registers['R6']), 0xdfaf)
Пример #16
0
    def test_call_absolute_decode(self):
        # call &0x1234
        raw = b'\x92\x12\x34\x12'
        ip = 0xc0de

        instruction, _ = decode_instruction(ip, raw + b'\xFF\xFF\xFF')

        self.assertIsInstance(instruction, SingleOperandInstruction)
        self.assertEqual(instruction.raw, list(raw))
        self.assertEqual(instruction.opcode, Opcode.CALL)
        self.assertEqual(instruction.width, OperandWidth.WORD)
        self.assertEqual(instruction.addressing_mode, AddressingMode.ABSOLUTE)
        self.assertEqual(instruction.register, Register.R2)
        operand = instruction.operand
        operand = simplify(operand).as_long()
        self.assertEqual(operand, 0x1234)
Пример #17
0
    def test_mov_offset_reg_decode(self):
        raw = b'\x5f\x44\xfc\xff' # should be mov.b -0x4(r4), r15
        ip = 0x453a

        instruction, _ = decode_instruction(ip, raw + b'\xFF\xFF\xFF')
        self.assertIsInstance(instruction, DoubleOperandInstruction)
        self.assertEqual(instruction.raw, list(raw))
        self.assertEqual(instruction.opcode, Opcode.MOV)
        self.assertEqual(instruction.width, OperandWidth.BYTE)
        self.assertEqual(instruction.source_addressing_mode, AddressingMode.INDEXED)
        self.assertEqual(instruction.source_register, Register.R4)
        source_operand = instruction.source_operand
        source_operand = simplify(source_operand).as_signed_long()
        self.assertEqual(source_operand, -0x4)
        self.assertEqual(instruction.dest_addressing_mode, AddressingMode.DIRECT)
        self.assertEqual(instruction.dest_register, Register.R15)
        self.assertEqual(instruction.dest_operand, None)
Пример #18
0
    def test_instruction_semantics_sxt_negative(self):
        # sxt r6
        raw = b'\x86\x11'
        ip = 0x1234

        ins, _ = decode_instruction(ip, raw)

        state = blank_state()
        state.cpu.registers['R6'] = BitVecVal(0x008c, 16)

        new_states = state.cpu.step_sxt(state, ins)

        self.assertEqual(len(new_states), 4)

        for new_state in new_states:
            # TODO: Check flags
            self.assertEqual(intval(new_state.cpu.registers['R6']), 0xff8c)
Пример #19
0
    def test_call_symbolic_decode(self):
        # call 0x1234
        # (or call 0x1234(r0))
        raw = b'\x90\x12\x32\x12'
        ip = 0xc0de

        instruction, _ = decode_instruction(ip, raw + b'\xFF\xFF\xFF')

        self.assertIsInstance(instruction, SingleOperandInstruction)
        self.assertEqual(instruction.raw, list(raw))
        self.assertEqual(instruction.opcode, Opcode.CALL)
        self.assertEqual(instruction.width, OperandWidth.WORD)
        self.assertEqual(instruction.addressing_mode, AddressingMode.SYMBOLIC)
        self.assertEqual(instruction.register, Register.R0)
        # 0x1232 instead of 0x1234 because -2 from instruction width
        operand = instruction.operand
        operand = simplify(operand).as_long()
        self.assertEqual(operand, 0x1232)
Пример #20
0
    def test_mov_reg_offset_decode(self):

        raw = b'\x81\x4f\x04\x00' # should be mov r15, 0x4(r1)
        ip = 0x4512

        instruction, _ = decode_instruction(ip, raw + b'\xFF\xFF\xFF')
        self.assertIsInstance(instruction, DoubleOperandInstruction)
        self.assertEqual(instruction.raw, list(raw))
        self.assertEqual(instruction.opcode, Opcode.MOV)
        self.assertEqual(instruction.width, OperandWidth.WORD)
        self.assertEqual(instruction.source_addressing_mode, AddressingMode.DIRECT)
        self.assertEqual(instruction.source_register, Register.R15)
        self.assertEqual(instruction.source_operand, None)
        self.assertEqual(instruction.dest_addressing_mode, AddressingMode.INDEXED)
        self.assertEqual(instruction.dest_register, Register.R1)
        dest_operand = instruction.dest_operand
        dest_operand = simplify(dest_operand).as_signed_long()
        self.assertEqual(dest_operand, 0x4)
Пример #21
0
    def test_mov_symbolic_decode(self):
        # mov 0x2400, r1
        raw = b'\x11\x40\xfe\x23'
        ip = 0xc0de

        instruction, _ = decode_instruction(ip, raw + b'\xFF\xFF\xFF')
        self.assertIsInstance(instruction, DoubleOperandInstruction)
        self.assertEqual(instruction.raw, list(raw))
        self.assertEqual(instruction.opcode, Opcode.MOV)
        self.assertEqual(instruction.width, OperandWidth.WORD)
        self.assertEqual(instruction.source_addressing_mode, AddressingMode.SYMBOLIC)
        self.assertEqual(instruction.source_register, Register.R0)
        source_operand = instruction.source_operand
        source_operand = source_operand.as_long()
        self.assertEqual(source_operand, 0x2400 - 2)
        self.assertEqual(instruction.dest_addressing_mode, AddressingMode.DIRECT)
        self.assertEqual(instruction.dest_register, Register.R1)
        self.assertEqual(instruction.dest_operand, None)
Пример #22
0
    def test_mov_offset_offset_decode(self):
        raw = b'\x9f\x4f\x86\x45\x00\x24' # should be mov 0x4586(r15), 0x2400(r15)
        ip = 0x441c

        instruction, _ = decode_instruction(ip, raw + b'\xFF\xFF\xFF')
        self.assertIsInstance(instruction, DoubleOperandInstruction)
        self.assertEqual(instruction.raw, list(raw))
        self.assertEqual(instruction.opcode, Opcode.MOV)
        self.assertEqual(instruction.width, OperandWidth.WORD)
        self.assertEqual(instruction.source_addressing_mode, AddressingMode.INDEXED)
        self.assertEqual(instruction.source_register, Register.R15)
        source_operand = instruction.source_operand
        source_operand = simplify(source_operand).as_signed_long()
        self.assertEqual(source_operand, 0x4586)
        self.assertEqual(instruction.dest_addressing_mode, AddressingMode.INDEXED)
        self.assertEqual(instruction.dest_register, Register.R15)
        dest_operand = instruction.dest_operand
        dest_operand = simplify(dest_operand).as_signed_long()
        self.assertEqual(dest_operand, 0x2400)
Пример #23
0
    def test_instruction_semantics_bit_cflag_set(self):
        # bit #0xff00, r15
        raw = b'\x3f\xb0\x00\xff'
        ip = 0x1234

        ins, _ = decode_instruction(ip, raw)

        state = blank_state()
        state.cpu.registers['R15'] = BitVecVal(0x8000, 16)

        new_states = state.cpu.step_bit(state,
                                        ins,
                                        enable_unsound_optimizations=False)
        new_states = [st for st in new_states
                      if st.path.is_sat()]  # only sat states

        for st in new_states:
            flag_reg = intval(st.cpu.registers['R2'])
            c_flag = (flag_reg & st.cpu.registers.mask_C) != 0
            self.assertTrue(c_flag)
Пример #24
0
    def test_instruction_semantics_xor_zflag_set(self):
        # xor #0x21, r15
        raw = b'\x3f\xe0\x21\x00'
        ip = 0x1234

        ins, _ = decode_instruction(ip, raw)

        state = blank_state()
        state.cpu.registers['R15'] = BitVecVal(0x0021, 16)

        new_states = state.cpu.step_xor(state,
                                        ins,
                                        enable_unsound_optimizations=False)
        new_states = [st for st in new_states
                      if st.path.is_sat()]  # only sat states

        for st in new_states:
            flag_reg = intval(st.cpu.registers['R2'])
            z_flag = (flag_reg & st.cpu.registers.mask_Z) != 0
            self.assertTrue(z_flag)
Пример #25
0
    def test_instruction_semantics_add_vflag_set(self):
        # add #0x0123, r15
        raw = b'\x3f\x50\x23\x01'
        ip = 0x1234

        ins, _ = decode_instruction(ip, raw)

        state = blank_state()
        state.cpu.registers['R15'] = BitVecVal(0x7fff, 16)

        new_states = state.cpu.step_add(state,
                                        ins,
                                        enable_unsound_optimizations=False)
        new_states = [st for st in new_states
                      if st.path.is_sat()]  # only sat states

        for st in new_states:
            flag_reg = intval(st.cpu.registers['R2'])
            v_flag = (flag_reg & st.cpu.registers.mask_V) != 0
            self.assertTrue(v_flag)
Пример #26
0
    def test_instruction_semantics_cmp_vflag_unset(self):
        # cmp.b #0x21, r15
        raw = b'\x7f\x90\x21\x00'
        ip = 0x1234

        ins, _ = decode_instruction(ip, raw)

        state = blank_state()
        state.cpu.registers['R15'] = BitVecVal(0x30, 16)

        new_states = state.cpu.step_cmp(state,
                                        ins,
                                        enable_unsound_optimizations=False)
        new_states = [st for st in new_states
                      if st.path.is_sat()]  # only sat states

        for st in new_states:
            flag_reg = intval(st.cpu.registers['R2'])
            v_flag = (flag_reg & st.cpu.registers.mask_V) != 0
            self.assertFalse(v_flag)
Пример #27
0
    def test_instruction_semantics_push(self):
        # push #0xdead
        raw = b'\x30\x12\xad\xde'
        ip = 0x1234

        ins, _ = decode_instruction(ip, raw)

        state = blank_state()
        state.cpu.registers['R1'] = BitVecVal(0x1234, 16)

        new_states = state.cpu.step_push(state, ins)

        self.assertEqual(len(new_states), 1)

        new_state = new_states[0]
        lo = new_state.memory[0x1232]
        hi = new_state.memory[0x1233]
        pushed_val = Concat(hi, lo)

        self.assertEqual(intval(pushed_val), 0xdead)
        self.assertEqual(intval(new_state.cpu.registers['R1']), 0x1232)