From 13e21aadf41423596d1e446961092aa779c4b780 Mon Sep 17 00:00:00 2001 From: Ajax Date: Mon, 16 Nov 2015 10:28:44 +0100 Subject: Test/Qemu: add an emulator for test-i386 and expected outputs --- test/arch/x86/qemu/testqemu.py | 110 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 test/arch/x86/qemu/testqemu.py (limited to 'test/arch/x86/qemu/testqemu.py') diff --git a/test/arch/x86/qemu/testqemu.py b/test/arch/x86/qemu/testqemu.py new file mode 100644 index 00000000..d04308e4 --- /dev/null +++ b/test/arch/x86/qemu/testqemu.py @@ -0,0 +1,110 @@ +import os +import sys +import struct +import logging +from pdb import pm + +from miasm2.analysis.sandbox import Sandbox_Linux_x86_32 +from miasm2.jitter.jitload import log_func +from miasm2.os_dep.win_api_x86_32 import get_str_ansi, upck32 + +# Utils +def parse_fmt(s): + fmt = s[:]+"\x00" + out = [] + i = 0 + while i < len(fmt): + c = fmt[i] + if c != "%": + i+=1 + continue + if fmt[i+1] == "%": + i+=2 + continue + j = 0 + i+=1 + while fmt[i+j] in "0123456789$.-": + j+=1 + if fmt[i+j] in ['l']: + j +=1 + if fmt[i+j] == "h": + x = fmt[i+j:i+j+2] + else: + x = fmt[i+j] + i+=j + out.append(x) + return out + +nb_tests = 1 +def xxx___printf_chk(jitter): + """Tiny implementation of printf_chk""" + global nb_tests + ret_ad, args = jitter.func_args_cdecl(["out", "format"]) + if args.out != 1: + raise RuntimeError("Not implemented") + fmt = get_str_ansi(jitter, args.format) + # Manage llx + fmt = fmt.replace("llx", "lx") + + fmt_a = parse_fmt(fmt) + esp = jitter.cpu.ESP + args = [] + i = 0 + + for x in fmt_a: + a = upck32(jitter.vm.get_mem(esp + 8 + 4*i, 4)) + if x == "s": + a = get_str_ansi(jitter, a) + elif x.lower() in ("x", 'd'): + pass + elif x.lower() in ("f", "l"): + a2 = upck32(jitter.vm.get_mem(esp + 8 + 4*(i+1), 4)) + a = struct.unpack("d", struct.pack("Q", a2 << 32 | a))[0] + i += 1 + else: + raise RuntimeError("Not implemented format") + args.append(a) + i += 1 + + output = fmt%(tuple(args)) + # NaN bad repr in Python + output = output.replace("nan", "-nan") + + if "\n" not in output: + raise RuntimeError("Format must end with a \\n") + + # Check with expected result + line = expected.next() + if output != line: + print "Expected:", line + print "Obtained:", output + raise RuntimeError("Bad semantic") + + sys.stdout.write("[%d] %s" % (nb_tests, output)) + nb_tests += 1 + jitter.func_ret_cdecl(ret_ad, 0) + + +# Parse arguments +parser = Sandbox_Linux_x86_32.parser(description="ELF sandboxer") +parser.add_argument("filename", help="ELF Filename") +parser.add_argument("funcname", help="Targeted function's name") +parser.add_argument("expected", help="Expected output") +options = parser.parse_args() + +# Expected output +expected = open(options.expected) + +# Create sandbox +sb = Sandbox_Linux_x86_32(options.filename, options, globals()) +try: + addr = sb.elf.getsectionbyname(".symtab").symbols[options.funcname].value +except AttributeError: + raise RuntimeError("The target binary must have a symtab section") + +log_func.setLevel(logging.ERROR) + +# Run +sb.run(addr) + +assert(sb.jitter.run is False) -- cgit 1.4.1 From 35822fc551ce0c881c7e5216e2a2119cbed0a162 Mon Sep 17 00:00:00 2001 From: Ajax Date: Mon, 16 Nov 2015 12:46:42 +0100 Subject: Test/QEMU: emulate puts, enabling test_self_modifying_code --- test/arch/x86/qemu/testqemu.py | 16 ++++++++++++++++ test/test_all.py | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'test/arch/x86/qemu/testqemu.py') diff --git a/test/arch/x86/qemu/testqemu.py b/test/arch/x86/qemu/testqemu.py index d04308e4..7cf2ab75 100644 --- a/test/arch/x86/qemu/testqemu.py +++ b/test/arch/x86/qemu/testqemu.py @@ -84,6 +84,22 @@ def xxx___printf_chk(jitter): nb_tests += 1 jitter.func_ret_cdecl(ret_ad, 0) +def xxx_puts(jitter): + ''' + #include + int puts(const char *s); + + writes the string s and a trailing newline to stdout. + ''' + ret_addr, args = jitter.func_args_cdecl(['target']) + output = jitter.get_str_ansi(args.target) + # Check with expected result + line = expected.next() + if output != line.rstrip(): + print "Expected:", line + print "Obtained:", output + raise RuntimeError("Bad semantic") + return jitter.func_ret_cdecl(ret_addr, 1) # Parse arguments parser = Sandbox_Linux_x86_32.parser(description="ELF sandboxer") diff --git a/test/test_all.py b/test/test_all.py index 4dff7ed7..6288466a 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -105,10 +105,11 @@ QEMU_TESTS = { "jcc": ("tcc", "python"), "loop": ("tcc", "python"), "lea": ("tcc", "python"), + "self_modifying_code": ("tcc", "python"), "conv": ("tcc", "python"), # Unsupported # "floats", "bcd", "xchg", "string", "misc", "segs", "code16", "exceptions", - # "self_modifying_code", "single_step" + # "single_step" } -- cgit 1.4.1