Exemplo n.º 1
0
def test_trace(trace):
    Triton.setArchitecture(ARCH.X86)
    symbolization_init()

    astCtxt = Triton.getAstContext()

    for opcode in trace:
        instruction = Instruction()
        instruction.setOpcode(opcode)
        Triton.processing(instruction)
        print(instruction.getDisassembly())

        if instruction.isBranch():
            # Opaque Predicate AST
            op_ast = Triton.getPathPredicate()
            # Try another model
            model = Triton.getModel(astCtxt.lnot(op_ast))
            if model:
                print("not an opaque predicate")
            else:
                if instruction.isConditionTaken():
                    print("opaque predicate: always taken")
                else:
                    print("opaque predicate: never taken")

    print('----------------------------------')
    return
Exemplo n.º 2
0
def test_trace(trace):
    Triton.setArchitecture(ARCH.X86)
    symbolization_init()

    astCtxt = Triton.getAstContext()

    for opcode in trace:
        instruction = Instruction()
        instruction.setOpcode(opcode)
        Triton.processing(instruction)
        print instruction.getDisassembly()

        if instruction.isBranch():
            # Opaque Predicate AST
            op_ast = Triton.getPathConstraintsAst()
            # Try another model
            model = Triton.getModel(astCtxt.lnot(op_ast))
            if model:
                print "not an opaque predicate"
            else:
                if instruction.isConditionTaken():
                    print "opaque predicate: always taken"
                else:
                    print "opaque predicate: never taken"

    print '----------------------------------'
    return
Exemplo n.º 3
0
class TestInstruction(unittest.TestCase):

    """Testing the Instruction class."""

    def setUp(self):
        """Define and process the instruction to test."""
        self.Triton = TritonContext()
        self.Triton.setArchitecture(ARCH.X86_64)
        self.inst = Instruction()
        self.inst.setOpcode("\x48\x01\xd8")  # add rax, rbx
        self.inst.setAddress(0x400000)
        self.Triton.setConcreteRegisterValue(self.Triton.registers.rax, 0x1122334455667788)
        self.Triton.setConcreteRegisterValue(self.Triton.registers.rbx, 0x8877665544332211)
        self.Triton.processing(self.inst)

    def test_address(self):
        """Check instruction current and next address."""
        self.assertEqual(self.inst.getAddress(), 0x400000)
        self.assertEqual(self.inst.getNextAddress(), 0x400003)

    def test_memory(self):
        """Check memory access."""
        self.assertListEqual(self.inst.getLoadAccess(), [])
        self.assertListEqual(self.inst.getStoreAccess(), [])
        self.assertFalse(self.inst.isMemoryWrite())
        self.assertFalse(self.inst.isMemoryRead())

    def test_registers(self):
        """Check register access."""
        self.assertEqual(len(self.inst.getReadRegisters()), 2, "access RAX and RBX")
        self.assertEqual(len(self.inst.getWrittenRegisters()), 8, "write in RAX, RIP, AF, XF, OF, PF, SF and ZF")

    def test_taints(self):
        """Check taints attributes."""
        self.assertFalse(self.inst.isTainted())

    def test_prefix(self):
        """Check prefix data."""
        self.assertFalse(self.inst.isPrefixed())
        self.assertEqual(self.inst.getPrefix(), PREFIX.INVALID)

    def test_control_flow(self):
        """Check control flow flags."""
        self.assertFalse(self.inst.isControlFlow(), "It is not a jmp, ret or call")
        self.assertFalse(self.inst.isBranch(), "It is not a jmp")

    def test_condition(self):
        """Check condition flags."""
        self.assertFalse(self.inst.isConditionTaken())

    def test_opcode(self):
        """Check opcode informations."""
        self.assertEqual(self.inst.getOpcode(), "\x48\x01\xd8")
        self.assertEqual(self.inst.getType(), OPCODE.ADD)

    def test_thread(self):
        """Check threads information."""
        self.assertEqual(self.inst.getThreadId(), 0)

    def test_operand(self):
        """Check operand information."""
        self.assertEqual(len(self.inst.getOperands()), 2)
        self.assertEqual(self.inst.getOperands()[0].getName(), "rax")
        self.assertEqual(self.inst.getOperands()[1].getName(), "rbx")
        with self.assertRaises(Exception):
            self.inst.getOperands()[2]

    def test_symbolic(self):
        """Check symbolic information."""
        self.assertEqual(len(self.inst.getSymbolicExpressions()), 8)

    def test_size(self):
        """Check size information."""
        self.assertEqual(self.inst.getSize(), 3)

    def test_disassembly(self):
        """Check disassembly equivalent."""
        self.assertEqual(self.inst.getDisassembly(), "add rax, rbx")
