コード例 #1
0
ファイル: test_walkTree.py プロジェクト: isp1r0/vivisect
    def test_coverage(self):
        '''
        ((mem[piva_global(0xbfbfee08):1] | (mem[(arg0 + 72):4] & 0xffffff00)) + piva_global())
        '''
        ids = []
        piva1 = Var('piva_global', 4)
        ids.append(piva1._sym_id)
        arg = Const(0xbfbfee08, 4)
        ids.append(arg._sym_id)
        call = Call(piva1, 4, argsyms=[arg])
        ids.append(call._sym_id)
        con = Const(1, 4)
        ids.append(con._sym_id)
        mem1 = Mem(call, con)
        ids.append(mem1._sym_id)

        arg = Arg(0, 4)
        ids.append(arg._sym_id)
        addop = Const(72, 4)
        ids.append(addop._sym_id)
        add = o_add(arg, addop, 4)
        ids.append(add._sym_id)
        con = Const(4, 4)
        ids.append(con._sym_id)
        memac = Mem(add, con)
        ids.append(memac._sym_id)
        andop = Const(0xffffff00, 4)
        ids.append(andop._sym_id)
        mem2 = o_and(memac, andop, 4)
        ids.append(mem2._sym_id)
        memor = o_or(mem1, mem2, 4)
        ids.append(memor._sym_id)

        piva2 = Var('piva_global', 4)
        ids.append(piva2._sym_id)
        call2 = Call(piva2, 4, argsyms=[])
        ids.append(call2._sym_id)
        add = o_add(memor, call2, 4)
        ids.append(add._sym_id)

        traveled_ids = []

        def walkerTest(path, symobj, ctx):
            traveled_ids.append(symobj._sym_id)

        add.walkTree(walkerTest)
        self.assertEqual(traveled_ids, ids)
        self.assertEqual(
            '((mem[piva_global(0xbfbfee08):1] | (mem[(arg0 + 72):4] & 0xffffff00)) + piva_global())',
            str(add))
コード例 #2
0
    def test_constraints(self):
        fva = 0x080509e0
        vw = self.i386_vw
        ctx = v_s_analysis.getSymbolikAnalysisContext(vw, consolve=True)
        g = ctx.getSymbolikGraph(fva)
        constraints = {
            0x080509e0: {
                0x8050a42: ConstrainPath(0x080509ef, Const(0x08050a42, 4), Var("eflags_eq", width=4)),
                0x80509f1: ConstrainPath(0x080509ef, Const(0x080509f1, 4), cnot(Var("eflags_eq", width=4))),
            },

            0x8050a20: {
                0x8050a26: ConstrainPath(0x08050a24, Const(0x08050a26, 4), cnot(Var("eflags_eq", width=4))),
                0x8050a42: ConstrainPath(0x08050a24, Const(0x08050a42, 4), Var("eflags_eq", width=4)),
            },
            0x8050a26: {
                0x8050a20: ConstrainPath(0x08050a3e, Const(0x08050a20, 4), cnot(Var("eflags_eq", width=4))),
                0x8050a40: ConstrainPath(0x08050a3e, Const(0x08050a40, 4), cnot(cnot(Var("eflags_eq", width=4)))),
            },

            0x80509f1: {
                0x8050a44: ConstrainPath(0x08050a0c, Const(0x08050a44, 4), Var("eflags_eq", width=4)),
                0x8050a0e: ConstrainPath(0x08050a0c, Const(0x08050a0e, 4), cnot(Var("eflags_eq", width=4)))
            },
        }

        for eid, xfrom, xto, props in g.getEdges():
            if xfrom not in constraints:
                self.assertEqual(0, len(props))
                continue
            self.assertTrue('symbolik_constraints' in props)
            self.assertEqual(1, len(props['symbolik_constraints']))
            pcon = props['symbolik_constraints'][0]
            self.assertEqual(pcon, constraints[xfrom][xto])
