def clearFlag(my_state, name): """ Set flag to 0, untainted - helper for tests XXX for most tests, flags should inherit taint """ v = cfa.Value('reg', name, cfa.reg_len(name)) my_state[v] = [cfa.Value('g', 0x0, cfa.reg_len(name))]
def undefBitFlag(my_state, name): """ Set flag to undefined. XXX specify register len? """ v = cfa.Value('reg', name, cfa.reg_len(name)) my_state[v] = [cfa.Value('t', 0, cfa.reg_len(name), vtop=1)]
def test_movzx(analyzer, initialState): """ Test movzx edx, dl """ opcode = "\x0f\xb6\xd2" prgm, before, after, expected = go_analyze(analyzer, initialState, opcode) expected[cfa.Value("reg", "edx")][0].value &= 0xff expected[cfa.Value("reg", "edx")][0].vtop &= 0xff expected[cfa.Value("reg", "edx")][0].taint &= 0xff expected[cfa.Value("reg", "edx")][0].ttop &= 0xff assertEqualStates(after, expected, opcode, prgm=prgm)
def test_mov_reg_ebpm6(analyzer, initialState, register): """ mov reg,[ebp-0x6] """ regid, regname = register opcode = "\x8b" + chr(0x45 + (regid << 3)) + "\xfa" prgm, before, after, expected = go_analyze(analyzer, initialState, opcode) # build expected state expected[cfa.Value('reg', regname)] = \ dereference_data(before, before[cfa.Value('reg', 'ebp')][0] - 6) assertEqualStates(after, expected, opcode, prgm=prgm)
def test_pop(analyzer, initialState, register): """ Tests opcodes 0x58-0x5F """ regid, regname = register opcode = chr(0x58 + regid) prgm, before, after, expected = go_analyze(analyzer, initialState, opcode) # build expected state expected[cfa.Value('reg', 'esp')][0] += 4 expected[cfa.Value('reg', regname)] = \ before[cfa.Value( 's', before[cfa.Value('reg', 'esp')][0].value)] assertEqualStates(after, expected, opcode, prgm=prgm)
def test_movzx_byte_untaintptr(analyzer, initialState): """ Test movzx ebx, byte ptr [ebx]" """ opcode = "0FB609".decode("hex") prgm, before, after, expected = go_analyze(analyzer, initialState, opcode) v = before[cfa.Value("g", getReg(before, "ecx").value)][0] expected[cfa.Value("reg", "ecx")][0].value = v.value & 0xff expected[cfa.Value("reg", "ecx")][0].vtop = v.vtop & 0xff expected[cfa.Value("reg", "ecx")][0].taint = v.taint & 0xff expected[cfa.Value("reg", "ecx")][0].ttop = v.ttop & 0xff assertEqualStates(after, expected, opcode, prgm=prgm)
def getReg(my_node, name): v = cfa.Value('reg', name, cfa.reg_len(name)) # hardcoded first unrel try: return my_node.unrels["0"][v][0] except KeyError: return my_node.unrels[list(my_node.unrels.keys())[0]][v][0]
def setRegVal(my_state, name, value, vtop=0, taint=0, ttop=0): if name == 'esp': region = 's' else: region = 'g' regval = cfa.Value(region, value, cfa.reg_len(name), vtop=vtop, taint=taint, ttop=ttop) setReg(my_state, name, regval)
def test_movzx_byte(analyzer, initialState): """ Test mov eax, 0x100 ; movzx eax, byte ptr [eax]" """ opcode = ("B800010000"+"0FB600").decode("hex") prgm, before, after, expected = go_analyze(analyzer, initialState, opcode) v = before[cfa.Value("g", 0x100)][0] expected[cfa.Value("reg", "eax")][0].value = v.value & 0xff expected[cfa.Value("reg", "eax")][0].vtop = v.vtop & 0xff expected[cfa.Value("reg", "eax")][0].taint = v.taint & 0xff expected[cfa.Value("reg", "eax")][0].ttop = v.ttop & 0xff assertEqualStates(after, expected, opcode, prgm=prgm)
def test_mov_byte_taintptr(analyzer, initialState): """ Test mov al, byte ptr [eax]" """ opcode = "8A00".decode("hex") prgm, before, after, expected = go_analyze(analyzer, initialState, opcode) v = before[cfa.Value("g", 1)][0] expected[cfa.Value("reg", "eax")][0].value = v.value & 0xff expected[cfa.Value("reg", "eax")][0].vtop = v.vtop & 0xff expected[cfa.Value("reg", "eax")][0].taint = 0xff expected[cfa.Value("reg", "eax")][0].ttop = 0 assertEqualStates(after, expected, opcode, prgm=prgm)
def test_decode_5055_lastbyte(analyzer): filename = 'init-5055-read-lastbyte.ini' filepath = os.path.join(os.path.dirname(os.path.realpath(__file__)), filename) initialState = open(filepath, 'rb').read() binarystr = '\x50\x55' prgm = analyzer(initialState, binarystr=binarystr) state1 = prgm['0'] #: after push ebp state2 = getNextState(prgm, state1) expectedState2 = prepareExpectedState(state1) expectedState2[cfa.Value('reg', 'esp')][0].value -= 4 print state1[cfa.Value('reg', 'ebp')] zk = cfa.Value('s', expectedState2[cfa.Value('reg', 'esp')][0].value) print zk #print zk in expectedState2[ expectedState2[cfa.Value( 's', expectedState2[cfa.Value('reg', 'esp')][0].value)] = \ state1[cfa.Value('reg', 'ebp')] print "zk", zk print "e2", type(expectedState2[zk]), "e3" expectedState2.address += 1 # not checked, cosmetic for debugging only assert len(prgm.edges) == 1 assertEqualStates(state2, expectedState2, binarystr[1], prgm=prgm)
def taintFlag(my_state, name): """ Taint flag - helper for tests XXX for most tests, flags should inherit taint """ v = cfa.Value('reg', name) p = my_state[v][0] p.taint = 1 p.ttop = p.tbot = 0
def test_and_esp(analyzer, initialState): """ Test and %esp,0xfffffff0 """ opcode = "\x83\xe4\xf0" prgm, before, after, expected = go_analyze(analyzer, initialState, opcode) expected[cfa.Value("reg", "esp")][0].value &= 0xfffffff0 esp = expected[cfa.Value("reg", "esp")][0].value undefBitFlag(expected, "af") clearFlag(expected, "of") clearFlag(expected, "cf") calc_zf(expected, "esp") calc_sf(expected, "esp") calc_pf(expected, "esp") assertEqualStates(after, expected, opcode, prgm=prgm)
def test_mov_ebp_reg(analyzer, initialState, register): """ mov ebp,[reg] """ regid, regname = register opcode = "\x8b" + chr(0x28 + regid) prgm, before, after, expected = go_analyze(analyzer, initialState, opcode) # build expected state newvalue = dereference_data(before, before[cfa.Value('reg', regname)][0]) if newvalue is None: # dereferenced pointer contains BOTTOM assertNoNextState(prgm, before) return expected[cfa.Value('reg', 'ebp')] = newvalue expected = getNextState(prgm, before) assertEqualStates(after, expected, opcode, prgm=prgm)
def test_decode_5055_full(analyzer): """ Fully analyze input file containing 0x5055 """ filename = 'init-5055-read-all.ini' filepath = os.path.join(os.path.dirname(os.path.realpath(__file__)), filename) initialState = open(filepath, 'rb').read() binarystr = '\x50\x55' prgm = analyzer(initialState, binarystr=binarystr) stateInit = prgm['0'] #: after push eax state1 = getNextState(prgm, stateInit) #: after push ebp state2 = getNextState(prgm, state1) expectedState1 = prepareExpectedState(stateInit) expectedState1[cfa.Value('reg', 'esp')][0].value -= 4 expectedState1[cfa.Value( 's', expectedState1[cfa.Value('reg', 'esp')][0].value)] = \ stateInit[cfa.Value('reg', 'eax')] expectedState1.address += 1 # not checked, cosmetic for debugging only expectedState2 = prepareExpectedState(stateInit) expectedState2[cfa.Value('reg', 'esp')][0].value -= 8 concatv = [ expectedState1[cfa.Value('reg', 'eax')][0] & expectedState1[cfa.Value('reg', 'ebp')][0] ] expectedState2[cfa.Value('s', expectedState2[cfa.Value( 'reg', 'esp')][0].value)] = concatv expectedState2.address += 1 assert len(prgm.edges) == 2 assertEqualStates(state1, expectedState1, binarystr[0], prgm) assertEqualStates(state2, expectedState2, binarystr[1], prgm)
def test_sub(analyzer, initialState): # sub esp, 0x1234 opcode = binascii.unhexlify("81ec34120000") prgm, before, after, expected = go_analyze(analyzer, initialState, opcode) # build expected state regvalue = getReg(before, "esp").value newregvalue = regvalue - 0x1234 expected[cfa.Value('reg', 'esp')][0].value -= 0x1234 calc_af(expected, before, "esp", -1) calc_pf(expected, "esp") calc_sf(expected, "esp") calc_zf(expected, "esp") clearFlag(expected, 'of') # XXX compute properly clearFlag(expected, 'cf') # XXX compute properly # TODO check taint assertEqualStates(after, expected, opcode, prgm=prgm)
def test_inc(analyzer, initialState, register): """ Tests opcodes 0x40-0x47 == inc eax--edi """ regid, reg = register opcode = chr(0x40 + regid) prgm, before, after, expected = go_analyze(analyzer, initialState, opcode) expected[cfa.Value('reg', reg)][0] += 1 bef_value = getReg(before, reg).value calc_af(expected, before, reg, 1) calc_pf(expected, reg) calc_sf(expected, reg) calc_zf(expected, reg) clearFlag(expected, 'of') # XXX compute properly # XXX taint more bits? # XXX flags should be tainted - known bug assertEqualStates(after, expected, opcode, prgm=prgm)
def getReg(my_node, name): v = cfa.Value('reg', name, cfa.reg_len(name)) # hardcoded first unrel return my_node.unrels["0"][v][0]
def getMem(my_state, addr): v = cfa.Value('g', addr) return my_state[v]
def getReg(my_state, name): v = cfa.Value('reg', name, cfa.reg_len(name)) return my_state[v][0]
def setReg(my_state, name, regval): v = cfa.Value('reg', name, cfa.reg_len(name)) my_state[v] = [ regval ]