def setUpClass(cls): super(PETests, cls).setUpClass() cls.psexec_fn = helpers.getTestPath('windows', 'i386', 'PsExec.exe') cls.vw_psexec = helpers.getTestWorkspace('windows', 'i386', 'PsExec.exe') cls.vw_sphinx = helpers.getTestWorkspace('windows', 'i386', 'sphinx_livepretend.exe') cls.vw_mimi = vivisect.VivWorkspace() mimi_fn = helpers.getTestPath('windows', 'i386', 'mimikatz.exe_') cls.vw_mimi.loadFromFile(mimi_fn)
def test_files(self): results = [] for name, test_data, path in self.data: logger.warning("======== %r ========", name) start = time.time() fn = helpers.getTestPath(*path) vw = viv_cli.VivCli() vw.loadFromFile(fn) do_analyze(vw) logger.debug("testing %r (%r)...", name, fn) retval = self.do_file(vw, test_data, name) results.append(retval) durn = time.time() - start logger.warning( f'============= {name} took {durn} seconds ===============') self.do_check_elfplt(vw) failed = 0 for fidx, tres in enumerate(results): for testname, testdata in tres.items(): if testdata != (0, 0): failed += testdata[0] + testdata[1] fname = self.data[fidx][0] failed_old, failed_new = testdata logger.error('%s: %s: missing: %r new: %r (%r)', fname, testname, failed_old, failed_new, fname) self.assertEqual(failed, 0, msg="ELF Tests Failed (see error log)")
def test_export_by_ordinal_base_45(self): file_path = helpers.getTestPath('windows', 'i386', 'export_by_ordinal_base_45.dll') pe = PE.peFromFileName(file_path) export_list = pe.getExports() self.assertEquals(len(export_list), 2, "expecting 2 exported functions") self.assertEquals(export_list[0][1], 45, "exported function with ordinal 45 not found") self.assertEquals(export_list[1][1], 55, "exported function with ordinal 55 not found")
def setUpClass(cls): super(PETests, cls).setUpClass() cls.psexec_fn = helpers.getTestPath('windows', 'i386', 'PsExec.exe') cls.vw_psexec = helpers.getTestWorkspace('windows', 'i386', 'PsExec.exe') cls.vw_sphinx = helpers.getTestWorkspace('windows', 'i386', 'sphinx_livepretend.exe')
def test_pe_pe32p(self): ''' test that we use the right check for constructing the optional header and that the data directories are right ''' file_path = helpers.getTestPath( 'windows', 'amd64', 'a7712b7c45ae081a1576a387308077f808c666449d1ea9ba680ec410569d476f.file' ) pe = PE.peFromFileName(file_path) self.assertTrue(pe.pe32p) self.eq(pe.psize, 8) self.eq(pe.IMAGE_NT_HEADERS.OptionalHeader.SizeOfStackReserve, 0x100000) self.eq(pe.IMAGE_NT_HEADERS.OptionalHeader.SizeOfStackCommit, 0x1000) self.eq(pe.IMAGE_NT_HEADERS.OptionalHeader.SizeOfHeapReserve, 0x100000) self.eq(pe.IMAGE_NT_HEADERS.OptionalHeader.SizeOfHeapCommit, 0x1000) self.eq(pe.IMAGE_NT_HEADERS.OptionalHeader.LoaderFlags, 0) self.eq(pe.IMAGE_NT_HEADERS.OptionalHeader.NumberOfRvaAndSizes, 0x10) ddir = pe.getDataDirectory(PE.IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR) self.eq(ddir.VirtualAddress, 0x2008) self.eq(ddir.Size, 0x48) ddir = pe.getDataDirectory(PE.IMAGE_DIRECTORY_ENTRY_RESOURCE) self.eq(ddir.VirtualAddress, 0x9a2000) self.eq(ddir.Size, 0x3c78)
def test_minimal(self): for path in (('linux','amd64','static64.llvm.elf'), ('linux','i386','static32.llvm.elf')): logger.warn("======== %r ========", path) fn = helpers.getTestPath(*path) e = Elf.Elf(file(fn)) vw = viv_cli.VivCli() vw.loadFromFile(fn)
def test_export_by_name(self): file_path = helpers.getTestPath('windows', 'i386', 'export_by_name.dll') pe = PE.peFromFileName(file_path) export_list = pe.getExports() self.assertEquals(len(export_list), 2, "expecting 2 exported functions") self.assertEquals(export_list[0][1], 0, "exported function with ordinal 0 not found") self.assertEquals(export_list[0][2], "Func1", "exported function with name 'Func1' not found") self.assertEquals(export_list[1][1], 1, "exported function with ordinal 1 not found") self.assertEquals(export_list[1][2], "Func2", "exported function with name 'Func2' not found")
def DISABLEtest_minimal(self): ''' Until we've got soe decent tests for this, all this does is prolong the test time ''' for path in (('linux','amd64','static64.llvm.elf'), ('linux','i386','static32.llvm.elf')): logger.warning("======== %r ========", path) fn = helpers.getTestPath(*path) e = Elf.Elf(open(fn, 'rb')) vw = viv_cli.VivCli() vw.loadFromFile(fn)
def loadGoBin(*path): ''' We don't need full analysis on the go binaries to complete the tests ''' vw = vivisect.VivWorkspace() path = helpers.getTestPath(*path) vw.loadFromFile(path) for ep in vw.getEntryPoints(): vw.makeFunction(ep) return vw
def test_hiaddr_imports(self): # Test if imports located at a high relative address are discovered. file_path = helpers.getTestPath('windows', 'i386', 'section_has_hi_virtualaddr.exe') pe = PE.peFromFileName(file_path) import_list = pe.getImports() self.assertEqual(len(import_list), 36, "expecting 36 imported functions") self.assertEqual( import_list[0][1], "advapi32.dll", "imported function with name 'advapi32.dll' not found")
def test_blob(self): fn = helpers.getTestPath(*path) vw = viv_cli.VivCli() vw.config.viv.parsers.blob.arch = 'arm' vw.config.viv.parsers.blob.baseaddr = 0x200000 vw.loadFromFile(fn) vw.makeFunction(0x200001) vw.makeFunction(0x200008) self.assertEqual(vw.getFunction(0x200007), 0x200000) self.assertEqual(vw.getFunction(0x200018), 0x200008)
def runServer(name, port): dirn = os.path.dirname(name) testfile = helpers.getTestPath('windows', 'amd64', 'firefox.exe') # load the file in so we get some workspace events, but not so many to make # this test take forever vw = vivisect.VivWorkspace() vw.loadFromFile(testfile) vw.setMeta('StorageName', name) vw.saveWorkspace() v_r_server.runMainServer(dirn, port)
def test_srec(self): fn = helpers.getTestPath(*path) vw = viv_cli.VivCli() vw.config.viv.parsers.srec.arch = 'msp430' vw.loadFromFile(fn) vw.makeFunction(0x4000) self.assertEqual(vw.getFunction(0x4000), 0x4000) self.assertEqual(vw.getFunction(0x4050), 0x4000) self.assertEqual(vw.getFunction(0x4060), 0x405e) self.assertEqual(vw.getFunction(0x4068), 0x405e)
def setUpClass(cls): super(PETests, cls).setUpClass() cls.psexec_fn = helpers.getTestPath('windows', 'i386', 'PsExec.exe') cls.vw_psexec = helpers.getTestWorkspace('windows', 'i386', 'PsExec.exe') cls.vw_sphinx = helpers.getTestWorkspace('windows', 'i386', 'sphinx_livepretend.exe') cls.vw_mimi = vivisect.VivWorkspace() mimi_fn = helpers.getTestPath('windows', 'i386', 'mimikatz.exe_') cls.vw_mimi.loadFromFile(mimi_fn) # this binary is a little big (1MB) # and we only care about the delay import table # so, don't do a full analysis fn_471 = helpers.getTestPath( 'windows', 'i386', '471ce36855fec6b44398b9b1e3cfb9e74b122fb2cc20fdf6603ebda39f86dddf') cls.vw_471 = vivisect.VivWorkspace() vivisect.parsers.pe.parseFile(cls.vw_471, fn_471)
def setUpClass(cls): testpath = helpers.getTestPath('windows', 'i386', 'malware.zip') cls.embed_vw = vivisect.VivWorkspace() cls.mmap_vw = vivisect.VivWorkspace() with zipfile.ZipFile(testpath, mode='r') as zp: fd = io.BytesIO(zp.open('mal_memmaps.exe', pwd=b'infected', mode='r').read()) # DEV: intentionally skipping analysis for now since the tests I have in mind # initially don't need it (and it adds a lot of time that isn't worth it until we # add a lot more tests) cls.mmap_vw.loadFromFd(fd) # DEV: This one needs analysis, but luckily only takes ~2 seconds to analyze fd = io.BytesIO(zp.open('mal_carve.exe', pwd=b'infected', mode='r').read()) cls.embed_vw.loadFromFd(fd) cls.embed_vw.analyze()
def setUpClass(cls): super(ELFTests, cls).setUpClass() cls.tests = [] for test in data: name, test_data, path = test logger.warn("======== %r ========", name) fn = helpers.getTestPath(*path) e = Elf.Elf(file(fn)) vw = viv_cli.VivCli() vw.loadFromFile(fn) #vw.analyze() vae.analyze(vw) vagr.analyze(vw) vaeep.analyze(vw) vagp.analyze(vw) cls.tests.append((name, test_data, fn, e, vw)) cls.maxDiff = None
def test_helper_pathjoin(self): # retrieve a known vivtestfiles path ( or skip ) helpers.getTestPath('windows', 'i386', 'helloworld.exe')
def setUpClass(cls): super(PETests, cls).setUpClass() cls.psexec_fn = helpers.getTestPath('windows', 'i386', 'PsExec.exe') cls.vw_psexec = viv_cli.VivCli() cls.vw_psexec.loadFromFile(cls.psexec_fn) cls.vw_psexec.analyze()
def test_helper_pathjoin(self): # retrieve a known vivtestfiles path ( or skip ) helpers.getTestPath("windows", "i386", "helloworld.exe")
def test_basic(self): testfile = helpers.getTestPath('windows', 'amd64', 'firefox.exe') good = vivisect.VivWorkspace() good.loadFromFile(testfile) host = '0.0.0.0' port = 0x4097 with tempfile.TemporaryDirectory() as tmpd: with tempfile.NamedTemporaryFile(dir=tmpd) as tmpf: proc = mp.Process(target=runServer, args=( tmpf.name, port, )) proc.daemon = True proc.start() # give the other process time to spin up time.sleep(0.5) # So...yea. The server could not be up yet, but I'm not waiting a mmillion years to # wait for it. retry = 0 conn = False while retry < 5: try: server = v_r_server.connectToServer(host, port) conn = True break except: retry += 1 time.sleep(0.2) if not conn: self.fail('Could not connect to %s:%s' % (host, port)) wslist = server.listWorkspaces() self.assertEqual(len(wslist), 1) self.assertEqual(server.getServerVersion(), 20130820) othr = v_r_server.getServerWorkspace(server, wslist[0]) # So the consumption of events from the server is *also* threaded, so I've got to do some blocking # to get us to wait on things retry = 0 while retry < 5: locs = othr.getLocations() if len(locs) != 1380: retry += 1 time.sleep(0.2) else: break self.assertEqual(len(othr.getLocations()), 1380) self.assertEqual(set(othr.getLocations()), set(good.getLocations())) self.assertEqual(set(othr.getXrefs()), set(good.getXrefs())) try: proc.terminate() proc.close() except: pass
def test_basic(self): testfile = helpers.getTestPath('windows', 'amd64', 'firefox.exe') good = vivisect.VivWorkspace() good.loadFromFile(testfile) host = 'localhost' port = 0x4097 with tempfile.TemporaryDirectory() as tmpd: tmpf = tempfile.NamedTemporaryFile(dir=tmpd, delete=False) try: proc = mp.Process(target=runServer, args=(tmpf.name, port,)) proc.daemon = True proc.start() # give the other process time to spin up time.sleep(0.5) # So...yea. The server could not be up yet, but I'm not waiting a million years to # wait for it. retry = 0 conn = False while retry < 5: try: server = v_r_server.connectToServer(host, port) conn = True break except: retry += 1 time.sleep(0.2) if not conn: self.fail('Could not connect to %s:%s' % (host, port)) wslist = server.listWorkspaces() self.assertEqual(len(wslist), 1) self.assertEqual(server.getServerVersion(), 20130820) othr = v_r_server.getServerWorkspace(server, wslist[0]) # So the consumption of events from the server is *also* threaded, so I've got to do some blocking # to get us to wait on things retry = 0 while retry < 5: locs = othr.getLocations() if len(locs) != 1389: retry += 1 time.sleep(0.2) else: break self.assertEqual(len(othr.getLocations()), 1389) self.assertEqual(set(othr.getLocations()), set(good.getLocations())) self.assertEqual(set(othr.getXrefs()), set(good.getXrefs())) try: othr.server = None q = othr.chan_lookup.get(othr.rchan) if q: # So it's not reeeealy auto analysis fini, but it's a good enough stand-in to get # the server thread to shutdown cleaner q.puts((v_const.VWE_AUTOANALFIN, None)) proc.terminate() proc.close() except: pass finally: tmpf.close() os.unlink(tmpf.name)