コード例 #3
0
    def _cconv_test(self, caller, callee, argc, retn):
        # some setup and other fun things
        vw = self.i386_vw

        # Note: The function itself isn't important, we just need a real Symbolik emulator
        # instance that we can pass to setSymbolikArgs so that we can monkey with things
        # from there
        fva = 0x08051e10
        ctx = v_s_analysis.getSymbolikAnalysisContext(vw, consolve=True)
        argv = [Var('arg%d' % i, 4) for i in range(argc)]
        emu = ctx.getFuncEmu(fva)
        callee.setSymbolikArgs(emu, argv)
        caller.setSymbolikArgs(emu, argv)
        emu.setSymVariable('eax', retn)

        self.assertEqual(caller.getSymbolikReturn(emu), retn)
        self.assertEqual(caller.getSymbolikReturn(emu),
                         callee.getSymbolikReturn(emu))

        # if the callee cleans it up, the stack point is automatically assumed to be
        # delta'd by 20 bytes for bfastcall (argc == 7, 3 are registers, so 4 stack args
        # plus the return address makes 5 dwords to clean up for 20 bytes
        bytes_cleaned = (1 + callee.getNumStackArgs(emu, argc)) * 4
        self.assertEqual(
            callee.deallocateCallSpace(emu, argc).reduce(),
            Const(bytes_cleaned, 4))
        # if the caller cleans things up, the instructions after are going to do it
        # (since we're currently looking at things from a precall perspective), and so
        # the only thing that is going to get cleaned up is the return address
        self.assertEqual(
            caller.deallocateCallSpace(emu, argc).reduce(), Const(4, 4))
コード例 #4
0
    def test_symbolik_outputs(self):
        vw = self.i386_vw
        fva = 0x804cda0  # a deliberately simple function

        sctx = v_s_analysis.getSymbolikAnalysisContext(vw, consolve=True)
        out = [
            (Var("eax", 4), []),  # literally just a ret
            (Arg(0, 4), [
                WriteMemory(0x0804cdae, Const(0x08061404, 4),
                            Const(0x00000004, 4), Arg(0, 4))
            ]),
        ]
        for ret, effects in sctx.getSymbolikOutputs(fva):
            self.assertTrue(
                (ret, effects) in out,
                msg='(%s, %s) is not in the symbolik outputs' % (ret, effects))
コード例 #5
0
    def test_emulator(self):
        fva = 0x08051e10
        vw = self.i386_vw
        ctx = v_s_analysis.getSymbolikAnalysisContext(vw, consolve=True)

        retn = [
            '((mem[(arg0 + 24):4](edx,mem[(arg0 + 8):4],mem[0xbfbfefec:4],mem[0xbfbfeff0:4]) * 8) + mem[arg0:4])',
            '0x08049a80()',
        ]

        esps = [
            Const(0xbfbfeff4, 4),
            Const(0xbfbff004, 4),
        ]
        for emu, effects in ctx.walkSymbolikPaths(fva):
            self.assertTrue(str(emu.getFunctionReturn().reduce(foo=True)) in retn)
            esp = emu.getSymVariable('esp').reduce(foo=True)
            self.assertTrue(esp in esps)
            self.assertEqual(emu.getSymVariable('ecx'), Var('arg0', 4))
コード例 #6
0
    def test_writemem(self):
        # reduction
        msg = 'the quick brown dog'
        base = Arg(0, 4) * Const(8, 4) | Const(0x410000, 4)
        size = Const(1, 4)

        writes = []
        for c in msg:
            valu = Const(ord(c), 4)
            wm = WriteMemory(0x44, base, size, valu)
            base += Const(1, 4)
            writes.append(wm)
        answer = [
            '[ ((arg0 * 8) | 0x00410000) : 1 ] = 116',
            '[ (((arg0 * 8) | 0x00410000) + 1) : 1 ] = 104',
            '[ (((arg0 * 8) | 0x00410000) + 2) : 1 ] = 101',
            '[ (((arg0 * 8) | 0x00410000) + 3) : 1 ] = 32',
            '[ (((arg0 * 8) | 0x00410000) + 4) : 1 ] = 113',
            '[ (((arg0 * 8) | 0x00410000) + 5) : 1 ] = 117',
            '[ (((arg0 * 8) | 0x00410000) + 6) : 1 ] = 105',
            '[ (((arg0 * 8) | 0x00410000) + 7) : 1 ] = 99',
            '[ (((arg0 * 8) | 0x00410000) + 8) : 1 ] = 107',
            '[ (((arg0 * 8) | 0x00410000) + 9) : 1 ] = 32',
            '[ (((arg0 * 8) | 0x00410000) + 10) : 1 ] = 98',
            '[ (((arg0 * 8) | 0x00410000) + 11) : 1 ] = 114',
            '[ (((arg0 * 8) | 0x00410000) + 12) : 1 ] = 111',
            '[ (((arg0 * 8) | 0x00410000) + 13) : 1 ] = 119',
            '[ (((arg0 * 8) | 0x00410000) + 14) : 1 ] = 110',
            '[ (((arg0 * 8) | 0x00410000) + 15) : 1 ] = 32',
            '[ (((arg0 * 8) | 0x00410000) + 16) : 1 ] = 100',
            '[ (((arg0 * 8) | 0x00410000) + 17) : 1 ] = 111',
            '[ (((arg0 * 8) | 0x00410000) + 18) : 1 ] = 103',
        ]

        for idx, write in enumerate(writes):
            write.reduce()
            self.assertEqual(str(write), answer[idx])

        # walkTree
        addr = Mem(Call(Var('seek', 4), Const(4, 4)), Const(16, 4))
        size = Var('ecx', 4)
        valu = Arg(0, 4)
        wm = WriteMemory(0x44, addr, size, valu)

        answer = [
            Arg(0, 4),
            Var('seek', 4),
            Call(Var('seek', 4), Const(4, 4)),
            Const(16, 4),
            Mem(Call(Var('seek', 4), Const(4, 4)), Const(16, 4)),
            Var('ecx', 4)
        ]
        visited = []
        wm.walkTree(walker, ctx=visited)
        self.assertEqual(answer, visited)

        # application
        emu = MockEmulator(MockVw())
        addr = Call(Var('malloc', 4), Const(4, 4), argsyms=[Var('eax', 4)])
        size = (Const(2, 4)**Var('ebx', 4)) >> Const(2, 4)
        size *= Const(4, 4)
        valu = Mem(Const(0x41424344, 4), Const(8, 4))
        wm = WriteMemory(0x44, addr, size, valu)

        emu.setSymVariable('ebx', Const(6, 4))
        newwm = wm.applyEffect(emu)
        newwm.reduce(emu=emu)
        self.assertEqual(str(newwm),
                         '[ malloc(eax) : 64 ] = mem[0x41424344:8]')
