Files
manticore/tests/test_binaries.py
T
Theofilos Petsios 715cc436c7 Abstract Disassembler classes and Binja CPU + Platform (#364)
* adding abstract disasm class

* before adding abstract insn

* explicit capstone use

* (wip) removing capstone

* debugging nose

* removed disassembler from constructor

* nits

* capstone->cs and nits

* basic memory (wip)

* tmp

* added binja dissasm

* fixed execution pipeline - calling LLIL instructions

* updated parseargs to select disassembler

* unstable (disassembler at CPU constructor breaks tests)

* disasm fix for tests

* nit for aliases in x86

* added a flag to differentiate disassembly and IL-disassembly for binja

* before merging

* merging with dev-events master

* fixed signal forwarding for binja

* cleaner initialization

* Binja RegisterFile. Dropped Platform

* address fixup

* properly incrementing PC

* some work on XOR, SET_REG, REG, CONST, AND, PUSH, POP

* adding first CALL, JMP, LOAD (wip)

* JUMP fix

* GOTO and misc fixes in PC handling

* adding instructions (wip)

* fixing flags and sizes (wip)

* loading database if exists for faster analysis

* fix for register debug

* fixes for register sizes and flags

* FIX for multiple IL instructions sharing the same PC

* removed CONST_PTR and misc fixes

* RET, SHR, shift left & misc instructions, fixing insn sizes (wip)

* flag fixes

* ctypes 2's complement parsing

* JUMP_TO, SYSCALL

* syscall fixups and flag computation using binja il only

* FLAG, NEG, CMP(family) of LLIL, some unimplemented methods

* MUL, DIV

* cmpxchg

* MUL, IMUL, ROR, ROL

* fallback to capstone for all LLIL_UNIMPL and LLIL_UNIMPL_MEM

* fixes for registers and memory when switching CPUs

* check for binja to disable multiprocessing

* merging

* nit

* hack for serialization

* moved check for disassembler to Manticore from __main__

* removing __class__ refs

* cleanup from __class__.disasm

* size calculation from get_instruction_low_level_il

* fix for NEG, check for empty queue, execute refactor

* fixes for LLIL functions

* removal of redundant regfile writes

* nit fixes

* function overrides in Cpu classes and orphan printf cleanup

* nit

* incomplete merge

* verbosity temp mod

* cleanups of FIXMEs

* 2-stage constructor for disassembler

* cleanup binja refs in abstractcpu

* serialization for platform_cpu

* check for UNIMPL in all the il queue

* typo fix

* fix for arm

* typo correction and starting caching implementation

* restored register printing and fixed import in x86.py
2017-08-17 17:43:27 -04:00

125 lines
5.0 KiB
Python

import StringIO
import unittest
import sys
import shutil
import tempfile
import os
import hashlib
import subprocess
import time
#logging.basicConfig(filename = "test.log",
# format = "%(asctime)s: %(name)s:%(levelname)s: %(message)s",
# level = logging.DEBUG)
class IntegrationTest(unittest.TestCase):
_multiprocess_can_split_ = True
def setUp(self):
# Create a temporary directory
self.test_dir = tempfile.mkdtemp()
def tearDown(self):
# Remove the directory after the test
shutil.rmtree(self.test_dir)
def _loadVisitedSet(self, visited):
self.assertTrue(os.path.exists(visited))
vitems = open(visited, 'r').read().splitlines()
vitems = map(lambda x: int(x[2:], 16), vitems)
return set(vitems)
def _runWithTimeout(self, procargs, logfile, timeout=1200):
with open(os.path.join(os.pardir, logfile), "w") as output:
po = subprocess.Popen(procargs, stdout=output)
secs_used = 0
while po.poll() is None and secs_used < timeout:
time.sleep(1)
sys.stderr.write("~")
secs_used += 1
self.assertEqual(po.returncode, 0)
self.assertTrue(secs_used < timeout)
sys.stderr.write("\n")
def testTimeout(self):
dirname = os.path.dirname(__file__)
filename = os.path.abspath(os.path.join(dirname, 'binaries/arguments_linux_amd64'))
self.assertTrue(filename.startswith(os.getcwd()))
filename = filename[len(os.getcwd())+1:]
data = file(filename,'rb').read()
workspace = '%s/workspace'%self.test_dir
t = time.time()
with open(os.path.join(os.pardir, '%s/output.log'%self.test_dir), "w") as output:
subprocess.check_call(['python', '-m', 'manticore',
'--workspace', workspace,
'--timeout', '1',
'--procs', '4',
filename,
'+++++++++'], stdout=output)
self.assertTrue(time.time()-t < 20)
def test_cli_verbosity(self):
"""
Tests that default verbosity produces the expected volume of output
"""
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'binaries/basic_linux_amd64')
output = subprocess.check_output(['python', '-m', 'manticore', filename])
self.assertLessEqual(len(output.splitlines()), 60)
output = subprocess.check_output(['python', '-m', 'manticore', filename, "-v"])
self.assertLessEqual(len(output.splitlines()), 80)
# output = subprocess.check_output(['python', '-m', 'manticore', filename, "-vvv"])
# self.assertGreaterEqual(len(output.splitlines()), 435000)
# output = subprocess.check_output(['python', '-m', 'manticore', filename, "-vvvv"])
# self.assertGreaterEqual(len(output.splitlines()), 950000)
def testArgumentsAssertions(self):
dirname = os.path.dirname(__file__)
filename = os.path.abspath(os.path.join(dirname, 'binaries/arguments_linux_amd64'))
self.assertTrue(filename.startswith(os.getcwd()))
filename = filename[len(os.getcwd())+1:]
data = file(filename,'rb').read()
workspace = '%s/workspace'%self.test_dir
assertions = '%s/assertions.txt'%self.test_dir
file(assertions,'w').write('0x0000000000401003 ZF == 1')
with open(os.path.join(os.pardir, '%s/output.log'%self.test_dir), "w") as output:
subprocess.check_call(['python', '-m', 'manticore',
'--workspace', workspace,
'--proc', '4',
'--assertions', assertions,
filename,
'+++++++++'], stdout=output)
actual = self._loadVisitedSet(os.path.join(dirname, '%s/visited.txt'%workspace))
expected = self._loadVisitedSet(os.path.join(dirname, 'reference/arguments_linux_arm64_visited.txt'))
self.assertGreaterEqual(actual, expected)
def testDecree(self):
dirname = os.path.dirname(__file__)
filename = os.path.abspath(os.path.join(dirname, 'binaries/cadet_decree_x86'))
self.assertTrue(filename.startswith(os.getcwd()))
filename = filename[len(os.getcwd())+1:]
SE = os.path.join(dirname, '../main.py')
data = file(filename,'rb').read()
workspace = '%s/workspace'%self.test_dir
self._runWithTimeout(['python', '-m', 'manticore',
'--workspace', workspace,
'--timeout', '20',
'--proc', '4',
'--policy', 'uncovered',
filename], '%s/output.log'%self.test_dir)
actual = self._loadVisitedSet(os.path.join(dirname, '%s/visited.txt'%workspace))
self.assertTrue(len(actual) > 100 )
if __name__ == '__main__':
unittest.main()