Esempio n. 1
0
    def test_pe(self):

        try:

            from pyopenreil.utils import bin_PE

            self._run_test(lambda abi: abi.cdecl, 
                ARCH_X86, bin_PE.Reader(self.file_path(self.PE_NAME)), self.PE_ADDR)
        
        except ImportError, why: print '[!]', str(why)
Esempio n. 2
0
    def test(self):

        # test input data for RC4 encryption
        test_key = 'somekey'
        test_val = 'bar'

        # load PE image of test program
        reader = bin_PE.Reader(self.BIN_PATH)
        tr = CodeStorageTranslator(reader)

        def code_optimization(addr):

            # construct dataflow graph for given function
            dfg = DFGraphBuilder(tr).traverse(addr)

            # run some basic optimizations
            dfg.eliminate_dead_code()
            dfg.constant_folding()
            dfg.eliminate_subexpressions()

            # store resulting instructions
            dfg.store(tr.storage)

        code_optimization(self.RC4_SET_KEY)
        code_optimization(self.RC4_CRYPT)

        # create CPU and ABI
        cpu = Cpu(self.ARCH)
        abi = Abi(cpu, tr)

        # allocate buffers for arguments of emulated functions
        ctx = abi.buff(256 + 4 * 2)
        val = abi.buff(test_val)

        # emulate rc4_set_key() function call
        abi.cdecl(self.RC4_SET_KEY, ctx, test_key, len(test_key))

        # emulate rc4_crypt() function call
        abi.cdecl(self.RC4_CRYPT, ctx, val, len(test_val))

        # read results of RC4 encryption
        val = abi.read(val, len(test_val))
        print 'Encrypted value:', repr(val)

        # check for correct result
        assert val == '\x38\x88\xBC'
Esempio n. 3
0
    def test(self):

        # load PE image of test program
        reader = bin_PE.Reader(self.BIN_PATH)
        tr = CodeStorageTranslator(reader)

        # construct dataflow graph for given function
        dfg = DFGraphBuilder(tr).traverse(self.PROC_ADDR)
        insn_before = tr.size()

        # run some basic optimizations
        dfg.eliminate_dead_code()
        dfg.constant_folding()
        dfg.eliminate_subexpressions()

        dfg.store(tr.storage)
        insn_after = tr.size()

        print tr.storage

        print '%d instructions before optimization and %d after\n' % \
              (insn_before, insn_after)

        # create CPU and ABI
        cpu = Cpu(self.ARCH)
        abi = Abi(cpu, tr)

        testval = 11

        # int fib(int n);
        ret = abi.cdecl(self.PROC_ADDR, testval)
        cpu.dump()

        print '%d number in Fibonacci sequence is %d' % (testval + 1, ret)

        assert ret == 144