コード例 #7
0
    def test_constrainpath(self):
        # reduction
        addrsym = Var('eax', 4) * Const(4, 4) + Const(0x4357, 4)
        consym = eq(Var('ebx', 4), Var('ebx', 4))
        cons = ConstrainPath(0x44, addrsym, consym)
        self.assertEqual(
            repr(cons),
            'ConstrainPath( 0x00000044, o_add(o_mul(Var("eax", width=4),Const(0x00000004,4),4),Const(0x00004357,4),4), eq(Var("ebx", width=4),Var("ebx", width=4)) )'
        )
        cons.reduce()
        self.assertEqual(
            repr(cons),
            'ConstrainPath( 0x00000044, o_add(o_mul(Var("eax", width=4),Const(0x00000004,4),4),Const(0x00004357,4),4), Const(0x00000001,4) )'
        )

        # walkTree
        addrsym = Var('eax', 4)
        consym = eq(eq(Var('ebx', 4), Var('edx', 4)), Const(1, 4))
        cons = ConstrainPath(0x44, addrsym, consym)
        visited = []

        cons.walkTree(walker, ctx=visited)
        answer = [
            Var('ebx', 4),
            Var('edx', 4),
            eq(Var('ebx', 4), Var('edx', 4)),
            Const(1, 4),
            eq(eq(Var('ebx', 4), Var('edx', 4)), Const(1, 4)),
        ]
        self.assertEqual(visited, answer)

        # application
        emu = MockEmulator(MockVw())
        addrsym = Var('ebx', 4)
        consym = eq(eq(Var('eax', 4), Var('ecx', 4)), Const(1, 4))
        cons = ConstrainPath(0x44, addrsym, consym)
        emu.setSymVariable('eax', Const(44, 4))
        emu.setSymVariable('ecx', Const(36, 4))
        newcons = cons.applyEffect(emu)
        newcons.reduce()
        self.assertEqual(newcons,
                         ConstrainPath(0x1994578, Var('ebx', 4), Const(0, 4)))