Exemplo n.º 4
0
def run(pc, func_spec, seed):
    global addrs
    flag = 0
    while pc:
        inst = Instruction()

        # Setup opcode
        opcode = Triton.getConcreteMemoryAreaValue(pc, 16)

        inst.setOpcode(opcode)
        inst.setAddress(pc)
        arr = [elem.encode("hex") for elem in inst.getOpcode()]
        if arr[:4] == ['f3', '0f', '1e', 'fa']:
            pc += 4
            continue
        if arr[:3] == ['0f', '01', 'd0']:
            pc += 3
            continue
        if arr[0] == 'f4':
            print("abort")
            break

        if arr[0] == 'e8':
            offset = 0
            offset += int(arr[4], 16)
            offset = offset << 8
            offset += int(arr[3], 16)
            offset = offset << 8
            offset += int(arr[2], 16)
            offset = offset << 8
            offset += int(arr[1], 16)
            faddr = offset + pc + 5
            faddr = faddr & 0xffffffff

            try:
                fclose_addr = gbinary.get_function_address("fclose")
                if fclose_addr == faddr:
                    pc += 5
                    continue
            except:
                pass

            try:
                fgets_addr = gbinary.get_function_address("fgets")
                if fgets_addr == faddr:
                    adr = Triton.getConcreteRegisterValue(Triton.registers.rdi)
                    num = Triton.getConcreteRegisterValue(Triton.registers.rsi)
                    for i in range(num):
                        if adr + i not in seed:
                            seed[adr + i] = 0

                    pc += 5
                    continue
            except:
                pass

            try:
                fread_addr = gbinary.get_function_address("fread")
                if fread_addr == faddr:
                    adr = Triton.getConcreteRegisterValue(Triton.registers.rdi)
                    num = Triton.getConcreteRegisterValue(
                        Triton.registers.rsi
                    ) * Triton.getConcreteRegisterValue(Triton.registers.rdx)
                    for i in range(num):
                        if adr + i not in seed:
                            print("new fread")
                            seed[adr + i] = 0

                    pc += 5
                    continue
            except:
                pass

            try:
                printf_addr = gbinary.get_function_address("printf")
                if printf_addr == faddr:
                    pc += 5
                    continue
            except:
                pass

            try:
                fprintf_addr = gbinary.get_function_address("fprintf")
                if fprintf_addr == faddr:
                    pc += 5
                    continue
            except:
                pass

        if arr[0] == 'e8' and flag == 0:
            offset = 0
            offset += int(arr[4], 16)
            offset = offset << 8
            offset += int(arr[3], 16)
            offset = offset << 8
            offset += int(arr[2], 16)
            offset = offset << 8
            offset += int(arr[1], 16)
            addr = offset + pc + 5
            addr = addr & 0xffffffff

            if addr in func_spec:
                last_op = addr
                if func_spec[addr][0] in ["==", ">=", "<="]:
                    Triton.setConcreteRegisterValue(Triton.registers.rax,
                                                    func_spec[addr][1])
                if func_spec[addr][0] == '>':
                    Triton.setConcreteRegisterValue(Triton.registers.rax,
                                                    func_spec[addr][1] + 1)
                if func_spec[addr][0] == '!=':
                    Triton.setConcreteRegisterValue(Triton.registers.rax,
                                                    func_spec[addr][1] + 1)
                if func_spec[addr][0] == '<':
                    Triton.setConcreteRegisterValue(Triton.registers.rax,
                                                    func_spec[addr][1] - 1)
                flag = 1
                pc += 5
                continue
        Triton.processing(inst)

        gflag = 0
        for addr in func_spec:
            if addr not in addrs:
                gflag = 1
                break
        if gflag == 0:
            break

        if flag == 2:
            addrs[last_op] = pc
            flag = 0
        if flag == 1:
            if inst.isBranch():
                flag = 2

        # hookingHandler(Triton)
        pc = Triton.getConcreteRegisterValue(Triton.registers.rip)