Esempio n. 4
0
def keygen(kao_binary_path, kao_installation_ID):
    '''
        Assembly code of serial number check from Kao's Toy Project binary,
        X and Y contains serial number that was entered by user.

        .text:004010EC check_serial    proc near
        .text:004010EC
        .text:004010EC ciphered        = byte ptr -21h
        .text:004010EC X               = dword ptr  8
        .text:004010EC Y               = dword ptr  0Ch
        .text:004010EC
        .text:004010EC                 push    ebp
        .text:004010ED                 mov     ebp, esp
        .text:004010EF                 add     esp, 0FFFFFFDCh
        .text:004010F2                 mov     ecx, 20h
        .text:004010F7                 mov     esi, offset installation_ID
        .text:004010FC                 lea     edi, [ebp+text_ciphered]
        .text:004010FF                 mov     edx, [ebp+X]
        .text:00401102                 mov     ebx, [ebp+Y]
        .text:00401105
        .text:00401105 loc_401105:
        .text:00401105                 lodsb
        .text:00401106                 sub     al, bl
        .text:00401108                 xor     al, dl
        .text:0040110A                 stosb
        .text:0040110B                 rol     edx, 1
        .text:0040110D                 rol     ebx, 1
        .text:0040110F                 loop    loc_401105
        .text:00401111                 mov     byte ptr [edi], 0
        .text:00401114                 push    offset text_valid ; "0how4zdy81jpe5xfu92kar6cgiq3lst7"
        .text:00401119                 lea     eax, [ebp+text_ciphered]
        .text:0040111C                 push    eax
        .text:0040111D                 call    lstrcmpA
        .text:00401122                 leave
        .text:00401123                 retn    8
        .text:00401123 check_serial    endp
    '''

    # address of the check_serial() function
    check_serial = 0x004010EC

    # address of the strcmp() call inside check_serial()
    stop_at = 0x0040111D

    # address of the global buffer with installation ID
    installation_ID = 0x004093A8

    # load Kao's PE binary
    from pyopenreil.utils import bin_PE
    tr = CodeStorageTranslator(bin_PE.Reader(kao_binary_path))

    # Construct DFG, run all available code optimizations
    # and update storage with new function code.
    dfg = DFGraphBuilder(tr).traverse(check_serial)
    dfg.optimize_all(tr.storage)

    print tr.get_func(check_serial)

    # create CPU and ABI
    cpu = Cpu(ARCH_X86)
    abi = VM.Abi(cpu, tr, no_reset=True)

    # hardcoded ciphered text constant from Kao's binary
    out_data = '0how4zdy81jpe5xfu92kar6cgiq3lst7'
    in_data = ''

    try:

        # convert installation ID into the binary form
        for s in kao_installation_ID.split('-'):

            in_data += struct.pack('L', int(s[:8], 16))
            in_data += struct.pack('L', int(s[8:], 16))

        assert len(in_data) == 32

    except:

        raise Exception('Invalid instllation ID string')

    # copy installation ID into the emulator's memory
    for i in range(32):

        cpu.mem.store(installation_ID + i, U8,
                      cpu.mem._Val(U8, 0, ord(in_data[i])))

    ret, ebp = 0x41414141, 0x42424242

    # create stack with symbolic arguments for check_serial()
    stack = abi.pushargs(( Val(exp = SymVal('ARG_0', U32)), \
                           Val(exp = SymVal('ARG_1', U32)) ))

    # dummy return address
    stack.push(Val(ret))

    # initialize emulator's registers
    cpu.reg('ebp', Val(ebp))
    cpu.reg('esp', Val(stack.top))

    # run until stop
    try:
        cpu.run(tr, check_serial, stop_at=[stop_at])
    except VM.CpuStop as e:

        print 'STOP at', hex(cpu.reg('eip').get_val())

        # get Z3 expressions list for current CPU state
        state = cpu.to_z3()
        cpu.dump(show_all=True)

        # read symbolic expressions for contents of the output buffer
        addr = cpu.reg('eax').val
        data = cpu.mem.read(addr.val, 32)

        for i in range(32):

            print '*' + hex(addr.val + i), '=', data[i].exp

        # create SMT solver
        solver = z3.Solver()

        for i in range(32):

            # add constraint for each output byte
            solver.add(
                data[i].to_z3(state, U8) == z3.BitVecVal(ord(out_data[i]), 8))

        # solve constraints
        solver.check()

        # get solution
        model = solver.model()

        # get and print serial number
        serial = map(lambda d: model[d].as_long(), model.decls())
        serial[1] = serial[0] ^ serial[1]

        print '\nSerial number: %s\n' % '-'.join(
            ['%.8X' % serial[0], '%.8X' % serial[1]])

        return serial

    assert False
Esempio n. 5
0
from pyopenreil.REIL import *
from pyopenreil.symbolic import *
from pyopenreil.VM import *

from pyopenreil.utils import bin_PE

# VA's of required functions and variables
check_serial = 0x004010EC
installation_ID = 0x004093A8

# create translator instance
tr = CodeStorageTranslator(bin_PE.Reader('toyproject.exe'))

# construct data flow graph of check_serial() function
dfg = DFGraphBuilder(tr).traverse(check_serial)

# Run all available code optimizations and update
# storage with new function code.
dfg.optimize_all(tr.storage)

# print generated IR code
print tr.get_func(check_serial)