コード例 #8
0
    def test_callfunc(self):
        # reduction, with and without argsyms
        funcsym = Var('NeatoBurrito', 4)
        argsyms = [
            (Const(1, 4)**Var('edx', 4)) ^ Const(0x10, 4),
            (Var('eax', 4) ^ Var('eax', 4) | Const(0x10, 4)) << Const(0, 4),
            (Var('ebx', 4) & Var('ebx', 4)) | Const(0x40, 4) | Const(0x80, 4),
            Mem(Const(0x41414141, 4), Const(32, 4)),
        ]
        cf = CallFunction(0x44, funcsym, argsyms=argsyms)
        self.assertEqual(
            str(cf),
            'NeatoBurrito(((1 ** edx) ^ 16),(((eax ^ eax) | 16) << 0),(((ebx & ebx) | 64) | 128),mem[0x41414141:32])'
        )
        cf.reduce()
        self.assertEqual(str(cf),
                         'NeatoBurrito(17,16,(ebx | 192),mem[0x41414141:32])')

        # walkTree
        funcsym = Var('NeatoBurrito', 4)
        argsyms = [
            (Var('eax', 4) + Const(47, 4)) + (Var('ebx', 4) + Const(12, 4)),
            Var('foo', 4) & Var('foo', 4),
            Var('eax', 4) / Const(4, 4),
            Var('eax', 4) >> Const(2, 4),
            Const(4, 4) / Var('eax', 4),
        ]
        cf = CallFunction(0x44, funcsym, argsyms=argsyms)
        answer = [
            Var('NeatoBurrito', 4),
            Var('eax', 4),
            Const(47, 4),
            o_add(Var("eax", 4), Const(47, 4), 4),
            Var('ebx', 4),
            Const(12, 4),
            o_add(Var('ebx', 4), Const(12, 4), 4),
            (Var('eax', 4) + Const(47, 4)) + (Var('ebx', 4) + Const(12, 4)),
            Var('foo', 4),
            Var('foo', 4),
            o_and(Var('foo', 4), Var('foo', 4), 4),
            Var('eax', 4),
            Const(4, 4),
            o_div(Var('eax', 4), Const(4, 4), 4),
            Var('eax', 4),
            Const(2, 4),
            o_rshift(Var('eax', 4), Const(2, 4), 4),
            Const(4, 4),
            Var('eax', 4),
            o_div(Const(4, 4), Var('eax', 4), 4),
        ]
        visited = []
        cf.walkTree(walker, ctx=visited)
        self.assertEqual(visited, answer)

        # application, with argsyms
        emu = MockEmulator(MockVw())
        emu.setSymVariable('eax', Const(100, 4))
        newcf = cf.applyEffect(emu=emu)
        newcf.reduce()
        self.assertEqual(str(newcf), 'NeatoBurrito((ebx + 159),foo,25,25,0)')

        # application, without argsyms
        # by itself, emu.applyFunctionCall is just a NOP
        emu = MockEmulator(MockVw())
        funcsym = Var('ebx', 4)
        cf = CallFunction(0x44, funcsym)
        newcf = cf.applyEffect(emu=emu)
        newcf.reduce()
        self.assertEqual(newcf, cf)
コード例 #9
0
    def test_readmem(self):
        # idempotent
        addr = Var('eax', 4)
        size = Var('GetFileSize', 4)
        rm = ReadMemory(0x44, addr, size)
        self.assertEqual(str(rm), '[ eax : GetFileSize ]')
        rm.reduce()
        self.assertEqual(rm, ReadMemory(0x59, addr, size))

        # reduction
        addr = ((((Var('eax', 4) * Var('ebx', 4) + Const(9, 4)) - Const(4, 4)))
                << Const(3, 4)) * Const(2, 4)
        size = ((Const(0x73, 4) | Const(0x84, 4)) | Const(0xCC00, 4)) ^ Var(
            'ecx', 4)
        rm = ReadMemory(0x44, addr, size)
        rm.reduce()
        self.assertEqual(str(rm),
                         '[ (((eax * ebx) + 5) * 16) : (0x0000ccf7 ^ ecx) ]')
        self.assertEqual(str(rm.symaddr), '(((eax * ebx) + 5) * 16)')
        self.assertEqual(str(rm.symsize), '(0x0000ccf7 ^ ecx)')

        # walkTree
        addr = (Var('edx', 4) + Var('mm0', 4)) - Var('edx', 4)
        addr <<= (Var('foo', 4) + Var('foo', 4) -
                  (Var('foo', 4) * Const(2, 4)))
        size = (Var('bar', 4) - Const(0x19, 4)) - (Var('biz', 4) -
                                                   Const(0x20, 4))
        rm = ReadMemory(0x44, addr, size)
        visited = []
        rm.walkTree(walker, ctx=visited)
        answer = [
            'edx',
            'mm0',
            '(edx + mm0)',
            'edx',
            '((edx + mm0) - edx)',
            'foo',
            'foo',
            '(foo + foo)',
            'foo',
            '2',
            '(foo * 2)',
            '((foo + foo) - (foo * 2))',
            '(((edx + mm0) - edx) << ((foo + foo) - (foo * 2)))',
            'bar',
            '25',
            '(bar - 25)',
            'biz',
            '32',
            '(biz - 32)',
            '((bar - 25) - (biz - 32))',
        ]
        strd = map(str, visited)
        self.assertEqual(answer, strd)
        self.assertEqual(
            str(rm),
            '[ (((edx + mm0) - edx) << ((foo + foo) - (foo * 2))) : ((bar - 25) - (biz - 32)) ]'
        )
        rm.reduce()
        self.assertEqual(str(rm), '[ mm0 : ((bar - biz) + 7) ]')

        # application
        emu = MockEmulator(MockVw())
        emu.setSymVariable('mm0', Var('bar', 4))
        emu.setSymVariable('biz', Const(4, 4))
        new_rm = rm.applyEffect(emu)
        self.assertEqual(str(new_rm), '[ bar : ((bar - 4) + 7) ]')
        new_rm.reduce()
        self.assertEqual(str(new_rm), '[ bar : (bar + 3) ]')