Exemplo n.º 5
0
class TestInstruction(unittest.TestCase):

    """Testing the Instruction class."""

    def setUp(self):
        """Define and process the instruction to test."""
        self.Triton = TritonContext()
        self.Triton.setArchitecture(ARCH.X86_64)
        self.inst = Instruction()
        self.inst.setOpcode(b"\x48\x01\xd8")  # add rax, rbx
        self.inst.setAddress(0x400000)
        self.Triton.setConcreteRegisterValue(self.Triton.registers.rax, 0x1122334455667788)
        self.Triton.setConcreteRegisterValue(self.Triton.registers.rbx, 0x8877665544332211)
        self.Triton.processing(self.inst)

    def test_address(self):
        """Check instruction current and next address."""
        self.assertEqual(self.inst.getAddress(), 0x400000)
        self.assertEqual(self.inst.getNextAddress(), 0x400003)

        inst = Instruction()
        inst.setAddress(-1)
        self.assertEqual(inst.getAddress(), 0xffffffffffffffff)

        inst.setAddress(-2)
        self.assertEqual(inst.getAddress(), 0xfffffffffffffffe)

        inst.setAddress(-3)
        self.assertEqual(inst.getAddress(), 0xfffffffffffffffd)

    def test_memory(self):
        """Check memory access."""
        self.assertListEqual(self.inst.getLoadAccess(), [])
        self.assertListEqual(self.inst.getStoreAccess(), [])
        self.assertFalse(self.inst.isMemoryWrite())
        self.assertFalse(self.inst.isMemoryRead())

    def test_registers(self):
        """Check register access."""
        self.assertEqual(len(self.inst.getReadRegisters()), 2, "access RAX and RBX")
        self.assertEqual(len(self.inst.getWrittenRegisters()), 8, "write in RAX, RIP, AF, XF, OF, PF, SF and ZF")

    def test_taints(self):
        """Check taints attributes."""
        self.assertFalse(self.inst.isTainted())

    def test_prefix(self):
        """Check prefix data."""
        self.assertFalse(self.inst.isPrefixed())
        self.assertEqual(self.inst.getPrefix(), PREFIX.X86.INVALID)

    def test_control_flow(self):
        """Check control flow flags."""
        self.assertFalse(self.inst.isControlFlow(), "It is not a jmp, ret or call")
        self.assertFalse(self.inst.isBranch(), "It is not a jmp")

    def test_condition(self):
        """Check condition flags."""
        self.assertFalse(self.inst.isConditionTaken())

    def test_opcode(self):
        """Check opcode informations."""
        self.assertEqual(self.inst.getOpcode(), b"\x48\x01\xd8")
        self.assertEqual(self.inst.getType(), OPCODE.X86.ADD)

    def test_thread(self):
        """Check threads information."""
        self.assertEqual(self.inst.getThreadId(), 0)

    def test_operand(self):
        """Check operand information."""
        self.assertEqual(len(self.inst.getOperands()), 2)
        self.assertEqual(self.inst.getOperands()[0].getName(), "rax")
        self.assertEqual(self.inst.getOperands()[1].getName(), "rbx")
        with self.assertRaises(Exception):
            self.inst.getOperands()[2]

    def test_symbolic(self):
        """Check symbolic information."""
        self.assertEqual(len(self.inst.getSymbolicExpressions()), 8)

    def test_size(self):
        """Check size information."""
        self.assertEqual(self.inst.getSize(), 3)

    def test_disassembly(self):
        """Check disassembly equivalent."""
        self.assertEqual(self.inst.getDisassembly(), "add rax, rbx")
Exemplo n.º 6
0
def emulate(pc):
    count = 0
    while pc:
        # Fetch opcode
        opcode = Triton.getConcreteMemoryAreaValue(pc, 16)

        # Create the Triton instruction
        instruction = Instruction()
        instruction.setOpcode(opcode)
        instruction.setAddress(pc)

        # Process
        Triton.processing(instruction)
        count += 1

        # Print instruction
        # print("pc = {:#x}, rax = {:#x}".format(pc, Triton.getConcreteRegisterValue(Triton.registers.rax)))
        # debug("{} (size={})".format(instruction, instruction.getSize()))

        # for expr in instruction.getSymbolicExpressions():
        #     print('\t', expr)

        if instruction.getType() == OPCODE.X86.HLT:
            break

        # Simulate routines
        flag_exit = hookingHandler(instruction)
        if flag_exit:
            break

        # Update branch constraint
        reg_zf = Triton.getRegisterAst(Triton.getRegister(REG.X86.ZF))
        reg_sf = Triton.getRegisterAst(Triton.getRegister(REG.X86.SF))
        reg_of = Triton.getRegisterAst(Triton.getRegister(REG.X86.OF))
        reg_cf = Triton.getRegisterAst(Triton.getRegister(REG.X86.CF))
        ast = Triton.getAstContext()

        # Next
        if instruction.isBranch(
        ) and not instruction.getType() == OPCODE.X86.JMP:
            # メインのバイナリのトレースになるまで読み飛ばし
            while True:
                event = Trace.get_next_branch()
                # debug(event)
                # if Trace.get_relative_addr_and_image(event['inst_addr'])[0] == pc:
                #     break
                if event['inst_addr'].startswith('0x5') and int(
                        event['inst_addr'], 16) & 0xfff == pc & 0xfff:
                    break
            # debug(event)

            # 分岐条件を収集
            def ja_succ(cf, zf):
                # CF=0 and ZF=0
                return ast.land([cf == 0, zf == 0])

            def jae_succ(cf):
                return cf == 0

            def jb_succ(cf):
                return cf == 1

            def jbe_succ(cf, zf):
                # CF=1 or ZF=1
                return ast.lor([cf == 1, zf == 1])

            def jg_succ(zf, sf, of):
                # ZF=0 and SF=OF
                return ast.land([zf == 0, sf == of])

            def jge_succ(sf, of):
                # SF=OF
                return sf == of

            def jl_succ(sf, of):
                # SF ≠ OF
                return sf != of

            def jle_succ(zf, sf, of):
                # ZF=1 or SF ≠ OF
                return ast.lor([zf == 1, sf != of])

            def je_succ(zf):
                return zf == 1

            def jne_succ(zf):
                return zf == 0

            def js_succ(sf):
                return sf == 1

            def jns_succ(sf):
                return sf == 0

            def selecter(instruction, event, succ_opcode, succ, fail_opcode,
                         fail):
                if instruction.getType() == succ_opcode:
                    if event['branch_taken']:
                        return succ
                    else:
                        return fail
                if instruction.getType() == fail_opcode:
                    if event['branch_taken']:
                        return fail
                    else:
                        return succ

            if False:
                pass
            elif instruction.getType() in [OPCODE.X86.JA, OPCODE.X86.JBE]:
                conditional_branch_constraints.append(
                    selecter(instruction, event, OPCODE.X86.JA, ja_succ,
                             OPCODE.X86.JBE, jbe_succ)(cf=reg_cf, zf=reg_zf))
            elif instruction.getType() in [OPCODE.X86.JB, OPCODE.X86.JAE]:
                conditional_branch_constraints.append(
                    selecter(instruction, event, OPCODE.X86.JB, jb_succ,
                             OPCODE.X86.JAE, jae_succ)(cf=reg_cf, zf=reg_zf))
            elif instruction.getType() in [OPCODE.X86.JL, OPCODE.X86.JGE]:
                conditional_branch_constraints.append(
                    selecter(instruction, event, OPCODE.X86.JL, jl_succ,
                             OPCODE.X86.JGE, jge_succ)(sf=reg_sf, of=reg_of))
            elif instruction.getType() in [OPCODE.X86.JG, OPCODE.X86.JLE]:
                conditional_branch_constraints.append(
                    selecter(instruction, event, OPCODE.X86.JG, jg_succ,
                             OPCODE.X86.JLE, jle_succ)(zf=reg_zf,
                                                       sf=reg_sf,
                                                       of=reg_of))
            elif instruction.getType() in [OPCODE.X86.JE, OPCODE.X86.JNE]:
                conditional_branch_constraints.append(
                    selecter(instruction, event, OPCODE.X86.JE, je_succ,
                             OPCODE.X86.JNE, jne_succ)(zf=reg_zf))
            elif instruction.getType() in [OPCODE.X86.JS, OPCODE.X86.JNS]:
                conditional_branch_constraints.append(
                    selecter(instruction, event, OPCODE.X86.JS, js_succ,
                             OPCODE.X86.JNS, jns_succ)(sf=reg_sf))
            else:
                raise Exception(
                    "Unhandled jcc instruction: {}".format(instruction))

            # 分岐結果をプログラムカウンタに反映
            if event['branch_taken']:
                pc = int(instruction.getDisassembly().split(' ')[-1], 16)
                continue
            else:
                pc = pc + instruction.getSize()
        else:
            pc = Triton.getConcreteRegisterValue(Triton.registers.rip)

    debug('Number of instruction executed: %d' % (count))
    return