コード例 #10
0
    def test_setvar(self):
        # reduction
        valu = Var('esp', 4) >> Var('ebp', 4)
        sv = SetVariable(0x44, 'vivisect', valu)
        self.assertEqual(str(sv), 'vivisect = (esp >> ebp)')

        valu = eq(Var('eax', 4), Var('eax', 4))
        sv = SetVariable(0x44, 'ultra', valu)
        self.assertEqual(str(sv), 'ultra = (eax == eax)')
        sv.reduce()
        self.assertEqual(str(sv), 'ultra = 1')

        # walkTree
        valu = ne(Const(0, 1), Const(0, 2))
        for i in range(8):
            valu |= Const(0x2 << i, 4)
        sv = SetVariable(0x44, 'vtrace', valu)
        visited = []
        sv.walkTree(walker, ctx=visited)
        answer = [
            Const(0, 1),
            Const(0, 2),
            ne(Const(0, 1), Const(0, 2)),
            Const(2, 4),
            o_or(ne(Const(0, 1), Const(0, 2)), Const(2, 4), 1),
            Const(4, 4),
            o_or(o_or(ne(Const(0, 1), Const(0, 2)), Const(2, 4), 1),
                 Const(4, 4), 1),
            Const(8, 4),
            o_or(
                o_or(o_or(ne(Const(0, 1), Const(0, 2)), Const(2, 4), 1),
                     Const(4, 4), 1), Const(8, 4), 1),
            Const(0x10, 4),
            o_or(
                o_or(
                    o_or(o_or(ne(Const(0, 1), Const(0, 2)), Const(2, 4), 1),
                         Const(4, 4), 1), Const(8, 4), 1), Const(0x10, 4), 1),
            Const(0x20, 4),
            o_or(
                o_or(
                    o_or(
                        o_or(
                            o_or(ne(Const(0, 1), Const(0, 2)), Const(2, 4), 1),
                            Const(4, 4), 1), Const(8, 4), 1), Const(0x10, 4),
                    1), Const(0x20, 4), 1),
            Const(0x40, 4),
            o_or(
                o_or(
                    o_or(
                        o_or(
                            o_or(
                                o_or(ne(Const(0, 1), Const(0, 2)), Const(2, 4),
                                     1), Const(4, 4), 1), Const(8, 4), 1),
                        Const(0x10, 4), 1), Const(0x20, 4), 1), Const(0x40, 4),
                1),
            Const(0x80, 4),
            o_or(
                o_or(
                    o_or(
                        o_or(
                            o_or(
                                o_or(
                                    o_or(ne(Const(0, 1), Const(0, 2)),
                                         Const(2, 4), 1), Const(4, 4), 1),
                                Const(8, 4), 1), Const(0x10, 4), 1),
                        Const(0x20, 4), 1), Const(0x40, 4), 1), Const(0x80, 4),
                1),
            Const(0x100, 4),
            o_or(
                o_or(
                    o_or(
                        o_or(
                            o_or(
                                o_or(
                                    o_or(
                                        o_or(ne(Const(0, 1), Const(0, 2)),
                                             Const(2, 4), 1), Const(4, 4), 1),
                                    Const(8, 4), 1), Const(0x10, 4), 1),
                            Const(0x20, 4), 1), Const(0x40, 4), 1),
                    Const(0x80, 4), 1), Const(0x100, 4), 1)
        ]
        self.assertEqual(visited, answer)
        sv.reduce()
        self.assertEqual(sv, SetVariable(0x9001, 'vtrace', Const(254, 4)))

        # application
        emu = MockEmulator(MockVw())
        sv.applyEffect(emu)
        self.assertEqual(emu.getSymVariable('vtrace'), Const(254, 4))