diff options
255 files changed, 5027 insertions, 3694 deletions
diff --git a/.appveyor.yml b/.appveyor.yml index fb565570..3023dc8f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -11,11 +11,13 @@ environment: APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 PLATFORM_TOOLSET: v141 PYTHON: c:\Python27 + PYTHON_VERSION: "2.7.x" - platform: x64 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 PLATFORM_TOOLSET: v141 PYTHON: c:\Python27-x64 + PYTHON_VERSION: "2.7.x" # on_finish: # - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/.travis.yml b/.travis.yml index ee4f0ed5..e395e804 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,8 @@ sudo: false language: python -python: 2.7 +python: + - 2.7 + - 3.6 addons: apt: sources: ['llvm-toolchain-trusty-6.0', 'ubuntu-toolchain-r-test'] @@ -29,4 +31,4 @@ before_script: # install - python setup.py build build_ext - python setup.py install -script: cd test && python -W error test_all.py $MIASM_TEST_EXTRA_ARG && git ls-files -o --exclude-standard +script: cd test && flags=""; python --version |& grep -q "Python 3" || flags="-W error"; python $flags test_all.py $MIASM_TEST_EXTRA_ARG && git ls-files -o --exclude-standard diff --git a/README.md b/README.md index e8e257c8..bee55db3 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ Get a location db: Assemble a line: ```pycon >>> l = mn_x86.fromstring('XOR ECX, ECX', loc_db, 32) ->>> print l +>>> print(l) XOR ECX, ECX >>> mn_x86.asm(l) ['1\xc9', '3\xc9', 'g1\xc9', 'g3\xc9'] @@ -66,15 +66,15 @@ XOR ECX, ECX Modify an operand: ```pycon >>> l.args[0] = mn_x86.regs.EAX ->>> print l +>>> print(l) XOR EAX, ECX >>> a = mn_x86.asm(l) ->>> print a +>>> print(a) ['1\xc8', '3\xc1', 'g1\xc8', 'g3\xc1'] ``` Disassemble the result: ```pycon ->>> print mn_x86.dis(a[0], 32) +>>> print(mn_x86.dis(a[0], 32)) XOR EAX, ECX ``` Using `Machine` abstraction: @@ -82,14 +82,14 @@ Using `Machine` abstraction: ```pycon >>> from miasm2.analysis.machine import Machine >>> mn = Machine('x86_32').mn ->>> print mn.dis('\x33\x30', 32) +>>> print(mn.dis('\x33\x30', 32)) XOR ESI, DWORD PTR [EAX] ``` For Mips: ```pycon >>> mn = Machine('mips32b').mn ->>> print mn.dis('97A30020'.decode('hex'), "b") +>>> print(mn.dis(b'\x97\xa3\x00 ', "b")) LHU V1, 0x20(SP) ``` Intermediate representation @@ -99,8 +99,8 @@ Create an instruction: ```pycon >>> machine = Machine('arml') ->>> instr = machine.mn.dis('002088e0'.decode('hex'), 'l') ->>> print instr +>>> instr = machine.mn.dis('\x00 \x88\xe0', 'l') +>>> print(instr) ADD R2, R8, R0 ``` @@ -120,7 +120,7 @@ Add instruction to the pool: Print current pool: ```pycon >>> for lbl, irblock in ircfg.blocks.items(): -... print irblock.to_string(loc_db) +... print(irblock.to_string(loc_db)) loc_0: R2 = R8 + R0 @@ -133,9 +133,9 @@ Working with IR, for instance by getting side effects: ... for assignblk in irblock: ... rw = assignblk.get_rw() ... for dst, reads in rw.iteritems(): -... print 'read: ', [str(x) for x in reads] -... print 'written:', dst -... print +... print('read: ', [str(x) for x in reads]) +... print('written:', dst) +... print() ... read: ['R8', 'R0'] written: R2 @@ -178,7 +178,7 @@ Disassembling the shellcode at address `0`: >>> mdis = machine.dis_engine(c.bin_stream) >>> asmcfg = mdis.dis_multiblock(0) >>> for block in asmcfg.blocks: -... print block.to_string(asmcfg.loc_db) +... print(block.to_string(asmcfg.loc_db)) ... loc_0 LEA ECX, DWORD PTR [ECX + 0x4] @@ -292,7 +292,7 @@ Launching the execution: ```pycon >>> symbolic_pc = sb.run_at(ircfg, 0) ->>> print symbolic_pc +>>> print(symbolic_pc) ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10) ``` diff --git a/example/asm/shellcode.py b/example/asm/shellcode.py index 9be5b517..b14b7441 100755 --- a/example/asm/shellcode.py +++ b/example/asm/shellcode.py @@ -1,7 +1,9 @@ #! /usr/bin/env python2 +from __future__ import print_function from argparse import ArgumentParser from pdb import pm +from future.utils import viewitems from elfesteem import pe_init from elfesteem.strpatchwork import StrPatchwork @@ -9,6 +11,7 @@ from miasm2.core import parse_asm, asmblock from miasm2.analysis.machine import Machine from miasm2.core.interval import interval from miasm2.core.locationdb import LocationDB +from miasm2.core.utils import iterbytes, int_to_byte parser = ArgumentParser("Multi-arch (32 bits) assembler") parser.add_argument('architecture', help="architecture: " + @@ -41,8 +44,17 @@ if args.PE: pe = pe_init.PE(wsize=size) s_text = pe.SHList.add_section(name="text", addr=0x1000, rawsize=0x1000) s_iat = pe.SHList.add_section(name="iat", rawsize=0x100) - new_dll = [({"name": "USER32.dll", - "firstthunk": s_iat.addr}, ["MessageBoxA"])] + new_dll = [ + ( + { + "name": "USER32.dll", + "firstthunk": s_iat.addr + }, + [ + "MessageBoxA" + ] + ) + ] pe.DirImport.add_dlldesc(new_dll) s_myimp = pe.SHList.add_section(name="myimp", rawsize=len(pe.DirImport)) pe.DirImport.set_rva(s_myimp.addr) @@ -51,8 +63,11 @@ if args.PE: addr_main = pe.rva2virt(s_text.addr) virt = pe.virt output = pe - dst_interval = interval([(pe.rva2virt(s_text.addr), - pe.rva2virt(s_text.addr + s_text.size))]) + dst_interval = interval( + [ + (pe.rva2virt(s_text.addr), pe.rva2virt(s_text.addr + s_text.size)) + ] + ) else: st = StrPatchwork() @@ -74,20 +89,26 @@ asmcfg, loc_db = parse_asm.parse_txt(machine.mn, attrib, source, loc_db) loc_db.set_location_offset(loc_db.get_name_location("main"), addr_main) if args.PE: - loc_db.set_location_offset(loc_db.get_or_create_name_location("MessageBoxA"), - pe.DirImport.get_funcvirt('USER32.dll', - 'MessageBoxA')) + loc_db.set_location_offset( + loc_db.get_or_create_name_location("MessageBoxA"), + pe.DirImport.get_funcvirt( + 'USER32.dll', + 'MessageBoxA' + ) + ) # Print and graph firsts blocks before patching it for block in asmcfg.blocks: - print block + print(block) open("graph.dot", "w").write(asmcfg.dot()) # Apply patches -patches = asmblock.asm_resolve_final(machine.mn, - asmcfg, - loc_db, - dst_interval) +patches = asmblock.asm_resolve_final( + machine.mn, + asmcfg, + loc_db, + dst_interval +) if args.encrypt: # Encrypt code loc_start = loc_db.get_or_create_name_location(args.encrypt[0]) @@ -95,20 +116,18 @@ if args.encrypt: ad_start = loc_db.get_location_offset(loc_start) ad_stop = loc_db.get_location_offset(loc_stop) - new_patches = dict(patches) - for ad, val in patches.items(): + for ad, val in list(viewitems(patches)): if ad_start <= ad < ad_stop: - new_patches[ad] = "".join([chr(ord(x) ^ 0x42) for x in val]) - patches = new_patches + patches[ad] = b"".join(int_to_byte(ord(x) ^ 0x42) for x in iterbytes(val)) -print patches +print(patches) if isinstance(virt, StrPatchwork): - for offset, raw in patches.items(): + for offset, raw in viewitems(patches): virt[offset] = raw else: - for offset, raw in patches.items(): + for offset, raw in viewitems(patches): virt.set(offset, raw) # Produce output -open(args.output, 'wb').write(str(output)) +open(args.output, 'wb').write(bytes(output)) diff --git a/example/asm/simple.py b/example/asm/simple.py index 5480e2f5..e46faa48 100644 --- a/example/asm/simple.py +++ b/example/asm/simple.py @@ -1,3 +1,4 @@ +from __future__ import print_function from pdb import pm from pprint import pprint @@ -29,7 +30,7 @@ patches = asmblock.asm_resolve_final(mn_x86, asmcfg, loc_db) # Show resolved asmcfg for block in asmcfg.blocks: - print block + print(block) # Print offset -> bytes pprint(patches) diff --git a/example/disasm/callback.py b/example/disasm/callback.py index 02416b38..95c165d4 100644 --- a/example/disasm/callback.py +++ b/example/disasm/callback.py @@ -1,3 +1,4 @@ +from __future__ import print_function from miasm2.analysis.binary import Container from miasm2.analysis.machine import Machine from miasm2.core.asmblock import AsmConstraint @@ -41,27 +42,28 @@ def cb_x86_callpop(cur_bloc, loc_db, *args, **kwargs): # Prepare a tiny shellcode -shellcode = ''.join(["\xe8\x00\x00\x00\x00", # CALL $ - "X", # POP EAX - "\xc3", # RET - ]) +shellcode = ( + b"\xe8\x00\x00\x00\x00" # CALL $ + b"X" # POP EAX + b"\xc3" # RET +) # Instantiate a x86 32 bit architecture machine = Machine("x86_32") cont = Container.from_string(shellcode) mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) -print "Without callback:\n" +print("Without callback:\n") asmcfg = mdis.dis_multiblock(0) -print "\n".join(str(block) for block in asmcfg.blocks) +print("\n".join(str(block) for block in asmcfg.blocks)) # Enable callback mdis.dis_block_callback = cb_x86_callpop -print "=" * 40 -print "With callback:\n" +print("=" * 40) +print("With callback:\n") asmcfg_after = mdis.dis_multiblock(0) -print "\n".join(str(block) for block in asmcfg_after.blocks) +print("\n".join(str(block) for block in asmcfg_after.blocks)) # Ensure the callback has been called assert asmcfg.loc_key_to_block(asmcfg.heads()[0]).lines[0].name == "CALL" diff --git a/example/disasm/dis_binary.py b/example/disasm/dis_binary.py index 3e12ca91..4ac5ef26 100644 --- a/example/disasm/dis_binary.py +++ b/example/disasm/dis_binary.py @@ -1,3 +1,4 @@ +from __future__ import print_function import sys from miasm2.analysis.binary import Container from miasm2.analysis.machine import Machine @@ -23,7 +24,7 @@ asmcfg = mdis.dis_multiblock(addr) # Display each basic blocks for block in asmcfg.blocks: - print block + print(block) # Output control flow graph in a dot file open('bin_cfg.dot', 'w').write(asmcfg.dot()) diff --git a/example/disasm/dis_binary_ir.py b/example/disasm/dis_binary_ir.py index 197fccfd..ac642a36 100644 --- a/example/disasm/dis_binary_ir.py +++ b/example/disasm/dis_binary_ir.py @@ -1,4 +1,6 @@ +from __future__ import print_function import sys +from future.utils import viewvalues from miasm2.analysis.binary import Container from miasm2.analysis.machine import Machine @@ -28,8 +30,8 @@ ir_arch = machine.ir(mdis.loc_db) ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg) # Display each IR basic blocks -for irblock in ircfg.blocks.values(): - print irblock +for irblock in viewvalues(ircfg.blocks): + print(irblock) # Output ir control flow graph in a dot file open('bin_ir_cfg.dot', 'w').write(ircfg.dot()) diff --git a/example/disasm/dis_binary_ira.py b/example/disasm/dis_binary_ira.py index 726f353e..04bddbbb 100644 --- a/example/disasm/dis_binary_ira.py +++ b/example/disasm/dis_binary_ira.py @@ -1,4 +1,6 @@ +from __future__ import print_function import sys +from future.utils import viewvalues from miasm2.analysis.binary import Container from miasm2.analysis.machine import Machine @@ -30,8 +32,8 @@ ir_arch_analysis = machine.ira(mdis.loc_db) ircfg_analysis = ir_arch_analysis.new_ircfg_from_asmcfg(asmcfg) # Display each IR basic blocks -for irblock in ircfg_analysis.blocks.values(): - print irblock +for irblock in viewvalues(ircfg_analysis.blocks): + print(irblock) # Output ir control flow graph in a dot file open('bin_ira_cfg.dot', 'w').write(ircfg_analysis.dot()) diff --git a/example/disasm/dis_x86_string.py b/example/disasm/dis_x86_string.py index 8f919e4e..175e9264 100644 --- a/example/disasm/dis_x86_string.py +++ b/example/disasm/dis_x86_string.py @@ -1,8 +1,9 @@ +from __future__ import print_function from miasm2.analysis.binary import Container from miasm2.analysis.machine import Machine # The Container will provide a *bin_stream*, bytes source for the disasm engine -cont = Container.from_string("\x83\xf8\x10\x74\x07\x89\xc6\x0f\x47\xc3\xeb\x08\x89\xc8\xe8\x31\x33\x22\x11\x40\xc3") +cont = Container.from_string(b"\x83\xf8\x10\x74\x07\x89\xc6\x0f\x47\xc3\xeb\x08\x89\xc8\xe8\x31\x33\x22\x11\x40\xc3") # Instantiate a x86 32 bit architecture machine = Machine("x86_32") @@ -16,7 +17,7 @@ asmcfg = mdis.dis_multiblock(0) # Display each basic blocks for block in asmcfg.blocks: - print block + print(block) # Output control flow graph in a dot file open('str_cfg.dot', 'w').write(asmcfg.dot()) diff --git a/example/disasm/full.py b/example/disasm/full.py index 5161a299..de3f82ac 100644 --- a/example/disasm/full.py +++ b/example/disasm/full.py @@ -1,7 +1,10 @@ +from __future__ import print_function import logging from argparse import ArgumentParser from pdb import pm +from future.utils import viewitems, viewvalues + from miasm2.analysis.binary import Container from miasm2.core.asmblock import log_asmblock, AsmCFG from miasm2.core.interval import interval @@ -35,7 +38,8 @@ parser.add_argument('-n', "--funcswatchdog", default=None, type=int, help="Maximum number of function to disassemble") parser.add_argument('-r', "--recurfunctions", action="store_true", help="Disassemble founded functions") -parser.add_argument('-v', "--verbose", action="count", help="Verbose mode") +parser.add_argument('-v', "--verbose", action="count", help="Verbose mode", + default=0) parser.add_argument('-g', "--gen_ir", action="store_true", help="Compute the intermediate representation") parser.add_argument('-z', "--dis-nulstart-block", action="store_true", @@ -43,7 +47,8 @@ parser.add_argument('-z', "--dis-nulstart-block", action="store_true", parser.add_argument('-l', "--dontdis-retcall", action="store_true", help="If set, disassemble only call destinations") parser.add_argument('-s', "--simplify", action="count", - help="Apply simplifications rules (liveness, graph simplification, ...)") + help="Apply simplifications rules (liveness, graph simplification, ...)", + default=0) parser.add_argument("--base-address", default=0, type=lambda x: int(x, 0), help="Base address of the input binary") @@ -92,7 +97,7 @@ log.info("import machine...") # Use the guessed architecture or the specified one arch = args.architecture if args.architecture else cont.arch if not arch: - print "Architecture recognition fail. Please specify it in arguments" + print("Architecture recognition fail. Please specify it in arguments") exit(-1) # Instance the arch-dependent machine @@ -177,7 +182,7 @@ while not finish and todo: # Generate dotty graph all_asmcfg = AsmCFG(mdis.loc_db) -for blocks in all_funcs_blocks.values(): +for blocks in viewvalues(all_funcs_blocks): all_asmcfg += blocks @@ -189,7 +194,7 @@ log.info('generate intervals') all_lines = [] total_l = 0 -print done_interval +print(done_interval) if args.image: log.info('build img') done_interval.show() @@ -199,7 +204,7 @@ for i, j in done_interval.intervals: all_lines.sort(key=lambda x: x.offset) -open('lines.dot', 'w').write('\n'.join([str(l) for l in all_lines])) +open('lines.dot', 'w').write('\n'.join(str(l) for l in all_lines)) log.info('total lines %s' % total_l) @@ -217,7 +222,7 @@ class IRADelModCallStack(ira): for assignblk in assignblks: dct = dict(assignblk) dct = { - dst:src for (dst, src) in dct.iteritems() if dst != self.sp + dst:src for (dst, src) in viewitems(dct) if dst != self.sp } out.append(AssignBlock(dct, assignblk.instr)) return out, extra @@ -238,21 +243,21 @@ if args.gen_ir: head = list(entry_points)[0] - for ad, asmcfg in all_funcs_blocks.items(): + for ad, asmcfg in viewitems(all_funcs_blocks): log.info("generating IR... %x" % ad) for block in asmcfg.blocks: ir_arch.add_asmblock_to_ircfg(block, ircfg) ir_arch_a.add_asmblock_to_ircfg(block, ircfg_a) log.info("Print blocks (without analyse)") - for label, block in ir_arch.blocks.iteritems(): - print block + for label, block in viewitems(ir_arch.blocks): + print(block) log.info("Gen Graph... %x" % ad) log.info("Print blocks (with analyse)") - for label, block in ir_arch_a.blocks.iteritems(): - print block + for label, block in viewitems(ir_arch_a.blocks): + print(block) if args.simplify > 0: log.info("Simplify...") @@ -289,7 +294,7 @@ if args.propagexpr: continue if reg in regs_todo: out[reg] = dst - return set(out.values()) + return set(viewvalues(out)) # Add dummy dependency to uncover out regs assignment for loc in ircfg_a.leaves(): @@ -317,7 +322,7 @@ if args.propagexpr: """ try: - _ = bs.getbytes(addr, size/8) + _ = bs.getbytes(addr, size // 8) except IOError: return False return True diff --git a/example/disasm/single_instr.py b/example/disasm/single_instr.py index d17e303f..70b37220 100644 --- a/example/disasm/single_instr.py +++ b/example/disasm/single_instr.py @@ -1,14 +1,15 @@ +from __future__ import print_function from miasm2.arch.x86.arch import mn_x86 from miasm2.arch.x86.regs import EDX from miasm2.core.locationdb import LocationDB loc_db = LocationDB() l = mn_x86.fromstring('MOV EAX, EBX', loc_db, 32) -print "instruction:", l -print "arg:", l.args[0] +print("instruction:", l) +print("arg:", l.args[0]) x = mn_x86.asm(l) -print x +print(x) l.args[0] = EDX y = mn_x86.asm(l) -print y -print mn_x86.dis(y[0], 32) +print(y) +print(mn_x86.dis(y[0], 32)) diff --git a/example/expression/access_c.py b/example/expression/access_c.py index b23ba81b..c6f26a10 100644 --- a/example/expression/access_c.py +++ b/example/expression/access_c.py @@ -39,10 +39,12 @@ Then, in the C generator: ExprCompose(var1, 0) => var1 """ - +from __future__ import print_function import sys +from future.utils import viewitems, viewvalues + from miasm2.analysis.machine import Machine from miasm2.analysis.binary import Container from miasm2.expression.expression import ExprOp, ExprCompose, ExprId, ExprInt @@ -57,21 +59,21 @@ from miasm2.core.ctypesmngr import CAstTypes, CTypePtr, CTypeStruct def find_call(ircfg): """Returns (irb, index) which call""" - for irb in ircfg.blocks.values(): + for irb in viewvalues(ircfg.blocks): out = set() if len(irb) < 2: continue assignblk = irb[-2] - for src in assignblk.itervalues(): + for src in viewvalues(assignblk): if not isinstance(src, ExprOp): continue if not src.op.startswith('call_func'): continue - out.add((irb, len(irb) - 2)) + out.add((irb.loc_key, len(irb) - 2)) if len(out) != 1: continue - irb, index = out.pop() - yield irb, index + loc_key, index = out.pop() + yield loc_key, index class MyExprToAccessC(ExprToAccessC): @@ -96,9 +98,10 @@ def get_funcs_arg0(ctx, ira, ircfg, lbl_head): g_dep = DependencyGraph(ircfg, follow_call=False) element = ira.arch.regs.RSI - for irb, index in find_call(ircfg): + for loc_key, index in find_call(ircfg): + irb = ircfg.get_block(loc_key) instr = irb[index].instr - print 'Analysing references from:', hex(instr.offset), instr + print('Analysing references from:', hex(instr.offset), instr) g_list = g_dep.get(irb.loc_key, set([element]), index, set([lbl_head])) for dep in g_list: emul_result = dep.emul(ira, ctx) @@ -113,7 +116,7 @@ class MyCHandler(CHandler): -data = open(sys.argv[1]).read() +data = open(sys.argv[1], 'rb').read() # Digest C information text = """ struct human { @@ -160,7 +163,7 @@ expr_types = {arg0: (ptr_llhuman,), mychandler = MyCHandler(types_mngr, expr_types) for expr in get_funcs_arg0(ctx, ir_arch_a, ircfg, lbl_head): - print "Access:", expr + print("Access:", expr) for c_str, ctype in mychandler.expr_to_c_and_types(expr): - print '\taccess:', c_str - print '\tc type:', ctype + print('\taccess:', c_str) + print('\tc type:', ctype) diff --git a/example/expression/asm_to_ir.py b/example/expression/asm_to_ir.py index 7036d960..16f766e1 100644 --- a/example/expression/asm_to_ir.py +++ b/example/expression/asm_to_ir.py @@ -1,5 +1,8 @@ +from __future__ import print_function from pdb import pm +from future.utils import viewitems + from miasm2.arch.x86.arch import mn_x86 from miasm2.core import parse_asm from miasm2.expression.expression import * @@ -27,11 +30,11 @@ loop: loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0) for block in asmcfg.blocks: - print block + print(block) -print "symbols:" -print loc_db +print("symbols:") +print(loc_db) patches = asmblock.asm_resolve_final(mn_x86, asmcfg, loc_db) # Translate to IR @@ -39,16 +42,16 @@ ir_arch = ir_a_x86_32(loc_db) ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg) # Display IR -for lbl, irblock in ircfg.blocks.items(): - print irblock +for lbl, irblock in viewitems(ircfg.blocks): + print(irblock) # Dead propagation open('graph.dot', 'w').write(ircfg.dot()) -print '*' * 80 +print('*' * 80) dead_simp(ir_arch, ircfg) open('graph2.dot', 'w').write(ircfg.dot()) # Display new IR -print 'new ir blocks' -for lbl, irblock in ircfg.blocks.items(): - print irblock +print('new ir blocks') +for lbl, irblock in viewitems(ircfg.blocks): + print(irblock) diff --git a/example/expression/basic_op.py b/example/expression/basic_op.py index 6032f483..8b5d7e2b 100644 --- a/example/expression/basic_op.py +++ b/example/expression/basic_op.py @@ -1,31 +1,32 @@ +from __future__ import print_function from miasm2.expression.expression import * -print """ +print(""" Simple expression manipulation demo -""" +""") # define 2 ID a = ExprId('eax', 32) b = ExprId('ebx', 32) -print a, b +print(a, b) # eax ebx # add those ID c = ExprOp('+', a, b) -print c +print(c) # (eax + ebx) # + automatically generates ExprOp('+', a, b) c = a + b -print c +print(c) # (eax + ebx) # ax is a slice of eax ax = a[:16] -print ax +print(ax) # eax[0:16] # memory deref d = ExprMem(c, 32) -print d +print(d) # @32[(eax + ebx)] diff --git a/example/expression/basic_simplification.py b/example/expression/basic_simplification.py index eefdc765..5ecf21db 100644 --- a/example/expression/basic_simplification.py +++ b/example/expression/basic_simplification.py @@ -1,9 +1,10 @@ +from __future__ import print_function from miasm2.expression.expression import * from miasm2.expression.simplifications import expr_simp -print """ +print(""" Simple expression simplification demo -""" +""") a = ExprId('eax', 32) @@ -14,6 +15,6 @@ exprs = [a + b - a, ExprCompose(a[:8], a[8:16])] for e in exprs: - print '*' * 40 - print 'original expression:', e - print "simplified:", expr_simp(e) + print('*' * 40) + print('original expression:', e) + print("simplified:", expr_simp(e)) diff --git a/example/expression/constant_propagation.py b/example/expression/constant_propagation.py index e70f8163..1259758b 100644 --- a/example/expression/constant_propagation.py +++ b/example/expression/constant_propagation.py @@ -25,7 +25,7 @@ args = parser.parse_args() machine = Machine("x86_32") -cont = Container.from_stream(open(args.filename)) +cont = Container.from_stream(open(args.filename, 'rb')) mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) ir_arch = machine.ira(mdis.loc_db) addr = int(args.address, 0) diff --git a/example/expression/export_llvm.py b/example/expression/export_llvm.py index a0af66b7..c8ee14a5 100644 --- a/example/expression/export_llvm.py +++ b/example/expression/export_llvm.py @@ -1,3 +1,5 @@ +from future.utils import viewitems, viewvalues + from argparse import ArgumentParser from miasm2.analysis.binary import Container from miasm2.analysis.machine import Machine @@ -12,7 +14,7 @@ parser.add_argument("--architecture", "-a", help="Force architecture") args = parser.parse_args() # This part focus on obtaining an IRCFG to transform # -cont = Container.from_stream(open(args.target)) +cont = Container.from_stream(open(args.target, 'rb')) machine = Machine(args.architecture if args.architecture else cont.arch) ir = machine.ir(cont.loc_db) dis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) @@ -47,12 +49,14 @@ func.init_fc() # ... all_regs = set() -for block in ircfg.blocks.itervalues(): +for block in viewvalues(ircfg.blocks): for irs in block.assignblks: - for dst, src in irs.get_rw(mem_read=True).iteritems(): + for dst, src in viewitems(irs.get_rw(mem_read=True)): elem = src.union(set([dst])) - all_regs.update(x for x in elem - if x.is_id()) + all_regs.update( + x for x in elem + if x.is_id() + ) reg2glob = {} for var in all_regs: @@ -70,7 +74,7 @@ for var in all_regs: func.from_ircfg(ircfg, append_ret=False) # Finish the saving of registers (temporary version to global) -for reg, glob in reg2glob.iteritems(): +for reg, glob in viewitems(reg2glob): value = func.builder.load(func.local_vars_pointers[reg.name]) func.builder.store(value, glob) diff --git a/example/expression/expr_c.py b/example/expression/expr_c.py index 37c9f510..83cc727b 100644 --- a/example/expression/expr_c.py +++ b/example/expression/expr_c.py @@ -3,6 +3,7 @@ Parse C expression to access variables and retrieve information: * Miasm expression to access this variable * variable type """ +from __future__ import print_function from miasm2.core.ctypesmngr import CTypeStruct, CAstTypes, CTypePtr from miasm2.arch.x86.ctype import CTypeAMD64_unk @@ -56,6 +57,6 @@ c_acceses = ["ptr->width", for c_str in c_acceses: expr = mychandler.c_to_expr(c_str) c_type = mychandler.c_to_type(c_str) - print 'C access:', c_str - print '\tExpr:', expr - print '\tType:', c_type + print('C access:', c_str) + print('\tExpr:', expr) + print('\tType:', c_type) diff --git a/example/expression/expr_grapher.py b/example/expression/expr_grapher.py index e0562852..e1643b03 100644 --- a/example/expression/expr_grapher.py +++ b/example/expression/expr_grapher.py @@ -1,6 +1,8 @@ +from __future__ import print_function + from miasm2.expression.expression import * -print "Simple Expression grapher demo" +print("Simple Expression grapher demo") a = ExprId("A", 32) b = ExprId("B", 32) @@ -8,13 +10,13 @@ c = ExprId("C", 32) d = ExprId("D", 32) m = ExprMem(a + b + c + a, 32) -e1 = ExprCompose(a + b - (c * a) / m | b, a + m) +e1 = ExprCompose(a + b - ((c * a) // m) | b, a + m) e2 = ExprInt(15, 64) e = ExprCond(d, e1, e2)[0:32] -print "[+] Expression:" -print e +print("[+] Expression:") +print(e) g = e.graph() -print "[+] Graph:" -print g.dot() +print("[+] Graph:") +print(g.dot()) diff --git a/example/expression/expr_random.py b/example/expression/expr_random.py index 66c09f2e..5ac3be06 100644 --- a/example/expression/expr_random.py +++ b/example/expression/expr_random.py @@ -1,22 +1,24 @@ +from __future__ import print_function +from builtins import range import string import random from miasm2.expression.expression_helper import ExprRandom -print "Simple expression generator\n" +print("Simple expression generator\n") depth = 8 seed = 0 random.seed(seed) -print "- An ID:" -print ExprRandom.identifier() -print "- A number:" -print ExprRandom.number() +print("- An ID:") +print(ExprRandom.identifier()) +print("- A number:") +print(ExprRandom.number()) -print "- 3 expressions (without cleaning expression cache):" -for i in xrange(3): - print "\t%s\n" % ExprRandom.get(depth=depth, clean=False) +print("- 3 expressions (without cleaning expression cache):") +for i in range(3): + print("\t%s\n" % ExprRandom.get(depth=depth, clean=False)) class ExprRandom_NoPerfect_NoReuse_UppercaseIdent(ExprRandom): """ExprRandom extension with: @@ -27,8 +29,8 @@ class ExprRandom_NoPerfect_NoReuse_UppercaseIdent(ExprRandom): perfect_tree = False reuse_element = False - identifier_charset = string.uppercase + identifier_charset = string.ascii_uppercase -print "- 3 expressions with a custom generator:" -for i in xrange(3): - print "\t%s\n" % ExprRandom_NoPerfect_NoReuse_UppercaseIdent.get(depth=depth) +print("- 3 expressions with a custom generator:") +for i in range(3): + print("\t%s\n" % ExprRandom_NoPerfect_NoReuse_UppercaseIdent.get(depth=depth)) diff --git a/example/expression/expr_translate.py b/example/expression/expr_translate.py index e1505dae..1a36a64c 100644 --- a/example/expression/expr_translate.py +++ b/example/expression/expr_translate.py @@ -1,5 +1,8 @@ +from __future__ import print_function import random +from future.utils import viewitems + from miasm2.expression.expression import * from miasm2.expression.expression_helper import ExprRandom from miasm2.ir.translators import Translator @@ -13,32 +16,32 @@ class ExprRandom_OpSubRange(ExprRandom): } -print "[+] Compute a random expression:" +print("[+] Compute a random expression:") expr = ExprRandom_OpSubRange.get(depth=8) -print "-> %s" % expr -print +print("-> %s" % expr) +print() target_exprs = {lang:Translator.to_language(lang).from_expr(expr) for lang in Translator.available_languages()} -for target_lang, target_expr in target_exprs.iteritems(): - print "[+] Translate in %s:" % target_lang - print target_expr - print +for target_lang, target_expr in viewitems(target_exprs): + print("[+] Translate in %s:" % target_lang) + print(target_expr) + print() -print "[+] Eval in Python:" +print("[+] Eval in Python:") def memory(addr, size): ret = random.randint(0, (1 << size) - 1) - print "Memory access: @0x%x -> 0x%x" % (addr, ret) + print("Memory access: @0x%x -> 0x%x" % (addr, ret)) return ret for expr_id in expr.get_r(mem_read=True): if isinstance(expr_id, ExprId): value = random.randint(0, (1 << expr_id.size) - 1) - print "Declare var: %s = 0x%x" % (expr_id.name, value) + print("Declare var: %s = 0x%x" % (expr_id.name, value)) globals()[expr_id.name] = value -print "-> 0x%x" % eval(target_exprs["Python"]) +print("-> 0x%x" % eval(target_exprs["Python"])) -print "[+] Validate the Miasm syntax rebuilding" +print("[+] Validate the Miasm syntax rebuilding") exprRebuild = eval(target_exprs["Miasm"]) assert(expr == exprRebuild) diff --git a/example/expression/get_read_write.py b/example/expression/get_read_write.py index 34d0f94a..0c8bb3dd 100644 --- a/example/expression/get_read_write.py +++ b/example/expression/get_read_write.py @@ -1,3 +1,7 @@ +from __future__ import print_function + +from future.utils import viewitems + from miasm2.arch.x86.arch import mn_x86 from miasm2.expression.expression import get_rw from miasm2.arch.x86.ira import ir_a_x86_32 @@ -6,10 +10,10 @@ from miasm2.core.locationdb import LocationDB loc_db = LocationDB() -print """ +print(""" Simple expression manipulation demo. Get read/written registers for a given instruction -""" +""") arch = mn_x86 ir_arch = ir_a_x86_32(loc_db) @@ -18,14 +22,14 @@ instr = arch.fromstring('LODSB', loc_db, 32) instr.offset, instr.l = 0, 15 ir_arch.add_instr_to_ircfg(instr, ircfg) -print '*' * 80 -for lbl, irblock in ircfg.blocks.iteritems(): - print irblock +print('*' * 80) +for lbl, irblock in viewitems(ircfg.blocks): + print(irblock) for assignblk in irblock: rw = assignblk.get_rw() - for dst, reads in rw.iteritems(): - print 'read: ', [str(x) for x in reads] - print 'written:', dst - print + for dst, reads in viewitems(rw): + print('read: ', [str(x) for x in reads]) + print('written:', dst) + print() open('graph_instr.dot', 'w').write(ircfg.dot()) diff --git a/example/expression/graph_dataflow.py b/example/expression/graph_dataflow.py index 92bcf249..55159598 100644 --- a/example/expression/graph_dataflow.py +++ b/example/expression/graph_dataflow.py @@ -1,5 +1,8 @@ +from __future__ import print_function from argparse import ArgumentParser +from future.utils import viewitems, viewvalues + from miasm2.analysis.binary import Container from miasm2.analysis.machine import Machine from miasm2.expression.expression import get_expr_mem @@ -17,10 +20,6 @@ parser.add_argument("-s", "--symb", help="Symbolic execution mode", args = parser.parse_args() -def node_x_2_id(n, x): - return hash(str(n) + str(x)) & 0xffffffffffffffff - - def get_node_name(label, i, n): n_name = (label, i, n) return n_name @@ -30,8 +29,8 @@ def intra_block_flow_symb(ir_arch, _, flow_graph, irblock, in_nodes, out_nodes): symbols_init = ir_arch.arch.regs.regs_init.copy() sb = SymbolicExecutionEngine(ir_arch, symbols_init) sb.eval_updt_irblock(irblock) - print '*' * 40 - print irblock + print('*' * 40) + print(irblock) out = sb.modified(mems=False) @@ -86,14 +85,14 @@ def node2str(node): def gen_block_data_flow_graph(ir_arch, ircfg, ad, block_flow_cb): - for irblock in ircfg.blocks.values(): - print irblock + for irblock in viewvalues(ircfg.blocks): + print(irblock) dead_simp(ir_arch, ircfg) irblock_0 = None - for irblock in ircfg.blocks.values(): + for irblock in viewvalues(ircfg.blocks): loc_key = irblock.loc_key offset = ircfg.loc_db.get_location_offset(loc_key) if offset == ad: @@ -110,15 +109,15 @@ def gen_block_data_flow_graph(ir_arch, ircfg, ad, block_flow_cb): irb_in_nodes[label] = {} irb_out_nodes[label] = {} - for label, irblock in ircfg.blocks.iteritems(): + for label, irblock in viewitems(ircfg.blocks): block_flow_cb(ir_arch, ircfg, flow_graph, irblock, irb_in_nodes[label], irb_out_nodes[label]) for label in ircfg.blocks: - print label - print 'IN', [str(x) for x in irb_in_nodes[label]] - print 'OUT', [str(x) for x in irb_out_nodes[label]] + print(label) + print('IN', [str(x) for x in irb_in_nodes[label]]) + print('OUT', [str(x) for x in irb_out_nodes[label]]) - print '*' * 20, 'interblock', '*' * 20 + print('*' * 20, 'interblock', '*' * 20) inter_block_flow(ir_arch, ircfg, flow_graph, irblock_0.loc_key, irb_in_nodes, irb_out_nodes) # from graph_qt import graph_qt @@ -128,22 +127,22 @@ def gen_block_data_flow_graph(ir_arch, ircfg, ad, block_flow_cb): ad = int(args.addr, 16) -print 'disasm...' -cont = Container.from_stream(open(args.filename)) +print('disasm...') +cont = Container.from_stream(open(args.filename, 'rb')) machine = Machine("x86_32") mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) mdis.follow_call = True asmcfg = mdis.dis_multiblock(ad) -print 'ok' +print('ok') -print 'generating dataflow graph for:' +print('generating dataflow graph for:') ir_arch_analysis = machine.ira(mdis.loc_db) ircfg = ir_arch_analysis.new_ircfg_from_asmcfg(asmcfg) -for irblock in ircfg.blocks.values(): - print irblock +for irblock in viewvalues(ircfg.blocks): + print(irblock) if args.symb: @@ -153,11 +152,11 @@ else: gen_block_data_flow_graph(ir_arch_analysis, ircfg, ad, block_flow_cb) -print '*' * 40 -print """ +print('*' * 40) +print(""" View with: dotty dataflow.dot or Generate ps with pdf: dot -Tps dataflow_xx.dot -o graph.ps -""" +""") diff --git a/example/expression/simplification_add.py b/example/expression/simplification_add.py index 621d1139..6ac36a17 100644 --- a/example/expression/simplification_add.py +++ b/example/expression/simplification_add.py @@ -1,13 +1,14 @@ +from __future__ import print_function import miasm2.expression.expression as m2_expr from miasm2.expression.simplifications import expr_simp from pdb import pm -print """ +print(""" Expression simplification demo: Adding a simplification: a + a + a == a * 3 More detailed examples can be found in miasm2/expression/simplification*. -""" +""") # Define the simplification method ## @expr_simp is the current expression simplifier instance @@ -32,14 +33,14 @@ def simp_add_mul(expr_simp, expr): a = m2_expr.ExprId('a', 32) base_expr = a + a + a -print "Without adding the simplification:" -print "\t%s = %s" % (base_expr, expr_simp(base_expr)) +print("Without adding the simplification:") +print("\t%s = %s" % (base_expr, expr_simp(base_expr))) # Enable pass expr_simp.enable_passes({m2_expr.ExprOp: [simp_add_mul]}) -print "After adding the simplification:" -print "\t%s = %s" % (base_expr, expr_simp(base_expr)) +print("After adding the simplification:") +print("\t%s = %s" % (base_expr, expr_simp(base_expr))) # Automatic fail assert(expr_simp(base_expr) == m2_expr.ExprOp("*", a, diff --git a/example/expression/simplification_tools.py b/example/expression/simplification_tools.py index cb062fb3..a9bcc429 100644 --- a/example/expression/simplification_tools.py +++ b/example/expression/simplification_tools.py @@ -1,10 +1,11 @@ +from __future__ import print_function from miasm2.expression.expression import * from pdb import pm -print """ +print(""" Expression simplification demo. (and regression test) -""" +""") a = ExprId('a', 32) @@ -39,26 +40,26 @@ def replace_expr(e): return e -print x +print(x) y = x.visit(replace_expr) -print y -print x.copy() -print y.copy() -print y == y.copy() -print repr(y), repr(y.copy()) +print(y) +print(x.copy()) +print(y.copy()) +print(y == y.copy()) +print(repr(y), repr(y.copy())) z = ExprCompose(a[5:5 + 8], b[:16], x[:8]) -print z -print z.copy() -print z[:31].copy().visit(replace_expr) +print(z) +print(z.copy()) +print(z[:31].copy().visit(replace_expr)) -print 'replace' -print x.replace_expr({c + ExprInt(0x42, 32): d, - a + b: c, }) -print z.replace_expr({c + ExprInt(0x42, 32): d, - a + b: c, }) +print('replace') +print(x.replace_expr({c + ExprInt(0x42, 32): d, + a + b: c, })) +print(z.replace_expr({c + ExprInt(0x42, 32): d, + a + b: c, })) u = z.copy() -print u +print(u) diff --git a/example/expression/solve_condition_stp.py b/example/expression/solve_condition_stp.py index c79dd0b8..e0ab09da 100644 --- a/example/expression/solve_condition_stp.py +++ b/example/expression/solve_condition_stp.py @@ -1,8 +1,11 @@ +from __future__ import print_function import sys import subprocess from optparse import OptionParser from pdb import pm +from future.utils import viewitems + from miasm2.analysis.machine import Machine from miasm2.analysis.binary import Container from miasm2.expression.expression import ExprInt, ExprCond, ExprId, \ @@ -29,9 +32,9 @@ if not args: def emul_symb(ir_arch, ircfg, mdis, states_todo, states_done): while states_todo: addr, symbols, conds = states_todo.pop() - print '*' * 40, "addr", addr, '*' * 40 + print('*' * 40, "addr", addr, '*' * 40) if (addr, symbols, conds) in states_done: - print 'Known state, skipping', addr + print('Known state, skipping', addr) continue states_done.add((addr, symbols, conds)) symbexec = SymbolicExecutionEngine(ir_arch) @@ -40,10 +43,10 @@ def emul_symb(ir_arch, ircfg, mdis, states_todo, states_done): del symbexec.symbols[ir_arch.pc] irblock = get_block(ir_arch, ircfg, mdis, addr) - print 'Run block:' - print irblock + print('Run block:') + print(irblock) addr = symbexec.eval_updt_irblock(irblock) - print 'Final state:' + print('Final state:') symbexec.dump(mems=False) assert addr is not None @@ -55,16 +58,16 @@ def emul_symb(ir_arch, ircfg, mdis, states_todo, states_done): addr_b = expr_simp(symbexec.eval_expr(addr.replace_expr(cond_group_b), {})) if not (addr_a.is_int() or addr_a.is_loc() and addr_b.is_int() or addr_b.is_loc()): - print str(addr_a), str(addr_b) + print(str(addr_a), str(addr_b)) raise ValueError("Unsupported condition") if isinstance(addr_a, ExprInt): addr_a = int(addr_a.arg) if isinstance(addr_b, ExprInt): addr_b = int(addr_b.arg) - states_todo.add((addr_a, symbexec.symbols.copy(), tuple(list(conds) + cond_group_a.items()))) - states_todo.add((addr_b, symbexec.symbols.copy(), tuple(list(conds) + cond_group_b.items()))) + states_todo.add((addr_a, symbexec.symbols.copy(), tuple(list(conds) + list(viewitems(cond_group_a))))) + states_todo.add((addr_b, symbexec.symbols.copy(), tuple(list(conds) + list(viewitems(cond_group_b))))) elif addr == ret_addr: - print 'Return address reached' + print('Return address reached') continue elif addr.is_int(): addr = int(addr.arg) @@ -81,7 +84,7 @@ if __name__ == '__main__': addr = int(options.address, 16) - cont = Container.from_stream(open(args[0])) + cont = Container.from_stream(open(args[0], 'rb')) mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) ir_arch = machine.ir(mdis.loc_db) ircfg = ir_arch.new_ircfg() @@ -120,7 +123,7 @@ if __name__ == '__main__': for instr in block.lines: for i, arg in enumerate(instr.args): instr.args[i]= arg.replace_expr(fix_args) - print block + print(block) # add fake address and len to parsed instructions ir_arch.add_asmblock_to_ircfg(block, ircfg) @@ -139,12 +142,12 @@ if __name__ == '__main__': all_info = [] - print '*' * 40, 'conditions to match', '*' * 40 - for addr, symbols, conds in sorted(states_done): - print '*' * 40, addr, '*' * 40 + print('*' * 40, 'conditions to match', '*' * 40) + for addr, symbols, conds in sorted(states_done, key=str): + print('*' * 40, addr, '*' * 40) reqs = [] for k, v in conds: - print k, v + print(k, v) reqs.append((k, v)) all_info.append((addr, reqs)) @@ -179,14 +182,14 @@ if __name__ == '__main__': "-p", '--SMTLIB2', "out.dot"]) except OSError: - print "Cannot find stp binary!" + print("Cannot find stp binary!") break for c in cases.split('\n'): if c.startswith('ASSERT'): all_cases.add((addr, c)) - print '*' * 40, 'ALL COND', '*' * 40 + print('*' * 40, 'ALL COND', '*' * 40) all_cases = list(all_cases) all_cases.sort(key=lambda x: (x[0], x[1])) for addr, val in all_cases: - print 'Address:', addr, 'is reachable using argc', val + print('Address:', addr, 'is reachable using argc', val) diff --git a/example/ida/ctype_propagation.py b/example/ida/ctype_propagation.py index 61bc747f..a043b9c9 100644 --- a/example/ida/ctype_propagation.py +++ b/example/ida/ctype_propagation.py @@ -1,7 +1,10 @@ +from __future__ import print_function import ida_kernwin import idc import ida_funcs +from future.utils import viewitems + from miasm2.core.bin_stream_ida import bin_stream_ida from miasm2.expression import expression as m2_expr from miasm2.expression.simplifications import expr_simp @@ -198,11 +201,12 @@ class SymbExecCTypeFix(SymbExecCType): for c_str, c_type in self.chandler.expr_to_c_and_types(expr, self.symbols): expr = self.cst_propag_link.get((irb.loc_key, index), {}).get(expr, expr) offset2cmt.setdefault(instr.offset, set()).add( - "\n%s: %s\n%s" % (expr, c_str, c_type)) + "\n%s: %s\n%s" % (expr, c_str, c_type) + ) self.eval_updt_assignblk(assignblk) - for offset, value in offset2cmt.iteritems(): + for offset, value in viewitems(offset2cmt): idc.MakeComm(offset, '\n'.join(value)) - print "%x\n" % offset, '\n'.join(value) + print("%x\n" % offset, '\n'.join(value)) return self.eval_expr(self.ir_arch.IRDst) @@ -222,11 +226,11 @@ def get_ira_call_fixer(ira): class iraCallStackFixer(ira): def call_effects(self, ad, instr): - print hex(instr.offset), instr + print(hex(instr.offset), instr) stk_before = idc.GetSpd(instr.offset) stk_after = idc.GetSpd(instr.offset + instr.l) stk_diff = stk_after - stk_before - print hex(stk_diff) + print(hex(stk_diff)) call_assignblk = AssignBlock( [ ExprAssign(self.ret_reg, ExprOp('call_func_ret', ad)), @@ -299,8 +303,8 @@ def analyse_function(): ) ctype = mychandler.types_mngr.types_ast.ast_parse_declaration(ast.ext[0]) objc = types_mngr.get_objc(ctype) - print '=' * 20 - print expr, objc + print('=' * 20) + print(expr, objc) infos_types[expr] = set([objc]) # Add fake head @@ -344,7 +348,7 @@ def analyse_function(): symbexec_engine.get_state() ) - for lbl, state in states.iteritems(): + for lbl, state in viewitems(states): if lbl not in ircfg.blocks: continue symbexec_engine = CTypeEngineFixer(ir_arch, types_mngr, state, cst_propag_link) diff --git a/example/ida/depgraph.py b/example/ida/depgraph.py index 2c79c05d..3de19cbc 100644 --- a/example/ida/depgraph.py +++ b/example/ida/depgraph.py @@ -1,11 +1,17 @@ +from __future__ import print_function +from builtins import map +from builtins import range import os import tempfile +from future.utils import viewitems, viewvalues + import idautils import idc import ida_funcs import ida_kernwin + from miasm2.core.bin_stream_ida import bin_stream_ida from miasm2.core.asmblock import * from miasm2.expression import expression as m2_expr @@ -23,12 +29,13 @@ class depGraphSettingsForm(ida_kernwin.Form): self.ira = ira self.ircfg = ircfg - self.stk_args = {'ARG%d' % i:i for i in xrange(10)} + self.stk_args = {'ARG%d' % i:i for i in range(10)} self.stk_unalias_force = False self.address = idc.ScreenEA() cur_block = None - for block in ircfg.getby_offset(self.address): + for loc_key in ircfg.getby_offset(self.address): + block = ircfg.get_block(loc_key) offset = self.ircfg.loc_db.get_location_offset(block.loc_key) if offset is not None: # Only one block non-generated @@ -41,11 +48,11 @@ class depGraphSettingsForm(ida_kernwin.Form): break assert line_nb is not None cur_loc_key = str(cur_block.loc_key) - loc_keys = sorted(map(str, ircfg.blocks.keys())) - regs = sorted(ira.arch.regs.all_regs_ids_byname.keys()) - regs += self.stk_args.keys() + loc_keys = sorted(map(str, ircfg.blocks)) + regs = sorted(ira.arch.regs.all_regs_ids_byname) + regs += list(self.stk_args) reg_default = regs[0] - for i in xrange(10): + for i in range(10): opnd = idc.GetOpnd(self.address, i).upper() if opnd in regs: reg_default = opnd @@ -121,7 +128,7 @@ Method to use: line = self.ircfg.blocks[self.loc_key][self.line_nb].instr arg_num = self.stk_args[value] stk_high = m2_expr.ExprInt(idc.GetSpd(line.offset), ir_arch.sp.size) - stk_off = m2_expr.ExprInt(self.ira.sp.size/8 * arg_num, ir_arch.sp.size) + stk_off = m2_expr.ExprInt(self.ira.sp.size // 8 * arg_num, ir_arch.sp.size) element = m2_expr.ExprMem(mn.regs.regs_init[ir_arch.sp] + stk_high + stk_off, self.ira.sp.size) element = expr_simp(element) # Force stack unaliasing @@ -162,33 +169,33 @@ def treat_element(): global graphs, comments, sol_nb, settings, addr, ir_arch, ircfg try: - graph = graphs.next() + graph = next(graphs) except StopIteration: comments = {} - print "Done: %d solutions" % (sol_nb) + print("Done: %d solutions" % (sol_nb)) return sol_nb += 1 - print "Get graph number %02d" % sol_nb + print("Get graph number %02d" % sol_nb) filename = os.path.join(tempfile.gettempdir(), "solution_0x%08x_%02d.dot" % (addr, sol_nb)) - print "Dump the graph to %s" % filename + print("Dump the graph to %s" % filename) open(filename, "w").write(graph.graph.dot()) for node in graph.relevant_nodes: try: offset = ircfg.blocks[node.loc_key][node.line_nb].instr.offset except IndexError: - print "Unable to highlight %s" % node + print("Unable to highlight %s" % node) continue comments[offset] = comments.get(offset, []) + [node.element] idc.SetColor(offset, idc.CIC_ITEM, settings.color) if graph.has_loop: - print 'Graph has dependency loop: symbolic execution is inexact' + print('Graph has dependency loop: symbolic execution is inexact') else: - print "Possible value: %s" % graph.emul(ir_arch).values()[0] + print("Possible value: %s" % next(iter(viewvalues(graph.emul(ir_arch))))) - for offset, elements in comments.iteritems(): + for offset, elements in viewitems(comments): idc.MakeComm(offset, ", ".join(map(str, elements))) def next_element(): @@ -228,7 +235,7 @@ def launch_depgraph(): loc_key, elements, line_nb = settings.loc_key, settings.elements, settings.line_nb # Simplify assignments - for irb in ircfg.blocks.values(): + for irb in list(viewvalues(ircfg.blocks)): irs = [] offset = ir_arch.loc_db.get_location_offset(irb.loc_key) fix_stack = offset is not None and settings.unalias_stack @@ -238,7 +245,7 @@ def launch_depgraph(): fix_dct = {ir_arch.sp: mn.regs.regs_init[ir_arch.sp] + stk_high} new_assignblk = {} - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): if fix_stack: src = src.replace_expr(fix_dct) if dst != ir_arch.sp: diff --git a/example/ida/graph_ir.py b/example/ida/graph_ir.py index 8026174d..de46c22d 100644 --- a/example/ida/graph_ir.py +++ b/example/ida/graph_ir.py @@ -1,11 +1,16 @@ +from __future__ import print_function import os import tempfile +from builtins import int as int_types + +from future.utils import viewitems, viewvalues import idaapi import ida_kernwin import idc import ida_funcs import idautils + from miasm2.core.asmblock import is_int from miasm2.core.bin_stream_ida import bin_stream_ida from miasm2.expression.simplifications import expr_simp @@ -89,9 +94,9 @@ def label_init(self, name="", offset=None): def label_str(self): - if isinstance(self.offset, (int, long)): + if isinstance(self.offset, int_types): return "%s:0x%x" % (self.name, self.offset) - return "%s:%s" % (self.name, str(self.offset)) + return "%s:%s" % (self.name, self.offset) def color_irblock(irblock, ir_arch): @@ -99,7 +104,7 @@ def color_irblock(irblock, ir_arch): lbl = idaapi.COLSTR("%s:" % ir_arch.loc_db.pretty_str(irblock.loc_key), idaapi.SCOLOR_INSN) out.append(lbl) for assignblk in irblock: - for dst, src in sorted(assignblk.iteritems()): + for dst, src in sorted(viewitems(assignblk)): dst_f = expr2colorstr(dst, loc_db=ir_arch.loc_db) src_f = expr2colorstr(src, loc_db=ir_arch.loc_db) line = idaapi.COLSTR("%s = %s" % (dst_f, src_f), idaapi.SCOLOR_INSN) @@ -120,11 +125,11 @@ class GraphMiasmIR(idaapi.GraphViewer): def OnRefresh(self): self.Clear() addr_id = {} - for irblock in self.ircfg.blocks.values(): + for irblock in viewvalues(self.ircfg.blocks): id_irblock = self.AddNode(color_irblock(irblock, self.ircfg)) addr_id[irblock] = id_irblock - for irblock in self.ircfg.blocks.values(): + for irblock in viewvalues(self.ircfg.blocks): if not irblock: continue all_dst = self.ircfg.dst_trackback(irblock) @@ -164,7 +169,7 @@ def is_addr_ro_variable(bs, addr, size): """ try: - _ = bs.getbytes(addr, size/8) + _ = bs.getbytes(addr, size // 8) except IOError: return False return True @@ -183,18 +188,18 @@ def build_graph(start_addr, type_graph, simplify=False, dontmodstack=True, loadi for assignblk in assignblks: dct = dict(assignblk) dct = { - dst:src for (dst, src) in dct.iteritems() if dst != self.sp + dst:src for (dst, src) in viewitems(dct) if dst != self.sp } out.append(AssignBlock(dct, assignblk.instr)) return out, extra if verbose: - print "Arch", dis_engine + print("Arch", dis_engine) fname = idc.GetInputFile() if verbose: - print fname + print(fname) bs = bin_stream_ida() mdis = dis_engine(bs) @@ -212,28 +217,28 @@ def build_graph(start_addr, type_graph, simplify=False, dontmodstack=True, loadi mdis.loc_db.add_location(name, addr) if verbose: - print "start disasm" + print("start disasm") if verbose: - print hex(start_addr) + print(hex(start_addr)) asmcfg = mdis.dis_multiblock(start_addr) entry_points = set([mdis.loc_db.get_offset_location(start_addr)]) if verbose: - print "generating graph" + print("generating graph") open('asm_flow.dot', 'w').write(asmcfg.dot()) - print "generating IR... %x" % start_addr + print("generating IR... %x" % start_addr) ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg) if verbose: - print "IR ok... %x" % start_addr + print("IR ok... %x" % start_addr) - for irb in ircfg.blocks.itervalues(): + for irb in list(viewvalues(ircfg.blocks)): irs = [] for assignblk in irb: new_assignblk = { expr_simp(dst): expr_simp(src) - for dst, src in assignblk.iteritems() + for dst, src in viewitems(assignblk) } irs.append(AssignBlock(new_assignblk, instr=assignblk.instr)) ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs) @@ -268,7 +273,7 @@ def build_graph(start_addr, type_graph, simplify=False, dontmodstack=True, loadi continue if reg in regs_todo: out[reg] = dst - return set(out.values()) + return set(viewvalues(out)) diff --git a/example/ida/rpyc_ida.py b/example/ida/rpyc_ida.py index 21faf43a..6c18fb7a 100644 --- a/example/ida/rpyc_ida.py +++ b/example/ida/rpyc_ida.py @@ -1,4 +1,5 @@ """rpyc IDA server""" +from __future__ import print_function from rpyc.utils.server import OneShotServer from rpyc.core import SlaveService @@ -11,7 +12,7 @@ def serve_threaded(hostname="localhost", port=4455): WARNING: IDA will be locked until the client script terminates. """ - print 'Running server' + print('Running server') server = OneShotServer(SlaveService, hostname=hostname, port=port, reuse_addr=True, ipv6=False, authenticator=None, diff --git a/example/ida/symbol_exec.py b/example/ida/symbol_exec.py index e004b1b6..aa1d57fe 100644 --- a/example/ida/symbol_exec.py +++ b/example/ida/symbol_exec.py @@ -1,7 +1,12 @@ +from __future__ import print_function import operator +from future.utils import viewitems + import idaapi import idc + + from miasm2.expression.expression_helper import Variables_Identifier from miasm2.expression.expression import ExprAssign @@ -49,10 +54,12 @@ class symbolicexec_t(idaapi.simplecustviewer_t): element = self.line2eq[linenum] expanded = Variables_Identifier(element[1], var_prefix="%s_v" % element[0]) - self.line2eq = self.line2eq[0:linenum] + \ - expanded.vars.items() + \ - [(element[0], expanded.equation)] + \ + self.line2eq = ( + self.line2eq[0:linenum] + + list(viewitems(expanded.vars)) + + [(element[0], expanded.equation)] + self.line2eq[linenum + 1:] + ) def print_lines(self): self.ClearLines() @@ -75,7 +82,7 @@ class symbolicexec_t(idaapi.simplecustviewer_t): self.machine = machine self.loc_db = loc_db - self.line2eq = sorted(equations.items(), key=operator.itemgetter(0)) + self.line2eq = sorted(viewitems(equations), key=operator.itemgetter(0)) self.lines_expanded = set() self.print_lines() @@ -144,7 +151,7 @@ def symbolic_exec(): ira = machine.ira(loc_db=mdis.loc_db) ircfg = ira.new_ircfg_from_asmcfg(asmcfg) - print "Run symbolic execution..." + print("Run symbolic execution...") sb = SymbolicExecutionEngine(ira, machine.mn.regs.regs_init) sb.run_at(ircfg, start) modified = {} @@ -192,7 +199,7 @@ if __name__ == '__main__': idaapi.CompileLine('static key_F3() { RunPythonStatement("symbolic_exec()"); }') idc.AddHotkey("F3", "key_F3") - print "=" * 50 - print """Available commands: + print("=" * 50) + print("""Available commands: symbolic_exec() - F3: Symbolic execution of current selection - """ + """) diff --git a/example/ida/utils.py b/example/ida/utils.py index a64973f1..b6d5dac4 100644 --- a/example/ida/utils.py +++ b/example/ida/utils.py @@ -1,3 +1,5 @@ +from __future__ import print_function +from builtins import map import idaapi from idc import * @@ -67,7 +69,7 @@ def guess_machine(addr=None): elif processor_name == "PPC": machine = Machine("ppc32b") else: - print repr(processor_name) + print(repr(processor_name)) raise NotImplementedError('not fully functional') return machine @@ -204,7 +206,7 @@ Python Expression dest_lang = self.languages[self.GetControlValue(self.cbLanguage)] try: text = Translator.to_language(dest_lang).from_expr(self.expr) - except Exception, error: + except Exception as error: self.ShowField(self.result, False) return -1 diff --git a/example/jitter/arm.py b/example/jitter/arm.py index e475abeb..86772874 100755 --- a/example/jitter/arm.py +++ b/example/jitter/arm.py @@ -1,5 +1,6 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from __future__ import print_function import logging from pdb import pm @@ -22,7 +23,7 @@ else: logging.basicConfig(level=logging.WARNING) if options.verbose is True: - print sb.jitter.vm + print(sb.jitter.vm) # Run the code sb.run() diff --git a/example/jitter/arm_sc.py b/example/jitter/arm_sc.py index 7720ad68..b81d3784 100755 --- a/example/jitter/arm_sc.py +++ b/example/jitter/arm_sc.py @@ -1,5 +1,6 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from miasm2.core.utils import int_to_byte from miasm2.analysis.sandbox import Sandbox_Linux_armb_str from miasm2.analysis.sandbox import Sandbox_Linux_arml_str from elfesteem.strpatchwork import StrPatchwork @@ -35,8 +36,8 @@ stop = sb.jitter.cpu.R1 s = sb.jitter.vm.get_mem(start, stop-start) s = StrPatchwork(s) for i, c in enumerate(s): - s[i] = chr(ord(c)^0x11) -s = str(s) -assert(s == "test string\x00") + s[i] = int_to_byte(ord(c)^0x11) +s = bytes(s) +assert(s == b"test string\x00") diff --git a/example/jitter/example_types.py b/example/jitter/example_types.py index bcf9bf70..d0751bbd 100755 --- a/example/jitter/example_types.py +++ b/example/jitter/example_types.py @@ -4,7 +4,9 @@ For a more complete view of what is possible, tests/core/types.py covers most of the module possibilities, and the module doc gives useful information as well. """ +from __future__ import print_function +from miasm2.core.utils import iterbytes from miasm2.analysis.machine import Machine from miasm2.core.types import MemStruct, Self, Void, Str, Array, Ptr, \ Num, Array, set_allocator @@ -145,9 +147,9 @@ class DataStr(MemStruct): ] -print "This script demonstrates a LinkedList implementation using the types " -print "module in the first part, and how to play with some casts in the second." -print +print("This script demonstrates a LinkedList implementation using the types ") +print("module in the first part, and how to play with some casts in the second.") +print() # A random jitter # You can also use miasm2.jitter.VmMngr.Vm(), but it does not happen in real @@ -172,17 +174,17 @@ assert link.size == 3 # If you get it directly from the VM, it is updated as well raw_size = vm.get_mem(link.get_addr("size"), link.get_type() .get_field_type("size").size) -assert raw_size == '\x03\x00\x00\x00' +assert raw_size == b'\x03\x00\x00\x00' -print "The linked list just built:" -print repr(link), '\n' +print("The linked list just built:") +print(repr(link), '\n') -print "Its uninitialized data elements:" +print("Its uninitialized data elements:") for data in link: # __iter__ returns MemVoids here, just cast them to the real data type real_data = data.cast(DataArray) - print repr(real_data) -print + print(repr(real_data)) +print() # Now let's play with one data data = link.pop(DataArray) @@ -196,9 +198,9 @@ assert data.arrayptr.deref == data.array # Let's say that it is a DataStr: datastr = data.cast(DataStr) -print "First element casted to DataStr:" -print repr(datastr) -print +print("First element casted to DataStr:") +print(repr(datastr)) +print() # data and datastr really share the same memory: data.val1 = 0x34 @@ -212,29 +214,29 @@ memstr = datastr.data.deref # Note that memstr is Str("utf16") memstr.val = 'Miams' -print "Cast data.array to MemStr and set the string value:" -print repr(memstr) -print +print("Cast data.array to MemStr and set the string value:") +print(repr(memstr)) +print() # If you followed, memstr and data.array point to the same object, so: -raw_miams = '\x00'.join('Miams') + '\x00'*3 -raw_miams_array = [ord(c) for c in raw_miams] +raw_miams = 'Miams'.encode('utf-16le') + b'\x00'*2 +raw_miams_array = [ord(c) for c in iterbytes(raw_miams)] assert list(data.array)[:len(raw_miams_array)] == raw_miams_array assert data.array.cast(Str("utf16")) == memstr # Default is "ansi" assert data.array.cast(Str()) != memstr assert data.array.cast(Str("utf16")).val == memstr.val -print "See that the original array has been modified:" -print repr(data) -print +print("See that the original array has been modified:") +print(repr(data)) +print() # Some type manipulation examples, for example let's construct an argv for # a program: # Let's say that we have two arguments, +1 for the program name and +1 for the # final null ptr in argv, the array has 4 elements: argv_t = Array(Ptr("<I", Str()), 4) -print "3 arguments argv type:", argv_t +print("3 arguments argv type:", argv_t) # alloc argv somewhere argv = argv_t.lval(vm) @@ -249,10 +251,10 @@ argv[3].val = 0 # If you changed your mind on the second arg, you could do: argv[2].deref.val = "42" -print "An argv instance:", repr(argv) -print "argv values:", repr([val.deref.val for val in argv[:-1]]) -print +print("An argv instance:", repr(argv)) +print("argv values:", repr([val.deref.val for val in argv[:-1]])) +print() -print "See test/core/types.py and the miasm2.core.types module doc for " -print "more information." +print("See test/core/types.py and the miasm2.core.types module doc for ") +print("more information.") diff --git a/example/jitter/mips32.py b/example/jitter/mips32.py index 70181a2a..2eb06c87 100755 --- a/example/jitter/mips32.py +++ b/example/jitter/mips32.py @@ -1,5 +1,6 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from __future__ import print_function from argparse import ArgumentParser from miasm2.analysis import debugging from miasm2.jitter.csts import * @@ -44,12 +45,16 @@ def jit_mips32_binary(args): trace_new_blocks=args.log_newbloc ) - myjit.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, open(filepath).read()) + myjit.vm.add_memory_page( + 0, + PAGE_READ | PAGE_WRITE, + open(filepath, 'rb').read() + ) myjit.add_breakpoint(0x1337BEEF, code_sentinelle) # for stack - myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, "\x00"*0x1000) + myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, b"\x00"*0x1000) myjit.cpu.SP = 0xF800 diff --git a/example/jitter/msp430.py b/example/jitter/msp430.py index 36e45421..1ecb4cef 100755 --- a/example/jitter/msp430.py +++ b/example/jitter/msp430.py @@ -1,5 +1,6 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from __future__ import print_function from argparse import ArgumentParser from miasm2.analysis import debugging from miasm2.jitter.csts import * @@ -39,12 +40,16 @@ def jit_msp430_binary(args): trace_new_blocks=args.log_newbloc ) - myjit.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, open(filepath, "rb").read()) + myjit.vm.add_memory_page( + 0, + PAGE_READ | PAGE_WRITE, + open(filepath, "rb").read() + ) myjit.add_breakpoint(0x1337, lambda _: exit(0)) # for stack - myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, "\x00"*0x1000) + myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, b"\x00"*0x1000) myjit.cpu.SP = 0xF800 diff --git a/example/jitter/run_with_linuxenv.py b/example/jitter/run_with_linuxenv.py index f4900a96..fda76f9a 100644 --- a/example/jitter/run_with_linuxenv.py +++ b/example/jitter/run_with_linuxenv.py @@ -24,8 +24,8 @@ if args.verbose: syscall.log.setLevel(logging.DEBUG) # Get corresponding interpreter and reloc address -cont_target_tmp = Container.from_stream(open(args.target)) -ld_path = str(cont_target_tmp.executable.getsectionbyname(".interp").content).strip("\x00") +cont_target_tmp = Container.from_stream(open(args.target, 'rb')) +ld_path = bytes(cont_target_tmp.executable.getsectionbyname(".interp").content).strip(b"\x00") if cont_target_tmp.executable.Ehdr.type in [elf_csts.ET_REL, elf_csts.ET_DYN]: elf_base_addr = 0x40000000 elif cont_target_tmp.executable.Ehdr.type == elf_csts.ET_EXEC: @@ -52,29 +52,38 @@ else: # Load the interpreter in memory, applying relocation linux_env = LinuxEnvironment() -linux_env.filesystem.passthrough.append(re.compile(args.passthrough)) +linux_env.filesystem.passthrough.append(re.compile(args.passthrough.encode())) ld_path = linux_env.filesystem.resolve_path(ld_path) -cont_ld = Container.from_stream(open(ld_path), - vm=jitter.vm, - addr=0x80000000, - apply_reloc=True) +cont_ld = Container.from_stream( + open(ld_path, "rb"), + vm=jitter.vm, + addr=0x80000000, + apply_reloc=True +) # Load the target ELF in memory, without applying reloc loc_db = cont_ld.loc_db -cont_target = Container.from_stream(open(args.target), vm=jitter.vm, - loc_db=loc_db, - addr=elf_base_addr, - apply_reloc=False) +cont_target = Container.from_stream( + open(args.target, "rb"), + vm=jitter.vm, + loc_db=loc_db, + addr=elf_base_addr, + apply_reloc=False +) # PHDR containing the PH header -elf_phdr_header = [ph32.ph for ph32 in cont_target.executable.ph - if ph32.ph.type == elf_csts.PT_PHDR][0] +elf_phdr_header = next( + ph32.ph for ph32 in cont_target.executable.ph + if ph32.ph.type == elf_csts.PT_PHDR +) # Prepare the desired environment -argv = [args.target] + args.extra_args +argv = [args.target.encode()] + [arg.encode() for arg in args.extra_args] if args.flags: argv += ["-%s" % args.flags] -envp = {"PATH": "/usr/local/bin", "USER": linux_env.user_name} -auxv = environment.AuxVec(elf_base_addr + elf_phdr_header.vaddr, - cont_target.entry_point, linux_env) +envp = {b"PATH": b"/usr/local/bin", b"USER": linux_env.user_name} +auxv = environment.AuxVec( + elf_base_addr + elf_phdr_header.vaddr, + cont_target.entry_point, linux_env +) prepare_loader(jitter, argv, envp, auxv, linux_env) syscall.enable_syscall_handling(jitter, linux_env, syscall_callbacks) diff --git a/example/jitter/sandbox_elf_ppc32.py b/example/jitter/sandbox_elf_ppc32.py index c5960e8e..04ecfd9e 100644 --- a/example/jitter/sandbox_elf_ppc32.py +++ b/example/jitter/sandbox_elf_ppc32.py @@ -5,12 +5,6 @@ from miasm2.jitter.csts import * from miasm2.jitter.jitload import log_func import logging - -# Python auto completion -filename = os.environ.get('PYTHONSTARTUP') -if filename and os.path.isfile(filename): - execfile(filename) - # Insert here user defined methods # Parse arguments diff --git a/example/jitter/trace.py b/example/jitter/trace.py index e1683450..9f025bfd 100644 --- a/example/jitter/trace.py +++ b/example/jitter/trace.py @@ -6,6 +6,8 @@ This example demonstrates two instrumentation possibility: Note: for better performance, one can also extend Codegen to produce instrumentation at the C / LLVM level """ +from __future__ import print_function + import os import time from pdb import pm @@ -26,11 +28,11 @@ class ESETrackMemory(EmulatedSymbExec): def mem_read(self, expr_mem): value = super(ESETrackMemory, self).mem_read(expr_mem) - print "Read %s: %s" % (expr_mem, value) + print("Read %s: %s" % (expr_mem, value)) return value def mem_write(self, dest, data): - print "Write %s: %s" % (dest, data) + print("Write %s: %s" % (dest, data)) return super(ESETrackMemory, self).mem_write(dest, data) # Parse arguments @@ -55,4 +57,4 @@ sb.run() stop_time = time.time() assert sb.jitter.run is False -print "Instr speed: %02.f / sec" % (instr_count / (stop_time - start_time)) +print("Instr speed: %02.f / sec" % (instr_count / (stop_time - start_time))) diff --git a/example/jitter/unpack_upx.py b/example/jitter/unpack_upx.py index 6bcef1ab..5d862dd1 100644 --- a/example/jitter/unpack_upx.py +++ b/example/jitter/unpack_upx.py @@ -1,3 +1,4 @@ +from __future__ import print_function import os import logging from pdb import pm @@ -12,12 +13,12 @@ def kernel32_GetProcAddress(jitter): # When the function is called, EBX is a pointer to the destination buffer dst_ad = jitter.cpu.EBX - logging.info('EBX ' + hex(dst_ad)) + logging.error('EBX ' + hex(dst_ad)) # Handle ordinal imports fname = (args.fname if args.fname < 0x10000 else jitter.get_str_ansi(args.fname)) - logging.info(fname) + logging.error(fname) # Get the generated address of the library, and store it in memory to # dst_ad @@ -38,6 +39,7 @@ parser.add_argument("--graph", action="store_true") options = parser.parse_args() options.load_hdr = True + sb = Sandbox_Win_x86_32(options.filename, options, globals(), parse_reloc=False) @@ -48,7 +50,7 @@ else: logging.basicConfig(level=logging.WARNING) if options.verbose is True: - print sb.jitter.vm + print(sb.jitter.vm) # Ensure there is one and only one leave (for OEP discovering) mdis = sb.machine.dis_engine(sb.jitter.bs) @@ -70,7 +72,7 @@ if options.graph is True: if options.verbose is True: - print sb.jitter.vm + print(sb.jitter.vm) def update_binary(jitter): @@ -114,4 +116,4 @@ sb.pe.NThdr.optentries[pe.DIRECTORY_ENTRY_DELAY_IMPORT].rva = 0 bname, fname = os.path.split(options.filename) fname = os.path.join(bname, fname.replace('.', '_')) -open(fname + '_unupx.bin', 'w').write(str(sb.pe)) +open(fname + '_unupx.bin', 'wb').write(bytes(sb.pe)) diff --git a/example/jitter/x86_32.py b/example/jitter/x86_32.py index 5272f732..2a73a2ad 100644 --- a/example/jitter/x86_32.py +++ b/example/jitter/x86_32.py @@ -20,7 +20,7 @@ def code_sentinelle(jitter): myjit = Machine("x86_32").jitter(args.jitter) myjit.init_stack() -data = open(args.filename).read() +data = open(args.filename, 'rb').read() run_addr = 0x40000000 myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) diff --git a/example/symbol_exec/depgraph.py b/example/symbol_exec/depgraph.py index 260d62ab..c1dbd422 100644 --- a/example/symbol_exec/depgraph.py +++ b/example/symbol_exec/depgraph.py @@ -1,7 +1,11 @@ +from __future__ import print_function +from builtins import range from argparse import ArgumentParser from pdb import pm import json +from future.utils import viewitems + from miasm2.analysis.machine import Machine from miasm2.analysis.binary import Container from miasm2.analysis.depgraph import DependencyGraph @@ -54,7 +58,7 @@ init_ctx = {} if args.rename_args: if arch == "x86_32": # StdCall example - for i in xrange(4): + for i in range(4): e_mem = ExprMem(ExprId("ESP_init", 32) + ExprInt(4 * (i + 1), 32), 32) init_ctx[e_mem] = ExprId("arg%d" % i, 32) @@ -74,8 +78,9 @@ dg = DependencyGraph( # Build information target_addr = int(args.target_addr, 0) -current_block = list(ircfg.getby_offset(target_addr))[0] +current_loc_key = next(iter(ircfg.getby_offset(target_addr))) assignblk_index = 0 +current_block = ircfg.get_block(current_loc_key) for assignblk_index, assignblk in enumerate(current_block): if assignblk.instr.offset == target_addr: break @@ -88,14 +93,14 @@ for sol_nb, sol in enumerate(dg.get(current_block.loc_key, elements, assignblk_i fdesc.write(sol.graph.dot()) results = sol.emul(ir_arch, ctx=init_ctx) - tokens = {str(k): str(v) for k, v in results.iteritems()} + tokens = {str(k): str(v) for k, v in viewitems(results)} if not args.json: - result = ", ".join("=".join(x) for x in tokens.iteritems()) - print "Solution %d: %s -> %s" % (sol_nb, + result = ", ".join("=".join(x) for x in viewitems(tokens)) + print("Solution %d: %s -> %s" % (sol_nb, result, - fname) + fname)) if sol.has_loop: - print '\tLoop involved' + print('\tLoop involved') if args.implicit: sat = sol.is_satisfiable @@ -109,10 +114,12 @@ for sol_nb, sol in enumerate(dg.get(current_block.loc_key, elements, assignblk_i constraints[element] = result if args.json: tokens["satisfiability"] = sat - tokens["constraints"] = {str(k): str(v) - for k, v in constraints.iteritems()} + tokens["constraints"] = { + str(k): str(v) + for k, v in viewitems(constraints) + } else: - print "\tSatisfiability: %s %s" % (sat, constraints) + print("\tSatisfiability: %s %s" % (sat, constraints)) if args.json: tokens["has_loop"] = sol.has_loop @@ -120,4 +127,4 @@ for sol_nb, sol in enumerate(dg.get(current_block.loc_key, elements, assignblk_i if args.json: - print json.dumps(json_solutions) + print(json.dumps(json_solutions)) diff --git a/example/symbol_exec/dse_crackme.py b/example/symbol_exec/dse_crackme.py index 37700d75..33ec3b72 100644 --- a/example/symbol_exec/dse_crackme.py +++ b/example/symbol_exec/dse_crackme.py @@ -4,15 +4,19 @@ This example should run on the compiled ELF x86 64bits version of "dse_crackme.c" """ +from __future__ import print_function #### This part is only related to the run of the sample, without DSE #### +from builtins import range import os import subprocess import platform from collections import namedtuple from pdb import pm from tempfile import NamedTemporaryFile +from future.utils import viewitems +from miasm2.core.utils import int_to_byte from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE from miasm2.analysis.sandbox import Sandbox_Linux_x86_64 from miasm2.expression.expression import * @@ -81,8 +85,11 @@ FS_0_ADDR = 0x7ff70000 sb.jitter.cpu.FS = 0x4 sb.jitter.cpu.set_segm_base(sb.jitter.cpu.FS, FS_0_ADDR) sb.jitter.vm.add_memory_page( - FS_0_ADDR + 0x28, PAGE_READ, "\x42\x42\x42\x42\x42\x42\x42\x42", - "Stack canary FS[0x28]") + FS_0_ADDR + 0x28, + PAGE_READ, + b"\x42\x42\x42\x42\x42\x42\x42\x42", + "Stack canary FS[0x28]" +) # Prepare the execution sb.jitter.init_run(sb.entry_point) @@ -108,7 +115,7 @@ class SymbolicFile(object): def read(self, length): assert self.state == "OPEN" out = [] - for i in xrange(self.position, min(self.position + length, + for i in range(self.position, min(self.position + length, self.max_size)): if i not in self.gen_bytes: ret = ExprId("SF_%08x_%d" % (id(self), i), 8) @@ -220,7 +227,7 @@ def xxx_puts_symb(dse): raise FinishOn(string) -todo = set([""]) # Set of file content to test +todo = set([b""]) # Set of file content to test # Instantiate the DSE engine machine = Machine("x86_64") @@ -262,7 +269,7 @@ found = False while todo: # Prepare a solution to try, based on the clean state file_content = todo.pop() - print "CUR: %r" % file_content + print("CUR: %r" % file_content) open(TEMP_FILE.name, "wb").write(file_content) dse.restore_snapshot(snapshot, keep_known_solutions=True) FILE_to_info.clear() @@ -272,38 +279,38 @@ while todo: try: sb.run() except FinishOn as finish_info: - print finish_info.string - if finish_info.string == "OK": + print(finish_info.string) + if finish_info.string == b"OK": # Stop if the expected result is found found = True break finfo = FILE_to_info_symb[FILE_stream] - for sol_ident, model in dse.new_solutions.iteritems(): + for sol_ident, model in viewitems(dse.new_solutions): # Build the file corresponding to solution in 'model' - out = "" + out = [] fsize = max(model.eval(dse.z3_trans.from_expr(FILE_size)).as_long(), len(finfo.gen_bytes)) - for index in xrange(fsize): + for index in range(fsize): try: byteid = finfo.gen_bytes[index] - out += chr(model.eval(dse.z3_trans.from_expr(byteid)).as_long()) + out.append(int_to_byte(model.eval(dse.z3_trans.from_expr(byteid)).as_long())) except (KeyError, AttributeError) as _: # Default value if there is no constraint on current byte - out += "\x00" + out.append(b"\x00") - todo.add(out) + todo.add(b"".join(out)) # Assert that the result has been found assert found == True -print "FOUND !" +print("FOUND !") TEMP_FILE.close() # Replay for real if not is_win: - print "Trying to launch the binary without Miasm" + print("Trying to launch the binary without Miasm") crackme = subprocess.Popen([options.filename, TEMP_FILE.name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -311,8 +318,8 @@ if not is_win: assert not stderr os.unlink(TEMP_FILE.name) stdout = stdout.strip() - print stdout - assert stdout == "OK" + print(stdout) + assert stdout == b"OK" else: os.unlink(TEMP_FILE.name) diff --git a/example/symbol_exec/dse_strategies.py b/example/symbol_exec/dse_strategies.py index b38c797a..8e479d61 100644 --- a/example/symbol_exec/dse_strategies.py +++ b/example/symbol_exec/dse_strategies.py @@ -17,8 +17,11 @@ Global overview: - Ask the DSE for new candidates, according to its strategy, ie. finding new block / branch / path """ +from __future__ import print_function from argparse import ArgumentParser +from future.utils import viewitems + from miasm2.analysis.machine import Machine from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE from miasm2.analysis.dse import DSEPathConstraint @@ -42,9 +45,13 @@ strategy = { run_addr = 0x40000 machine = Machine("x86_32") jitter = machine.jitter("python") -with open(args.filename) as fdesc: - jitter.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, fdesc.read(), - "Binary") +with open(args.filename, "rb") as fdesc: + jitter.vm.add_memory_page( + run_addr, + PAGE_READ | PAGE_WRITE, + fdesc.read(), + "Binary" + ) # Expect a binary with one argument on the stack jitter.init_stack() @@ -94,7 +101,7 @@ while todo: continue done.add(arg_value) - print "Run with ARG = %s" % arg_value + print("Run with ARG = %s" % arg_value) # Restore state, while keeping already found solutions dse.restore_snapshot(snapshot, keep_known_solutions=True) @@ -113,17 +120,21 @@ while todo: # - last edge for branch coverage # - execution path for path coverage - for sol_ident, model in dse.new_solutions.iteritems(): - print "Found a solution to reach: %s" % str(sol_ident) + for sol_ident, model in viewitems(dse.new_solutions): + print("Found a solution to reach: %s" % str(sol_ident)) # Get the argument to use as a Miasm Expr sol_value = model.eval(dse.z3_trans.from_expr(arg)).as_long() sol_expr = ExprInt(sol_value, arg.size) # Display info and update storages - print "\tARG = %s" % sol_expr + print("\tARG = %s" % sol_expr) todo.add(sol_expr) reaches.add(sol_ident) -print "Found %d input, to reach %d element of coverage" % (len(done), - len(reaches)) +print( + "Found %d input, to reach %d element of coverage" % ( + len(done), + len(reaches) + ) +) diff --git a/example/symbol_exec/single_instr.py b/example/symbol_exec/single_instr.py index 3b27a814..bdc65360 100644 --- a/example/symbol_exec/single_instr.py +++ b/example/symbol_exec/single_instr.py @@ -1,3 +1,4 @@ +from __future__ import print_function # Minimalist Symbol Exec example from miasm2.analysis.binary import Container from miasm2.analysis.machine import Machine @@ -32,9 +33,9 @@ symb = SymbolicExecutionEngine(ira) cur_addr = symb.run_at(ircfg, START_ADDR) # Modified elements -print 'Modified registers:' +print('Modified registers:') symb.dump(mems=False) -print 'Modified memory (should be empty):' +print('Modified memory (should be empty):') symb.dump(ids=False) # Check final status diff --git a/miasm2/analysis/binary.py b/miasm2/analysis/binary.py index 93bd74b2..ee733d79 100644 --- a/miasm2/analysis/binary.py +++ b/miasm2/analysis/binary.py @@ -46,7 +46,7 @@ class Container(object): return container_type(data, *args, **kwargs) except ContainerSignatureException: continue - except ContainerParsingException, error: + except ContainerParsingException as error: log.error(error) # Fallback mode @@ -134,7 +134,7 @@ class ContainerPE(Container): from elfesteem import pe_init # Parse signature - if not data.startswith('MZ'): + if not data.startswith(b'MZ'): raise ContainerSignatureException() # Build executable instance @@ -143,7 +143,7 @@ class ContainerPE(Container): self._executable = vm_load_pe(vm, data) else: self._executable = pe_init.PE(data) - except Exception, error: + except Exception as error: raise ContainerParsingException('Cannot read PE: %s' % error) # Check instance validity @@ -159,7 +159,7 @@ class ContainerPE(Container): self._bin_stream = bin_stream_pe(self._executable) ep_detected = self._executable.Opthdr.AddressOfEntryPoint self._entry_point = self._executable.rva2virt(ep_detected) - except Exception, error: + except Exception as error: raise ContainerParsingException('Cannot read PE: %s' % error) @@ -168,7 +168,7 @@ class ContainerELF(Container): def parse(self, data, vm=None, addr=0, apply_reloc=False, **kwargs): """Load an ELF from @data - @data: str containing the ELF bytes + @data: bytes containing the ELF bytes @vm (optional): VmMngr instance. If set, load the ELF in virtual memory @addr (optional): base address the ELF in virtual memory @apply_reloc (optional): if set, apply relocation during ELF loading @@ -181,18 +181,22 @@ class ContainerELF(Container): from elfesteem import elf_init # Parse signature - if not data.startswith('\x7fELF'): + if not data.startswith(b'\x7fELF'): raise ContainerSignatureException() # Build executable instance try: if vm is not None: - self._executable = vm_load_elf(vm, data, loc_db=self.loc_db, - base_addr=addr, - apply_reloc=apply_reloc) + self._executable = vm_load_elf( + vm, + data, + loc_db=self.loc_db, + base_addr=addr, + apply_reloc=apply_reloc + ) else: self._executable = elf_init.ELF(data) - except Exception, error: + except Exception as error: raise ContainerParsingException('Cannot read ELF: %s' % error) # Guess the architecture @@ -202,7 +206,7 @@ class ContainerELF(Container): try: self._bin_stream = bin_stream_elf(self._executable) self._entry_point = self._executable.Ehdr.entry + addr - except Exception, error: + except Exception as error: raise ContainerParsingException('Cannot read ELF: %s' % error) if vm is None: @@ -217,9 +221,11 @@ class ContainerUnknown(Container): def parse(self, data, vm=None, addr=0, **kwargs): self._bin_stream = bin_stream_str(data, base_address=addr) if vm is not None: - vm.add_memory_page(addr, - PAGE_READ, - data) + vm.add_memory_page( + addr, + PAGE_READ, + data + ) self._executable = None self._entry_point = 0 diff --git a/miasm2/analysis/cst_propag.py b/miasm2/analysis/cst_propag.py index 9a5e3d54..25d66318 100644 --- a/miasm2/analysis/cst_propag.py +++ b/miasm2/analysis/cst_propag.py @@ -1,5 +1,7 @@ import logging +from future.utils import viewitems + from miasm2.ir.symbexec import SymbolicExecutionEngine from miasm2.expression.expression import ExprMem from miasm2.expression.expression_helper import possible_values @@ -95,7 +97,7 @@ class SymbExecStateFix(SymbolicExecutionEngine): for index, assignblk in enumerate(irb): new_assignblk = {} links = {} - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): src = self.propag_expr_cst(src) if dst.is_mem(): ptr = dst.ptr @@ -175,7 +177,7 @@ def propagate_cst_expr(ir_arch, ircfg, addr, init_infos): """ states = compute_cst_propagation_states(ir_arch, ircfg, addr, init_infos) cst_propag_link = {} - for lbl, state in states.iteritems(): + for lbl, state in viewitems(states): if lbl not in ircfg.blocks: continue symbexec = SymbExecStateFix(ir_arch, ircfg, state, cst_propag_link) diff --git a/miasm2/analysis/data_analysis.py b/miasm2/analysis/data_analysis.py index 30346e63..bd073fcb 100644 --- a/miasm2/analysis/data_analysis.py +++ b/miasm2/analysis/data_analysis.py @@ -1,5 +1,12 @@ +from __future__ import print_function + +from future.utils import viewitems + +from builtins import object +from functools import cmp_to_key from miasm2.expression.expression \ - import get_expr_mem, get_list_rw, ExprId, ExprInt + import get_expr_mem, get_list_rw, ExprId, ExprInt, \ + compare_exprs from miasm2.ir.symbexec import SymbolicExecutionEngine @@ -19,7 +26,7 @@ def intra_block_flow_raw(ir_arch, ircfg, flow_graph, irb, in_nodes, out_nodes): # gen mem arg to mem node links all_mems = set() - for node_w, nodes_r in dict_rw.iteritems(): + for node_w, nodes_r in viewitems(dict_rw): for n in nodes_r.union([node_w]): all_mems.update(get_expr_mem(n)) if not all_mems: @@ -40,7 +47,7 @@ def intra_block_flow_raw(ir_arch, ircfg, flow_graph, irb, in_nodes, out_nodes): flow_graph.add_uniq_edge(node_n_r, node_n_w) # gen data flow links - for node_w, nodes_r in dict_rw.iteritems(): + for node_w, nodes_r in viewitems(dict_rw): for n_r in nodes_r: if n_r in current_nodes: node_n_r = current_nodes[n_r] @@ -65,11 +72,11 @@ def inter_block_flow_link(ir_arch, ircfg, flow_graph, irb_in_nodes, irb_out_node # link current nodes to bloc in_nodes if not lbl in ircfg.blocks: - print "cannot find bloc!!", lbl + print("cannot find bloc!!", lbl) return set() irb = ircfg.blocks[lbl] to_del = set() - for n_r, node_n_r in irb_in_nodes[irb.loc_key].items(): + for n_r, node_n_r in viewitems(irb_in_nodes[irb.loc_key]): if not n_r in current_nodes: continue flow_graph.add_uniq_edge(current_nodes[n_r], node_n_r) @@ -78,7 +85,7 @@ def inter_block_flow_link(ir_arch, ircfg, flow_graph, irb_in_nodes, irb_out_node # if link exec to data, all nodes depends on exec nodes if link_exec_to_data: for n_x_r in exec_nodes: - for n_r, node_n_r in irb_in_nodes[irb.loc_key].items(): + for n_r, node_n_r in viewitems(irb_in_nodes[irb.loc_key]): if not n_x_r in current_nodes: continue if isinstance(n_r, ExprInt): @@ -86,15 +93,15 @@ def inter_block_flow_link(ir_arch, ircfg, flow_graph, irb_in_nodes, irb_out_node flow_graph.add_uniq_edge(current_nodes[n_x_r], node_n_r) # update current nodes using bloc out_nodes - for n_w, node_n_w in irb_out_nodes[irb.loc_key].items(): + for n_w, node_n_w in viewitems(irb_out_nodes[irb.loc_key]): current_nodes[n_w] = node_n_w # get nodes involved in exec flow - x_nodes = tuple(sorted(list(irb.dst.get_r()))) + x_nodes = tuple(sorted(irb.dst.get_r(), key=cmp_to_key(compare_exprs))) todo = set() for lbl_dst in ircfg.successors(irb.loc_key): - todo.add((lbl_dst, tuple(current_nodes.items()), x_nodes)) + todo.add((lbl_dst, tuple(viewitems(current_nodes)), x_nodes)) return todo @@ -109,7 +116,7 @@ def create_implicit_flow(ir_arch, flow_graph, irb_in_nodes, irb_out_ndes): irb = ir_arch.blocks[lbl] for lbl_son in ir_arch.graph.successors(irb.loc_key): if not lbl_son in ir_arch.blocks: - print "cannot find bloc!!", lbl + print("cannot find bloc!!", lbl) continue irb_son = ir_arch.blocks[lbl_son] for n_r in irb_in_nodes[irb_son.loc_key]: @@ -144,7 +151,7 @@ def inter_block_flow(ir_arch, ircfg, flow_graph, irb_0, irb_in_nodes, irb_out_no todo.update(out) -class symb_exec_func: +class symb_exec_func(object): """ This algorithm will do symbolic execution on a function, trying to propagate @@ -164,15 +171,13 @@ class symb_exec_func: self.ir_arch = ir_arch def add_state(self, parent, ad, state): - variables = dict(state.symbols.items()) + variables = dict(state.symbols) # get bloc dead, and remove from state b = self.ir_arch.get_block(ad) if b is None: raise ValueError("unknown bloc! %s" % ad) - variables = variables.items() - - s = parent, ad, tuple(sorted(variables)) + s = parent, ad, tuple(sorted(viewitems(variables))) self.todo.add(s) def get_next_state(self): @@ -183,10 +188,10 @@ class symb_exec_func: if len(self.todo) == 0: return None if self.total_done > 600: - print "symbexec watchdog!" + print("symbexec watchdog!") return None self.total_done += 1 - print 'CPT', self.total_done + print('CPT', self.total_done) while self.todo: state = self.get_next_state() parent, ad, s = state diff --git a/miasm2/analysis/data_flow.py b/miasm2/analysis/data_flow.py index 2201a088..3874b21b 100644 --- a/miasm2/analysis/data_flow.py +++ b/miasm2/analysis/data_flow.py @@ -1,6 +1,8 @@ """Data flow analysis based on miasm intermediate representation""" - +from builtins import range from collections import namedtuple +from future.utils import viewitems, viewvalues +from miasm2.core.utils import encode_hex from miasm2.core.graph import DiGraph from miasm2.ir.ir import AssignBlock, IRBlock from miasm2.expression.expression import ExprLoc, ExprMem, ExprId, ExprInt,\ @@ -56,7 +58,7 @@ class ReachingDefinitions(dict): modified = True while modified: modified = False - for block in self.ircfg.blocks.itervalues(): + for block in viewvalues(self.ircfg.blocks): modified |= self.process_block(block) def process_block(self, block): @@ -67,7 +69,7 @@ class ReachingDefinitions(dict): predecessor_state = {} for pred_lbl in self.ircfg.predecessors(block.loc_key): pred = self.ircfg.blocks[pred_lbl] - for lval, definitions in self.get_definitions(pred_lbl, len(pred)).iteritems(): + for lval, definitions in viewitems(self.get_definitions(pred_lbl, len(pred))): predecessor_state.setdefault(lval, set()).update(definitions) modified = self.get((block.loc_key, 0)) != predecessor_state @@ -75,7 +77,7 @@ class ReachingDefinitions(dict): return False self[(block.loc_key, 0)] = predecessor_state - for index in xrange(len(block)): + for index in range(len(block)): modified |= self.process_assignblock(block, index) return modified @@ -151,7 +153,7 @@ class DiGraphDefUse(DiGraph): def _compute_def_use(self, reaching_defs, deref_mem=False): - for block in self._blocks.itervalues(): + for block in viewvalues(self._blocks): self._compute_def_use_block(block, reaching_defs, deref_mem=deref_mem) @@ -159,7 +161,7 @@ class DiGraphDefUse(DiGraph): def _compute_def_use_block(self, block, reaching_defs, deref_mem=False): for index, assignblk in enumerate(block): assignblk_reaching_defs = reaching_defs.get_definitions(block.loc_key, index) - for lval, expr in assignblk.iteritems(): + for lval, expr in viewitems(assignblk): self.add_node(AssignblkNode(block.loc_key, index, lval)) read_vars = expr.get_r(mem_read=deref_mem) @@ -212,7 +214,7 @@ def dead_simp_useful_assignblks(irarch, defuse, reaching_defs): ircfg = reaching_defs.ircfg useful = set() - for block_lbl, block in ircfg.blocks.iteritems(): + for block_lbl, block in viewitems(ircfg.blocks): successors = ircfg.successors(block_lbl) for successor in successors: if successor not in ircfg.blocks: @@ -225,14 +227,14 @@ def dead_simp_useful_assignblks(irarch, defuse, reaching_defs): if keep_all_definitions or (len(successors) == 0): valid_definitions = reaching_defs.get_definitions(block_lbl, len(block)) - for lval, definitions in valid_definitions.iteritems(): + for lval, definitions in viewitems(valid_definitions): if lval in irarch.get_out_regs(block) or keep_all_definitions: for definition in definitions: useful.add(AssignblkNode(definition[0], definition[1], lval)) # Force keeping of specific cases for index, assignblk in enumerate(block): - for lval, rval in assignblk.iteritems(): + for lval, rval in viewitems(assignblk): if (lval.is_mem() or irarch.IRDst == lval or lval.is_id("exception_flags") or @@ -262,7 +264,7 @@ def dead_simp(irarch, ircfg): reaching_defs = ReachingDefinitions(ircfg) defuse = DiGraphDefUse(reaching_defs, deref_mem=True) useful = set(dead_simp_useful_assignblks(irarch, defuse, reaching_defs)) - for block in ircfg.blocks.itervalues(): + for block in list(viewvalues(ircfg.blocks)): irs = [] for idx, assignblk in enumerate(block): new_assignblk = dict(assignblk) @@ -311,7 +313,7 @@ def _do_merge_blocks(ircfg, loc_key, son_loc_key): assignblks.append(assignblk) continue affs = {} - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): if dst != ircfg.IRDst: affs[dst] = src if affs: @@ -348,7 +350,7 @@ def _test_jmp_only(ircfg, loc_key, heads): irblock = ircfg.blocks[loc_key] if len(irblock.assignblks) != 1: return None - items = dict(irblock.assignblks[0]).items() + items = list(viewitems(dict(irblock.assignblks[0]))) if len(items) != 1: return None if len(ircfg.successors(loc_key)) != 1: @@ -528,7 +530,7 @@ def remove_empty_assignblks(ircfg): @ircfg: IRCFG instance """ modified = False - for loc_key, block in ircfg.blocks.iteritems(): + for loc_key, block in list(viewitems(ircfg.blocks)): irs = [] block_modified = False for assignblk in block: @@ -591,13 +593,13 @@ class SSADefUse(DiGraph): if block is None: continue for index, assignblk in enumerate(block): - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): node = AssignblkNode(lbl, index, dst) graph.add_var_def(node, src) graph.add_def_node(def_nodes, node, src) graph.add_use_node(use_nodes, node, src) - for dst, node in def_nodes.iteritems(): + for dst, node in viewitems(def_nodes): graph.add_node(node) if dst not in use_nodes: continue @@ -650,7 +652,7 @@ class PropagateThroughExprId(object): @assignblks: list of AssignBlock to check """ for assignblk in assignblks: - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): if src.is_function_call(): return True if dst.is_mem(): @@ -723,7 +725,7 @@ class PropagateThroughExprId(object): def_dct = {} for node in ircfg.nodes(): for index, assignblk in enumerate(ircfg.blocks[node]): - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): if not dst.is_id(): continue if dst in ssa.immutable_ids: @@ -786,7 +788,7 @@ class PropagateThroughExprId(object): """ node_to_reg, to_replace, defuse = self.get_candidates(ssa, head, max_expr_depth) modified = False - for node, reg in node_to_reg.iteritems(): + for node, reg in viewitems(node_to_reg): for successor in defuse.successors(node): if not self.propagation_allowed(ssa, to_replace, node, successor): continue @@ -800,7 +802,7 @@ class PropagateThroughExprId(object): assignblks = list(block) assignblk = block[node_b.index] out = {} - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): if src.is_op('Phi'): out[dst] = src continue @@ -874,16 +876,16 @@ class PropagateThroughExprMem(object): ircfg = ssa.graph todo = set() modified = False - for block in ircfg.blocks.itervalues(): + for block in viewvalues(ircfg.blocks): for i, assignblk in enumerate(block): - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): if not dst.is_mem(): continue if expr_has_mem(src): continue todo.add((block.loc_key, i + 1, dst, src)) ptr = dst.ptr - for size in xrange(8, dst.size, 8): + for size in range(8, dst.size, 8): todo.add((block.loc_key, i + 1, ExprMem(ptr, size), src[:size])) while todo: @@ -891,13 +893,13 @@ class PropagateThroughExprMem(object): block = ircfg.blocks[loc_key] assignblks = list(block) block_modified = False - for i in xrange(index, len(block)): + for i in range(index, len(block)): assignblk = block[i] write_mem = False assignblk_modified = False out = dict(assignblk) out_new = {} - for dst, src in out.iteritems(): + for dst, src in viewitems(out): if dst.is_mem(): write_mem = True ptr = dst.ptr.replace_expr({mem_dst:mem_src}) @@ -941,7 +943,7 @@ def stack_to_reg(expr): diff = int(ptr.args[1]) assert diff % 4 == 0 diff = (0 - diff) & 0xFFFFFFFF - return ExprId("STACK.%d" % (diff / 4), expr.size) + return ExprId("STACK.%d" % (diff // 4), expr.size) return False @@ -997,12 +999,12 @@ def retrieve_stack_accesses(ir_arch_a, ircfg): @ircfg: IRCFG instance """ stack_vars = set() - for block in ircfg.blocks.itervalues(): + for block in viewvalues(ircfg.blocks): for assignblk in block: - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): stack_vars.update(get_stack_accesses(ir_arch_a, dst)) stack_vars.update(get_stack_accesses(ir_arch_a, src)) - stack_vars = filter(lambda expr: check_expr_below_stack(ir_arch_a, expr), stack_vars) + stack_vars = [expr for expr in stack_vars if check_expr_below_stack(ir_arch_a, expr)] base_to_var = {} for var in stack_vars: @@ -1010,7 +1012,7 @@ def retrieve_stack_accesses(ir_arch_a, ircfg): base_to_interval = {} - for addr, vars in base_to_var.iteritems(): + for addr, vars in viewitems(base_to_var): var_interval = interval() for var in vars: offset = expr_simp(addr - ir_arch_a.sp) @@ -1019,7 +1021,7 @@ def retrieve_stack_accesses(ir_arch_a, ircfg): continue start = int(offset) - stop = int(expr_simp(offset + ExprInt(var.size / 8, offset.size))) + stop = int(expr_simp(offset + ExprInt(var.size // 8, offset.size))) mem = interval([(start, stop-1)]) var_interval += mem base_to_interval[addr] = var_interval @@ -1033,7 +1035,7 @@ def retrieve_stack_accesses(ir_arch_a, ircfg): tmp += mem base_to_info = {} - for addr, vars in base_to_var.iteritems(): + for addr, vars in viewitems(base_to_var): name = "var_%d" % (len(base_to_info)) size = max([var.size for var in vars]) base_to_info[addr] = size, name @@ -1079,11 +1081,11 @@ def replace_stack_vars(ir_arch_a, ircfg): base_to_info = retrieve_stack_accesses(ir_arch_a, ircfg) modified = False - for block in ircfg.blocks.itervalues(): + for block in list(viewvalues(ircfg.blocks)): assignblks = [] for assignblk in block: out = {} - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): new_dst = dst.visit(lambda expr:replace_mem_stack_vars(expr, base_to_info)) new_src = src.visit(lambda expr:replace_mem_stack_vars(expr, base_to_info)) if new_dst != dst or new_src != src: @@ -1120,9 +1122,9 @@ def get_memlookup(expr, bs, is_addr_ro_variable): def read_mem(bs, expr): ptr = int(expr.ptr) - var_bytes = bs.getbytes(ptr, expr.size / 8)[::-1] + var_bytes = bs.getbytes(ptr, expr.size // 8)[::-1] try: - value = int(var_bytes.encode('hex'), 16) + value = int(encode_hex(var_bytes), 16) except ValueError: return expr return ExprInt(value, expr.size) @@ -1137,11 +1139,11 @@ def load_from_int(ir_arch, bs, is_addr_ro_variable): """ modified = False - for block in ir_arch.blocks.itervalues(): + for block in list(viewvalues(ir_arch.blocks)): assignblks = list() for assignblk in block: out = {} - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): # Test src mems = get_memlookup(src, bs, is_addr_ro_variable) src_new = src @@ -1197,7 +1199,7 @@ class AssignBlockLivenessInfos(object): out.append( '\n'.join( "\t%s = %s" % (dst, src) - for (dst, src) in self.assignblk.iteritems() + for (dst, src) in viewitems(self.assignblk) ) ) out.append("\tVarOut:" + ", ".join(str(x) for x in self.var_out)) @@ -1217,7 +1219,7 @@ class IRBlockLivenessInfos(object): self.assignblks = [] for assignblk in irblock: gens, kills = set(), set() - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): expr = ExprAssign(dst, src) read = expr.get_r(mem_read=True) write = expr.get_w() @@ -1290,13 +1292,13 @@ class DiGraphLiveness(DiGraph): ) if node not in self._blocks: yield [self.DotCellDescription(text="NOT PRESENT", attr={})] - raise StopIteration + return for i, info in enumerate(self._blocks[node].infos): var_in = "VarIn:" + ", ".join(str(x) for x in info.var_in) var_out = "VarOut:" + ", ".join(str(x) for x in info.var_out) - assignmnts = ["%s = %s" % (dst, src) for (dst, src) in info.assignblk.iteritems()] + assignmnts = ["%s = %s" % (dst, src) for (dst, src) in viewitems(info.assignblk)] if i == 0: yield self.DotCellDescription( @@ -1323,7 +1325,7 @@ class DiGraphLiveness(DiGraph): """ infos = block.infos modified = False - for i in reversed(xrange(len(infos))): + for i in reversed(range(len(infos))): new_vars = set(infos[i].gen.union(infos[i].var_out.difference(infos[i].kill))) if infos[i].var_in != new_vars: modified = True @@ -1385,13 +1387,13 @@ def discard_phi_sources(ircfg, deleted_vars): @ircfg: IRCFG instance in ssa form @deleted_vars: unused phi sources """ - for block in ircfg.blocks.values(): + for block in list(viewvalues(ircfg.blocks)): if not block.assignblks: continue assignblk = block[0] todo = {} modified = False - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): if not src.is_op('Phi'): todo[dst] = src continue @@ -1459,7 +1461,7 @@ def update_phi_with_deleted_edges(ircfg, edges_to_del): assignblks = list(block) assignblk = assignblks[0] out = {} - for dst, phi_sources in assignblk.iteritems(): + for dst, phi_sources in viewitems(assignblk): if not phi_sources.is_op('Phi'): out = assignblk break @@ -1484,7 +1486,7 @@ def update_phi_with_deleted_edges(ircfg, edges_to_del): new_irblock = IRBlock(loc_dst, assignblks) blocks[block.loc_key] = new_irblock - for loc_key, block in blocks.iteritems(): + for loc_key, block in viewitems(blocks): ircfg.blocks[loc_key] = block return modified @@ -1543,13 +1545,13 @@ class DiGraphLivenessSSA(DiGraphLivenessIRA): super(DiGraphLivenessSSA, self).__init__(ircfg) self.loc_key_to_phi_parents = {} - for irblock in self.blocks.values(): + for irblock in viewvalues(self.blocks): if not irblock_has_phi(irblock): continue out = {} - for sources in irblock[0].itervalues(): + for sources in viewvalues(irblock[0]): var_to_parents = get_phi_sources_parent_block(self, irblock.loc_key, sources.args) - for var, var_parents in var_to_parents.iteritems(): + for var, var_parents in viewitems(var_to_parents): out.setdefault(var, set()).update(var_parents) self.loc_key_to_phi_parents[irblock.loc_key] = out diff --git a/miasm2/analysis/debugging.py b/miasm2/analysis/debugging.py index 6b88f00a..824b62ce 100644 --- a/miasm2/analysis/debugging.py +++ b/miasm2/analysis/debugging.py @@ -1,11 +1,16 @@ +from __future__ import print_function +from builtins import map +from builtins import range import cmd +from future.utils import viewitems + from miasm2.core.utils import hexdump from miasm2.core.interval import interval import miasm2.jitter.csts as csts from miasm2.jitter.jitload import ExceptionHandle -class DebugBreakpoint: +class DebugBreakpoint(object): "Debug Breakpoint parent class" pass @@ -46,17 +51,19 @@ class DebugBreakpointMemory(DebugBreakpoint): def __str__(self): bp_type = "" - for k, v in self.type2str.items(): + for k, v in viewitems(self.type2str): if k & self.access_type != 0: bp_type += v - return "Memory BP @0x%08x, Size 0x%08x, Type %s" % (self.addr, - self.size, - bp_type) + return "Memory BP @0x%08x, Size 0x%08x, Type %s" % ( + self.addr, + self.size, + bp_type + ) @classmethod def get_access_type(cls, read=False, write=False): value = 0 - for k, v in cls.type2str.items(): + for k, v in viewitems(cls.type2str): if v == "R" and read is True: value += k if v == "W" and write is True: @@ -146,10 +153,10 @@ class Debugguer(object): return DebugBreakpointTerminate(res) if isinstance(res, DebugBreakpointSoft): - print "Breakpoint reached @0x%08x" % res.addr + print("Breakpoint reached @0x%08x" % res.addr) elif isinstance(res, ExceptionHandle): if res == ExceptionHandle.memoryBreakpoint(): - print "Memory breakpoint reached!" + print("Memory breakpoint reached!") # Remove flag except_flag = self.myjit.vm.get_exception() @@ -196,7 +203,7 @@ class Debugguer(object): def on_step(self): for addr, size in self.mem_watched: - print "@0x%08x:" % addr + print("@0x%08x:" % addr) self.get_mem(addr, size) def get_reg_value(self, reg_name): @@ -238,20 +245,20 @@ class DebugCmd(cmd.Cmd, object): def print_breakpoints(self): bp_list = self.dbg.bp_list if len(bp_list) == 0: - print "No breakpoints." + print("No breakpoints.") else: for i, b in enumerate(bp_list): - print "%d\t0x%08x" % (i, b.addr) + print("%d\t0x%08x" % (i, b.addr)) def print_watchmems(self): watch_list = self.dbg.mem_watched if len(watch_list) == 0: - print "No memory watchpoints." + print("No memory watchpoints.") else: - print "Num\tAddress \tSize" + print("Num\tAddress \tSize") for i, w in enumerate(watch_list): addr, size = w - print "%d\t0x%08x\t0x%08x" % (i, addr, size) + print("%d\t0x%08x\t0x%08x" % (i, addr, size)) def print_registers(self): regs = self.dbg.get_gpreg_all() @@ -259,17 +266,21 @@ class DebugCmd(cmd.Cmd, object): # Display settings title1 = "Registers" title2 = "Values" - max_name_len = max(map(len, regs.keys() + [title1])) + max_name_len = max(map(len, list(regs) + [title1])) # Print value table s = "%s%s | %s" % ( title1, " " * (max_name_len - len(title1)), title2) - print s - print "-" * len(s) - for name, value in sorted(regs.items(), key=lambda x: x[0]): - print "%s%s | %s" % (name, - " " * (max_name_len - len(name)), - hex(value).replace("L", "")) + print(s) + print("-" * len(s)) + for name, value in sorted(viewitems(regs), key=lambda x: x[0]): + print( + "%s%s | %s" % ( + name, + " " * (max_name_len - len(name)), + hex(value).replace("L", "") + ) + ) def add_breakpoints(self, bp_addr): for addr in bp_addr: @@ -281,35 +292,41 @@ class DebugCmd(cmd.Cmd, object): good = False break if good is False: - print "Breakpoint 0x%08x already set (%d)" % (addr, i) + print("Breakpoint 0x%08x already set (%d)" % (addr, i)) else: l = len(self.dbg.bp_list) self.dbg.add_breakpoint(addr) - print "Breakpoint 0x%08x successfully added ! (%d)" % (addr, l) + print("Breakpoint 0x%08x successfully added ! (%d)" % (addr, l)) - display_mode = {"mn": None, - "regs": None, - "newbloc": None} + display_mode = { + "mn": None, + "regs": None, + "newbloc": None + } def update_display_mode(self): - self.display_mode = {"mn": self.dbg.myjit.jit.log_mn, - "regs": self.dbg.myjit.jit.log_regs, - "newbloc": self.dbg.myjit.jit.log_newbloc} + self.display_mode = { + "mn": self.dbg.myjit.jit.log_mn, + "regs": self.dbg.myjit.jit.log_regs, + "newbloc": self.dbg.myjit.jit.log_newbloc + } # Command line methods def print_warning(self, s): - print self.color_r + s + self.color_e + print(self.color_r + s + self.color_e) def onecmd(self, line): - cmd_translate = {"h": "help", - "q": "exit", - "e": "exit", - "!": "exec", - "r": "run", - "i": "info", - "b": "breakpoint", - "s": "step", - "d": "dump"} + cmd_translate = { + "h": "help", + "q": "exit", + "e": "exit", + "!": "exec", + "r": "run", + "i": "info", + "b": "breakpoint", + "s": "step", + "d": "dump" + } if len(line) >= 2 and \ line[1] == " " and \ @@ -342,12 +359,12 @@ class DebugCmd(cmd.Cmd, object): self.update_display_mode() def help_display(self): - print "Enable/Disable tracing." - print "Usage: display <mode1> <mode2> ... on|off" - print "Available modes are:" + print("Enable/Disable tracing.") + print("Usage: display <mode1> <mode2> ... on|off") + print("Available modes are:") for k in self.display_mode: - print "\t%s" % k - print "Use 'info display' to get current values" + print("\t%s" % k) + print("Use 'info display' to get current values") def do_watchmem(self, arg): if arg == "": @@ -365,21 +382,23 @@ class DebugCmd(cmd.Cmd, object): self.dbg.watch_mem(addr, size) def help_watchmem(self): - print "Add a memory watcher." - print "Usage: watchmem <addr> [size]" - print "Use 'info watchmem' to get current memory watchers" + print("Add a memory watcher.") + print("Usage: watchmem <addr> [size]") + print("Use 'info watchmem' to get current memory watchers") def do_info(self, arg): - av_info = ["registers", - "display", - "breakpoints", - "watchmem"] + av_info = [ + "registers", + "display", + "breakpoints", + "watchmem" + ] if arg == "": - print "'info' must be followed by the name of an info command." - print "List of info subcommands:" + print("'info' must be followed by the name of an info command.") + print("List of info subcommands:") for k in av_info: - print "\t%s" % k + print("\t%s" % k) if arg.startswith("b"): # Breakpoint @@ -388,8 +407,8 @@ class DebugCmd(cmd.Cmd, object): if arg.startswith("d"): # Display self.update_display_mode() - for k, v in self.display_mode.items(): - print "%s\t\t%s" % (k, v) + for k, v in viewitems(self.display_mode): + print("%s\t\t%s" % (k, v)) if arg.startswith("w"): # Watchmem @@ -400,9 +419,9 @@ class DebugCmd(cmd.Cmd, object): self.print_registers() def help_info(self): - print "Generic command for showing things about the program being" - print "debugged. Use 'info' without arguments to get the list of" - print "available subcommands." + print("Generic command for showing things about the program being") + print("debugged. Use 'info' without arguments to get the list of") + print("available subcommands.") def do_breakpoint(self, arg): if arg == "": @@ -412,23 +431,23 @@ class DebugCmd(cmd.Cmd, object): self.add_breakpoints(addrs) def help_breakpoint(self): - print "Add breakpoints to argument addresses." - print "Example:" - print "\tbreakpoint 0x11223344" - print "\tbreakpoint 1122 0xabcd" + print("Add breakpoints to argument addresses.") + print("Example:") + print("\tbreakpoint 0x11223344") + print("\tbreakpoint 1122 0xabcd") def do_step(self, arg): if arg == "": nb = 1 else: nb = int(arg) - for _ in xrange(nb): + for _ in range(nb): self.dbg.step() def help_step(self): - print "Step program until it reaches a different source line." - print "Argument N means do this N times (or till program stops" - print "for another reason)." + print("Step program until it reaches a different source line.") + print("Argument N means do this N times (or till program stops") + print("for another reason).") def do_dump(self, arg): if arg == "": @@ -444,36 +463,36 @@ class DebugCmd(cmd.Cmd, object): self.dbg.get_mem(addr, size) def help_dump(self): - print "Dump <addr> [size]. Dump size bytes at addr." + print("Dump <addr> [size]. Dump size bytes at addr.") def do_run(self, _): self.dbg.run() def help_run(self): - print "Launch or continue the current program" + print("Launch or continue the current program") def do_exit(self, _): return True def do_exec(self, line): try: - print eval(line) - except Exception, error: - print "*** Error: %s" % error + print(eval(line)) + except Exception as error: + print("*** Error: %s" % error) def help_exec(self): - print "Exec a python command." - print "You can also use '!' shortcut." + print("Exec a python command.") + print("You can also use '!' shortcut.") def help_exit(self): - print "Exit the interpreter." - print "You can also use the Ctrl-D shortcut." + print("Exit the interpreter.") + print("You can also use the Ctrl-D shortcut.") def help_help(self): - print "Print help" + print("Print help") def postloop(self): - print '\nGoodbye !' + print('\nGoodbye !') super(DebugCmd, self).postloop() do_EOF = do_exit diff --git a/miasm2/analysis/depgraph.py b/miasm2/analysis/depgraph.py index 4e5f0433..4bfae67f 100644 --- a/miasm2/analysis/depgraph.py +++ b/miasm2/analysis/depgraph.py @@ -1,5 +1,9 @@ """Provide dependency graph""" +from functools import total_ordering + +from future.utils import viewitems + from miasm2.expression.expression import ExprInt, ExprLoc, ExprAssign from miasm2.core.graph import DiGraph from miasm2.core.locationdb import LocationDB @@ -14,7 +18,7 @@ try: except ImportError: pass - +@total_ordering class DependencyNode(object): """Node elements of a DependencyGraph @@ -50,16 +54,17 @@ class DependencyNode(object): self.element == depnode.element and self.line_nb == depnode.line_nb) - def __ne__(self, other): - return not self.__eq__(other) + def __ne__(self, depnode): + # required Python 2.7.14 + return not self == depnode - def __cmp__(self, node): + def __lt__(self, node): """Compares @self with @node.""" if not isinstance(node, self.__class__): - return cmp(self.__class__, node.__class__) + return NotImplemented - return cmp((self.loc_key, self.element, self.line_nb), - (node.loc_key, node.element, node.line_nb)) + return ((self.loc_key, self.element, self.line_nb) < + (node.loc_key, node.element, node.line_nb)) def __str__(self): """Returns a string representation of DependencyNode""" @@ -96,7 +101,7 @@ class DependencyState(object): def __init__(self, loc_key, pending, line_nb=None): self.loc_key = loc_key self.history = [loc_key] - self.pending = {k: set(v) for k, v in pending.iteritems()} + self.pending = {k: set(v) for k, v in viewitems(pending)} self.line_nb = line_nb self.links = set() @@ -104,9 +109,11 @@ class DependencyState(object): self._graph = None def __repr__(self): - return "<State: %r (%r) (%r)>" % (self.loc_key, - self.pending, - self.links) + return "<State: %r (%r) (%r)>" % ( + self.loc_key, + self.pending, + self.links + ) def extend(self, loc_key): """Return a copy of itself, with itself in history @@ -129,7 +136,7 @@ class DependencyState(object): graph.add_node(node_a) else: graph.add_edge(node_a, node_b) - for parent, sons in self.pending.iteritems(): + for parent, sons in viewitems(self.pending): for son in sons: graph.add_edge(parent, son) return graph @@ -148,7 +155,7 @@ class DependencyState(object): def add_pendings(self, future_pending): """Add @future_pending to the state""" - for node, depnodes in future_pending.iteritems(): + for node, depnodes in viewitems(future_pending): if node not in self.pending: self.pending[node] = depnodes else: @@ -263,7 +270,7 @@ class DependencyResult(DependencyState): line2elements.setdefault(depnode.line_nb, set()).add(depnode.element) - for line_nb, elements in sorted(line2elements.iteritems()): + for line_nb, elements in sorted(viewitems(line2elements)): if max_line is not None and line_nb >= max_line: break assignmnts = {} @@ -385,8 +392,10 @@ class DependencyResultImplicit(DependencyResult): self._solver = solver # Return only inputs values (others could be wrongs) - return {element: symb_exec.eval_expr(element) - for element in self.inputs} + return { + element: symb_exec.eval_expr(element) + for element in self.inputs + } @property def is_satisfiable(self): @@ -562,7 +571,7 @@ class DependencyGraph(object): """Track pending expression in an assignblock""" future_pending = {} node_resolved = set() - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): # Only track pending if dst not in state.pending: continue diff --git a/miasm2/analysis/disasm_cb.py b/miasm2/analysis/disasm_cb.py index d3278cb4..36e120b6 100644 --- a/miasm2/analysis/disasm_cb.py +++ b/miasm2/analysis/disasm_cb.py @@ -1,5 +1,9 @@ #-*- coding:utf-8 -*- +from __future__ import print_function + +from future.utils import viewvalues + from miasm2.expression.expression import ExprInt, ExprId, ExprMem, match_expr from miasm2.expression.simplifications import expr_simp from miasm2.core.asmblock import AsmConstraintNext, AsmConstraintTo @@ -27,13 +31,12 @@ def arm_guess_subcall( sp = LocationDB() ir_arch = ira(sp) ircfg = ira.new_ircfg() - print '###' - print cur_bloc + print('###') + print(cur_bloc) ir_arch.add_asmblock_to_ircfg(cur_bloc, ircfg) - ir_blocks = ircfg.blocks.values() to_add = set() - for irblock in ir_blocks: + for irblock in viewvalues(ircfg.blocks): pc_val = None lr_val = None for exprs in irblock: @@ -72,8 +75,7 @@ def arm_guess_jump_table( ircfg = ira.new_ircfg() ir_arch.add_asmblock_to_ircfg(cur_bloc, ircfg) - ir_blocks = ircfg.blocks.values() - for irblock in ir_blocks: + for irblock in viewvalues(ircfg.blocks): pc_val = None for exprs in irblock: for e in exprs: @@ -84,18 +86,18 @@ def arm_guess_jump_table( if not isinstance(pc_val, ExprMem): continue assert(pc_val.size == 32) - print pc_val + print(pc_val) ad = pc_val.arg ad = expr_simp(ad) - print ad + print(ad) res = match_expr(ad, jra + jrb, set([jra, jrb])) if res is False: raise NotImplementedError('not fully functional') - print res + print(res) if not isinstance(res[jrb], ExprInt): raise NotImplementedError('not fully functional') base_ad = int(res[jrb]) - print base_ad + print(base_ad) addrs = set() i = -1 max_table_entry = 10000 @@ -109,7 +111,7 @@ def arm_guess_jump_table( if abs(ad - base_ad) > max_diff_addr: break addrs.add(ad) - print [hex(x) for x in addrs] + print([hex(x) for x in addrs]) for ad in addrs: offsets_to_dis.add(ad) diff --git a/miasm2/analysis/dse.py b/miasm2/analysis/dse.py index 5eb924d7..fee85984 100644 --- a/miasm2/analysis/dse.py +++ b/miasm2/analysis/dse.py @@ -47,7 +47,7 @@ Here are a few remainings TODO: the solver for reducing the possible values thanks to its accumulated constraints. """ - +from builtins import range from collections import namedtuple try: @@ -55,6 +55,9 @@ try: except ImportError: z3 = None +from future.utils import viewitems + +from miasm2.core.utils import encode_hex, force_bytes from miasm2.expression.expression import ExprMem, ExprInt, ExprCompose, \ ExprAssign, ExprId, ExprLoc, LocKey from miasm2.core.bin_stream import bin_stream_vm @@ -111,7 +114,7 @@ class ESETrackModif(EmulatedSymbExec): # Split access in atomic accesses out = [] - for addr in xrange(dst_addr, dst_addr + (expr_mem.size / 8)): + for addr in range(dst_addr, dst_addr + expr_mem.size // 8): if addr in self.dse_memory_range: # Symbolize memory access out.append(self.dse_memory_to_expr(addr)) @@ -249,14 +252,18 @@ class DSEEngine(object): Known functions will be looked by {name}_symb in the @namespace """ + namespace = dict( + (force_bytes(name), func) for name, func in viewitems(namespace) + ) # lambda cannot contain statement def default_func(dse): - fname = "%s_symb" % libimp.fad2cname[dse.jitter.pc] + fname = b"%s_symb" % libimp.fad2cname[dse.jitter.pc] raise RuntimeError("Symbolic stub '%s' not found" % fname) - for addr, fname in libimp.fad2cname.iteritems(): - fname = "%s_symb" % fname + for addr, fname in viewitems(libimp.fad2cname): + fname = force_bytes(fname) + fname = b"%s_symb" % fname func = namespace.get(fname, None) if func is not None: self.add_handler(addr, func) @@ -292,9 +299,11 @@ class DSEEngine(object): if value != symb_value: errors.append(DriftInfo(symbol, symb_value, value)) elif symbol.is_mem() and symbol.ptr.is_int(): - value_chr = self.jitter.vm.get_mem(int(symbol.ptr), - symbol.size / 8) - exp_value = int(value_chr[::-1].encode("hex"), 16) + value_chr = self.jitter.vm.get_mem( + int(symbol.ptr), + symbol.size // 8 + ) + exp_value = int(encode_hex(value_chr[::-1]), 16) if exp_value != symb_value: errors.append(DriftInfo(symbol, symb_value, exp_value)) @@ -410,14 +419,16 @@ class DSEEngine(object): if memory: self.jitter.vm.reset_memory_page_pool() self.jitter.vm.reset_code_bloc_pool() - for addr, metadata in snapshot["mem"].iteritems(): - self.jitter.vm.add_memory_page(addr, - metadata["access"], - metadata["data"]) + for addr, metadata in viewitems(snapshot["mem"]): + self.jitter.vm.add_memory_page( + addr, + metadata["access"], + metadata["data"] + ) # Restore registers self.jitter.pc = snapshot["regs"][self.ir_arch.pc.name] - for reg, value in snapshot["regs"].iteritems(): + for reg, value in viewitems(snapshot["regs"]): setattr(self.jitter.cpu, reg, value) # Reset intern elements @@ -426,16 +437,16 @@ class DSEEngine(object): self.jitter.bs._atomic_mode = False # Reset symb exec - for key, _ in self.symb.symbols.items(): + for key, _ in list(viewitems(self.symb.symbols)): del self.symb.symbols[key] - for expr, value in snapshot["symb"].items(): + for expr, value in viewitems(snapshot["symb"]): self.symb.symbols[expr] = value def update_state(self, assignblk): """From this point, assume @assignblk in the symbolic execution @assignblk: AssignBlock/{dst -> src} """ - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): self.symb.apply_change(dst, src) def _update_state_from_concrete_symb(self, symbexec, cpu=True, mem=False): @@ -534,8 +545,10 @@ class DSEPathConstraint(DSEEngine): def take_snapshot(self, *args, **kwargs): snap = super(DSEPathConstraint, self).take_snapshot(*args, **kwargs) - snap["new_solutions"] = {dst: src.copy - for dst, src in self.new_solutions.iteritems()} + snap["new_solutions"] = { + dst: src.copy + for dst, src in viewitems(self.new_solutions) + } snap["cur_constraints"] = self.cur_solver.assertions() if self._produce_solution_strategy == self.PRODUCE_SOLUTION_PATH_COV: snap["_history"] = list(self._history) @@ -650,9 +663,11 @@ class DSEPathConstraint(DSEEngine): # if addr (- [a, b], then @size[addr] reachables # values are in @8[a, b + size[ for start, stop in addr_range: - stop += (expr.size / 8) - 1 - full_range = ModularIntervals(symb_pc.size, - [(start, stop)]) + stop += expr.size // 8 - 1 + full_range = ModularIntervals( + symb_pc.size, + [(start, stop)] + ) memory_to_add.update(full_range) path_constraint.add(eaff) @@ -662,7 +677,7 @@ class DSEPathConstraint(DSEEngine): # Inject memory for start, stop in memory_to_add: - for address in xrange(start, stop + 1): + for address in range(start, stop + 1): expr_mem = ExprMem(ExprInt(address, self.ir_arch.pc.size), 8) diff --git a/miasm2/analysis/expression_range.py b/miasm2/analysis/expression_range.py index f09a18d0..8f498549 100644 --- a/miasm2/analysis/expression_range.py +++ b/miasm2/analysis/expression_range.py @@ -1,5 +1,8 @@ """Naive range analysis for expression""" +from future.builtins import zip +from functools import reduce + from miasm2.analysis.modularintervals import ModularIntervals _op_range_handler = { @@ -44,9 +47,11 @@ def expr_range(expr): # Otherwise, overapproximate (ie. full range interval) if expr.op in _op_range_handler: sub_ranges = [expr_range(arg) for arg in expr.args] - return reduce(_op_range_handler[expr.op], - (sub_range for sub_range in sub_ranges[1:]), - sub_ranges[0]) + return reduce( + _op_range_handler[expr.op], + (sub_range for sub_range in sub_ranges[1:]), + sub_ranges[0] + ) elif expr.op == "-": assert len(expr.args) == 1 return - expr_range(expr.args[0]) diff --git a/miasm2/analysis/gdbserver.py b/miasm2/analysis/gdbserver.py index 6c630f88..61ee8955 100644 --- a/miasm2/analysis/gdbserver.py +++ b/miasm2/analysis/gdbserver.py @@ -1,10 +1,15 @@ #-*- coding:utf-8 -*- +from __future__ import print_function +from future.builtins import map, range + +from miasm2.core.utils import decode_hex, encode_hex, int_to_byte + import socket import struct import time import logging -from StringIO import StringIO +from io import BytesIO import miasm2.analysis.debugging as debugging from miasm2.jitter.jitload import ExceptionHandle @@ -15,7 +20,7 @@ class GdbServer(object): general_registers_order = [] general_registers_size = {} # RegName : Size in octet - status = "S05" + status = b"S05" def __init__(self, dbg, port=4455): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -28,242 +33,243 @@ class GdbServer(object): # Communication methods def compute_checksum(self, data): - return chr(sum(map(ord, data)) % 256).encode("hex") + return encode_hex(int_to_byte(sum(map(ord, data)) % 256)) def get_messages(self): - all_data = "" - data = self.sock.recv(4096) - all_data += data - while (len(data) == 4096 or data == ""): - if data == "": - # Avoid consuming CPU - time.sleep(0.001) - continue + all_data = b"" + while True: data = self.sock.recv(4096) + if not data: + break all_data += data logging.debug("<- %r", all_data) self.recv_queue += self.parse_messages(all_data) def parse_messages(self, data): - buf = StringIO(data) - + buf = BytesIO(data) msgs = [] while (buf.tell() < buf.len): token = buf.read(1) - if token == "+": + if token == b"+": continue - if token == "-": + if token == b"-": raise NotImplementedError("Resend packet") - if token == "$": - packet_data = "" + if token == b"$": + packet_data = b"" c = buf.read(1) - while c != "#": + while c != b"#": packet_data += c c = buf.read(1) checksum = buf.read(2) if checksum != self.compute_checksum(packet_data): raise ValueError("Incorrect checksum") - msgs.append(packet_data) return msgs def send_string(self, s): - self.send_queue.append("O" + s.encode("hex")) + self.send_queue.append(b"O" + encode_hex(s)) def process_messages(self): while self.recv_queue: msg = self.recv_queue.pop(0) - buf = StringIO(msg) + buf = BytesIO(msg) msg_type = buf.read(1) - self.send_queue.append("+") + self.send_queue.append(b"+") - if msg_type == "q": - if msg.startswith("qSupported"): - self.send_queue.append("PacketSize=3fff") - elif msg.startswith("qC"): + if msg_type == b"q": + if msg.startswith(b"qSupported"): + self.send_queue.append(b"PacketSize=3fff") + elif msg.startswith(b"qC"): # Current thread - self.send_queue.append("") - elif msg.startswith("qAttached"): + self.send_queue.append(b"") + elif msg.startswith(b"qAttached"): # Not supported - self.send_queue.append("") - elif msg.startswith("qTStatus"): + self.send_queue.append(b"") + elif msg.startswith(b"qTStatus"): # Not supported - self.send_queue.append("") - elif msg.startswith("qfThreadInfo"): + self.send_queue.append(b"") + elif msg.startswith(b"qfThreadInfo"): # Not supported - self.send_queue.append("") + self.send_queue.append(b"") else: raise NotImplementedError() - elif msg_type == "H": + elif msg_type == b"H": # Set current thread - self.send_queue.append("OK") + self.send_queue.append(b"OK") - elif msg_type == "?": + elif msg_type == b"?": # Report why the target halted self.send_queue.append(self.status) # TRAP signal - elif msg_type == "g": + elif msg_type == b"g": # Report all general register values self.send_queue.append(self.report_general_register_values()) - elif msg_type == "p": + elif msg_type == b"p": # Read a specific register reg_num = int(buf.read(), 16) self.send_queue.append(self.read_register(reg_num)) - elif msg_type == "P": + elif msg_type == b"P": # Set a specific register - reg_num, value = buf.read().split("=") + reg_num, value = buf.read().split(b"=") reg_num = int(reg_num, 16) - value = int(value.decode("hex")[::-1].encode("hex"), 16) + value = int(encode_hex(decode_hex(value)[::-1]), 16) self.set_register(reg_num, value) - self.send_queue.append("OK") + self.send_queue.append(b"OK") - elif msg_type == "m": + elif msg_type == b"m": # Read memory - addr, size = map(lambda x: int(x, 16), buf.read().split(",")) + addr, size = (int(x, 16) for x in buf.read().split(b",", 1)) self.send_queue.append(self.read_memory(addr, size)) - elif msg_type == "k": + elif msg_type == b"k": # Kill self.sock.close() self.send_queue = [] self.sock = None - elif msg_type == "!": + elif msg_type == b"!": # Extending debugging will be used - self.send_queue.append("OK") + self.send_queue.append(b"OK") - elif msg_type == "v": - if msg == "vCont?": + elif msg_type == b"v": + if msg == b"vCont?": # Is vCont supported ? - self.send_queue.append("") + self.send_queue.append(b"") - elif msg_type == "s": + elif msg_type == b"s": # Step self.dbg.step() - self.send_queue.append("S05") # TRAP signal + self.send_queue.append(b"S05") # TRAP signal - elif msg_type == "Z": + elif msg_type == b"Z": # Add breakpoint or watchpoint bp_type = buf.read(1) - if bp_type == "0": + if bp_type == b"0": # Exec breakpoint - assert(buf.read(1) == ",") - addr, size = map( - lambda x: int(x, 16), buf.read().split(",")) + assert(buf.read(1) == b",") + addr, size = (int(x, 16) for x in buf.read().split(b",", 1)) if size != 1: raise NotImplementedError("Bigger size") self.dbg.add_breakpoint(addr) - self.send_queue.append("OK") + self.send_queue.append(b"OK") - elif bp_type == "1": + elif bp_type == b"1": # Hardware BP - assert(buf.read(1) == ",") - addr, size = map( - lambda x: int(x, 16), buf.read().split(",")) - - self.dbg.add_memory_breakpoint(addr, size, - read=True, - write=True) - self.send_queue.append("OK") - - elif bp_type in ["2", "3", "4"]: + assert(buf.read(1) == b",") + addr, size = (int(x, 16) for x in buf.read().split(b",", 1)) + + self.dbg.add_memory_breakpoint( + addr, + size, + read=True, + write=True + ) + self.send_queue.append(b"OK") + + elif bp_type in [b"2", b"3", b"4"]: # Memory breakpoint - assert(buf.read(1) == ",") - read = bp_type in ["3", "4"] - write = bp_type in ["2", "4"] - addr, size = map( - lambda x: int(x, 16), buf.read().split(",")) - - self.dbg.add_memory_breakpoint(addr, size, - read=read, - write=write) - self.send_queue.append("OK") + assert(buf.read(1) == b",") + read = bp_type in [b"3", b"4"] + write = bp_type in [b"2", b"4"] + addr, size = (int(x, 16) for x in buf.read().split(b",", 1)) + + self.dbg.add_memory_breakpoint( + addr, + size, + read=read, + write=write + ) + self.send_queue.append(b"OK") else: raise ValueError("Impossible value") - elif msg_type == "z": + elif msg_type == b"z": # Remove breakpoint or watchpoint bp_type = buf.read(1) - if bp_type == "0": + if bp_type == b"0": # Exec breakpoint - assert(buf.read(1) == ",") - addr, size = map( - lambda x: int(x, 16), buf.read().split(",")) + assert(buf.read(1) == b",") + addr, size = (int(x, 16) for x in buf.read().split(b",", 1)) if size != 1: raise NotImplementedError("Bigger size") dbgsoft = self.dbg.get_breakpoint_by_addr(addr) assert(len(dbgsoft) == 1) self.dbg.remove_breakpoint(dbgsoft[0]) - self.send_queue.append("OK") + self.send_queue.append(b"OK") - elif bp_type == "1": + elif bp_type == b"1": # Hardware BP - assert(buf.read(1) == ",") - addr, size = map( - lambda x: int(x, 16), buf.read().split(",")) + assert(buf.read(1) == b",") + addr, size = (int(x, 16) for x in buf.read().split(b",", 1)) self.dbg.remove_memory_breakpoint_by_addr_access( - addr, read=True, write=True) - self.send_queue.append("OK") + addr, + read=True, + write=True + ) + self.send_queue.append(b"OK") - elif bp_type in ["2", "3", "4"]: + elif bp_type in [b"2", b"3", b"4"]: # Memory breakpoint - assert(buf.read(1) == ",") - read = bp_type in ["3", "4"] - write = bp_type in ["2", "4"] - addr, size = map( - lambda x: int(x, 16), buf.read().split(",")) + assert(buf.read(1) == b",") + read = bp_type in [b"3", b"4"] + write = bp_type in [b"2", b"4"] + addr, size = (int(x, 16) for x in buf.read().split(b",", 1)) self.dbg.remove_memory_breakpoint_by_addr_access( - addr, read=read, write=write) - self.send_queue.append("OK") + addr, + read=read, + write=write + ) + self.send_queue.append(b"OK") else: raise ValueError("Impossible value") - elif msg_type == "c": + elif msg_type == b"c": # Continue - self.status = "" + self.status = b"" self.send_messages() ret = self.dbg.run() if isinstance(ret, debugging.DebugBreakpointSoft): - self.status = "S05" - self.send_queue.append("S05") # TRAP signal + self.status = b"S05" + self.send_queue.append(b"S05") # TRAP signal elif isinstance(ret, ExceptionHandle): if ret == ExceptionHandle.memoryBreakpoint(): - self.status = "S05" - self.send_queue.append("S05") + self.status = b"S05" + self.send_queue.append(b"S05") else: raise NotImplementedError("Unknown Except") elif isinstance(ret, debugging.DebugBreakpointTerminate): # Connexion should close, but keep it running as a TRAP # The connexion will be close on instance destruction - print ret - self.status = "S05" - self.send_queue.append("S05") + print(ret) + self.status = b"S05" + self.send_queue.append(b"S05") else: raise NotImplementedError() else: raise NotImplementedError( - "Not implemented: message type '%s'" % msg_type) + "Not implemented: message type %r" % msg_type + ) def send_messages(self): for msg in self.send_queue: - if msg == "+": - data = "+" + if msg == b"+": + data = b"+" else: - data = "$%s#%s" % (msg, self.compute_checksum(msg)) + data = b"$%s#%s" % (msg, self.compute_checksum(msg)) logging.debug("-> %r", data) self.sock.send(data) self.send_queue = [] @@ -272,7 +278,7 @@ class GdbServer(object): self.recv_queue = [] self.send_queue = [] - self.send_string("Test\n") + self.send_string(b"Test\n") while (self.sock): self.get_messages() @@ -285,8 +291,8 @@ class GdbServer(object): # Debugguer processing methods def report_general_register_values(self): - s = "" - for i in xrange(len(self.general_registers_order)): + s = b"" + for i in range(len(self.general_registers_order)): s += self.read_register(i) return s @@ -307,7 +313,7 @@ class GdbServer(object): else: raise NotImplementedError("Unknown size") - return struct.pack(pack_token, reg_value).encode("hex") + return encode_hex(struct.pack(pack_token, reg_value)) def set_register(self, reg_num, value): reg_name = self.general_registers_order[reg_num] @@ -319,39 +325,44 @@ class GdbServer(object): def read_memory(self, addr, size): except_flag_vm = self.dbg.myjit.vm.get_exception() try: - return self.dbg.get_mem_raw(addr, size).encode("hex") + return encode_hex(self.dbg.get_mem_raw(addr, size)) except RuntimeError: self.dbg.myjit.vm.set_exception(except_flag_vm) - return "00" * size + return b"00" * size class GdbServer_x86_32(GdbServer): "Extend GdbServer for x86 32bits purposes" - general_registers_order = ["EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", - "EDI", "EIP", "EFLAGS", "CS", "SS", "DS", "ES", - "FS", "GS"] - - general_registers_size = {"EAX": 4, - "ECX": 4, - "EDX": 4, - "EBX": 4, - "ESP": 4, - "EBP": 4, - "ESI": 4, - "EDI": 4, - "EIP": 4, - "EFLAGS": 2, - "CS": 2, - "SS": 2, - "DS": 2, - "ES": 2, - "FS": 2, - "GS": 2} + general_registers_order = [ + "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", + "EDI", "EIP", "EFLAGS", "CS", "SS", "DS", "ES", + "FS", "GS" + ] + + general_registers_size = { + "EAX": 4, + "ECX": 4, + "EDX": 4, + "EBX": 4, + "ESP": 4, + "EBP": 4, + "ESI": 4, + "EDI": 4, + "EIP": 4, + "EFLAGS": 2, + "CS": 2, + "SS": 2, + "DS": 2, + "ES": 2, + "FS": 2, + "GS": 2 + } register_ignore = [ - "tf", "i_f", "nt", "rf", "vm", "ac", "vif", "vip", "i_d"] + "tf", "i_f", "nt", "rf", "vm", "ac", "vif", "vip", "i_d" + ] def read_register_by_name(self, reg_name): sup_func = super(GdbServer_x86_32, self).read_register_by_name @@ -364,7 +375,8 @@ class GdbServer_x86_32(GdbServer): if reg_name == "EFLAGS": val = 0 eflags_args = [ - "cf", 1, "pf", 0, "af", 0, "zf", "nf", "tf", "i_f", "df", "of"] + "cf", 1, "pf", 0, "af", 0, "zf", "nf", "tf", "i_f", "df", "of" + ] eflags_args += ["nt", 0, "rf", "vm", "ac", "vif", "vip", "i_d"] eflags_args += [0] * 10 @@ -387,26 +399,30 @@ class GdbServer_msp430(GdbServer): "Extend GdbServer for msp430 purposes" - general_registers_order = ["PC", "SP", "SR", "R3", "R4", "R5", "R6", "R7", - "R8", "R9", "R10", "R11", "R12", "R13", "R14", - "R15"] - - general_registers_size = {"PC": 2, - "SP": 2, - "SR": 2, - "R3": 2, - "R4": 2, - "R5": 2, - "R6": 2, - "R7": 2, - "R8": 2, - "R9": 2, - "R10": 2, - "R11": 2, - "R12": 2, - "R13": 2, - "R14": 2, - "R15": 2} + general_registers_order = [ + "PC", "SP", "SR", "R3", "R4", "R5", "R6", "R7", + "R8", "R9", "R10", "R11", "R12", "R13", "R14", + "R15" + ] + + general_registers_size = { + "PC": 2, + "SP": 2, + "SR": 2, + "R3": 2, + "R4": 2, + "R5": 2, + "R6": 2, + "R7": 2, + "R8": 2, + "R9": 2, + "R10": 2, + "R11": 2, + "R12": 2, + "R13": 2, + "R14": 2, + "R15": 2 + } def read_register_by_name(self, reg_name): sup_func = super(GdbServer_msp430, self).read_register_by_name diff --git a/miasm2/analysis/modularintervals.py b/miasm2/analysis/modularintervals.py index 83890f19..2195598b 100644 --- a/miasm2/analysis/modularintervals.py +++ b/miasm2/analysis/modularintervals.py @@ -1,4 +1,7 @@ """Intervals with a maximum size, supporting modular arithmetic""" + +from future.builtins import range +from builtins import int as int_types from itertools import product from miasm2.core.interval import interval @@ -59,7 +62,7 @@ class ModularIntervals(object): """Check and promote the second argument from integer to ModularIntervals with one value""" def ret_func(self, target): - if isinstance(target, (int, long)): + if isinstance(target, int_types): target = ModularIntervals(self.size, interval([(target, target)])) if not isinstance(target, ModularIntervals): raise TypeError("Unsupported operation with %s" % target.__class__) @@ -336,7 +339,7 @@ class ModularIntervals(object): shifter &= interval([(0, self.size)]) ret = interval() for shift_range in shifter: - for shift in xrange(shift_range[0], shift_range[1] + 1): + for shift in range(shift_range[0], shift_range[1] + 1): for x_min, x_max in self.intervals: ret += self._range_shift_uniq(x_min, x_max, shift, operation) return self.__class__(self.size, ret) @@ -372,7 +375,7 @@ class ModularIntervals(object): shifter %= self.size ret = interval() for shift_range in shifter: - for shift in xrange(shift_range[0], shift_range[1] + 1): + for shift in range(shift_range[0], shift_range[1] + 1): for x_min, x_max in self.intervals: ret += self._range_rotate_uniq(x_min, x_max, shift, operation) @@ -446,7 +449,7 @@ class ModularIntervals(object): @modulo: integer """ - if not isinstance(modulo, (int, long)): + if not isinstance(modulo, int_types): raise TypeError("Modulo with %s is not supported" % modulo.__class__) return self._integer_modulo(modulo) diff --git a/miasm2/analysis/outofssa.py b/miasm2/analysis/outofssa.py index 6355aeb2..41c665af 100644 --- a/miasm2/analysis/outofssa.py +++ b/miasm2/analysis/outofssa.py @@ -1,3 +1,5 @@ +from future.utils import viewitems, viewvalues + from miasm2.expression.expression import ExprId from miasm2.ir.ir import IRBlock, AssignBlock from miasm2.analysis.ssa import get_phi_sources_parent_block, \ @@ -59,7 +61,7 @@ class UnSSADiGraph(object): """ ircfg = self.ssa.graph - for irblock in ircfg.blocks.values(): + for irblock in list(viewvalues(ircfg.blocks)): if not irblock_has_phi(irblock): continue @@ -82,7 +84,7 @@ class UnSSADiGraph(object): for parent, src in self.phi_parent_sources[dst]: parent_to_parallel_copies.setdefault(parent, {})[new_var] = src - for parent, parallel_copies in parent_to_parallel_copies.iteritems(): + for parent, parallel_copies in viewitems(parent_to_parallel_copies): parent = ircfg.blocks[parent] assignblks = list(parent) assignblks.append(AssignBlock(parallel_copies, parent[-1].instr)) @@ -104,10 +106,10 @@ class UnSSADiGraph(object): node """ ircfg = self.ssa.graph - for irblock in ircfg.blocks.itervalues(): + for irblock in viewvalues(ircfg.blocks): if not irblock_has_phi(irblock): continue - for dst, sources in irblock[0].iteritems(): + for dst, sources in viewitems(irblock[0]): assert sources.is_op('Phi') new_var = self.create_copy_var(dst) self.phi_new_var[dst] = new_var @@ -130,7 +132,7 @@ class UnSSADiGraph(object): """ Generate trivial coalescing of phi variable and itself """ - for phi_new_var in self.phi_new_var.itervalues(): + for phi_new_var in viewvalues(self.phi_new_var): self.merge_state.setdefault(phi_new_var, set([phi_new_var])) def order_ssa_var_dom(self): @@ -303,7 +305,7 @@ class UnSSADiGraph(object): assignments. @parent: Optional parent location of the phi source for liveness tests """ - for dst, src in parallel_copies.iteritems(): + for dst, src in viewitems(parallel_copies): dst_merge = self.merge_state.setdefault(dst, set([dst])) src_merge = self.merge_state.setdefault(src, set([src])) if not self.merge_sets_interfere(dst_merge, src_merge, parent): @@ -317,7 +319,7 @@ class UnSSADiGraph(object): ircfg = self.ssa.graph # Run coalesce on the post phi parallel copy - for irblock in ircfg.blocks.values(): + for irblock in viewvalues(ircfg.blocks): if not irblock_has_phi(irblock): continue parallel_copies = {} @@ -335,7 +337,7 @@ class UnSSADiGraph(object): for parent, src in self.phi_parent_sources[dst]: parent_to_parallel_copies.setdefault(parent, {})[new_var] = src - for parent, parallel_copies in parent_to_parallel_copies.iteritems(): + for parent, parallel_copies in viewitems(parent_to_parallel_copies): self.aggressive_coalesce_parallel_copy(parallel_copies, parent) def get_best_merge_set_name(self, merge_set): @@ -363,7 +365,7 @@ class UnSSADiGraph(object): # Elect representative for merge sets merge_set_to_name = {} - for merge_set in self.merge_state.itervalues(): + for merge_set in viewvalues(self.merge_state): frozen_merge_set = frozenset(merge_set) merge_sets.add(frozen_merge_set) var_name = self.get_best_merge_set_name(merge_set) @@ -384,10 +386,10 @@ class UnSSADiGraph(object): @ircfg: IRDiGraph instance """ - for irblock in self.ssa.graph.blocks.values(): + for irblock in list(viewvalues(self.ssa.graph.blocks)): assignblks = list(irblock) out = {} - for dst, src in assignblks[0].iteritems(): + for dst, src in viewitems(assignblks[0]): if src.is_op('Phi'): assert set([dst]) == set(src.args) continue @@ -399,11 +401,11 @@ class UnSSADiGraph(object): """ Remove trivial expressions (a=a) in the current graph """ - for irblock in self.ssa.graph.blocks.values(): + for irblock in list(viewvalues(self.ssa.graph.blocks)): assignblks = list(irblock) for i, assignblk in enumerate(assignblks): out = {} - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): if dst == src: continue out[dst] = src diff --git a/miasm2/analysis/sandbox.py b/miasm2/analysis/sandbox.py index ccffd529..d3e8fce1 100644 --- a/miasm2/analysis/sandbox.py +++ b/miasm2/analysis/sandbox.py @@ -1,13 +1,20 @@ +from __future__ import print_function +from builtins import range + import os import logging from argparse import ArgumentParser +from future.utils import viewitems, viewvalues + +from miasm2.core.utils import force_bytes from miasm2.analysis.machine import Machine from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE from miasm2.analysis import debugging from miasm2.jitter.jitload import log_func + class Sandbox(object): """ @@ -112,7 +119,7 @@ class Sandbox(object): if self.options.gdbserver: port = self.options.gdbserver - print "Listen on port %d" % port + print("Listen on port %d" % port) gdb = self.machine.gdbserver(dbg, port) self.gdb = gdb gdb.run() @@ -184,7 +191,7 @@ class OS_Win(OS): from miasm2.jitter.loader.pe import vm_load_pe, vm_load_pe_libs,\ preload_pe, libimp_pe, vm_load_pe_and_dependencies from miasm2.os_dep import win_api_x86_32, win_api_x86_32_seh - methods = win_api_x86_32.__dict__ + methods = dict((name.encode(),func) for name, func in viewitems(win_api_x86_32.__dict__)) methods.update(custom_methods) super(OS_Win, self).__init__(methods, *args, **kwargs) @@ -199,33 +206,42 @@ class OS_Win(OS): # Load main pe with open(self.fname, "rb") as fstream: - self.pe = vm_load_pe(self.jitter.vm, fstream.read(), - load_hdr=self.options.load_hdr, - name=self.fname, - **kwargs) + self.pe = vm_load_pe( + self.jitter.vm, + fstream.read(), + load_hdr=self.options.load_hdr, + name=self.fname, + **kwargs + ) self.name2module[fname_basename] = self.pe # Load library if self.options.loadbasedll: # Load libs in memory - self.name2module.update(vm_load_pe_libs(self.jitter.vm, - self.ALL_IMP_DLL, - libs, - self.modules_path, - **kwargs)) + self.name2module.update( + vm_load_pe_libs( + self.jitter.vm, + self.ALL_IMP_DLL, + libs, + self.modules_path, + **kwargs + ) + ) # Patch libs imports - for pe in self.name2module.itervalues(): + for pe in viewvalues(self.name2module): preload_pe(self.jitter.vm, pe, libs) if self.options.dependencies: - vm_load_pe_and_dependencies(self.jitter.vm, - fname_basename, - self.name2module, - libs, - self.modules_path, - **kwargs) + vm_load_pe_and_dependencies( + self.jitter.vm, + fname_basename, + self.name2module, + libs, + self.modules_path, + **kwargs + ) win_api_x86_32.winobjs.current_pe = self.pe @@ -275,8 +291,12 @@ class OS_Linux(OS): self.libs = libimp_elf() with open(self.fname, "rb") as fstream: - self.elf = vm_load_elf(self.jitter.vm, fstream.read(), - name=self.fname, **kwargs) + self.elf = vm_load_elf( + self.jitter.vm, + fstream.read(), + name=self.fname, + **kwargs + ) preload_elf(self.jitter.vm, self.elf, self.libs) self.entry_point = self.elf.Ehdr.entry @@ -325,7 +345,8 @@ class OS_Linux_str(OS): self.options.load_base_addr = int(self.options.load_base_addr, 0) self.jitter.vm.add_memory_page( self.options.load_base_addr, PAGE_READ | PAGE_WRITE, data, - "Initial Str") + "Initial Str" + ) # Library calls handler self.jitter.add_lib_handler(libs, methods) @@ -516,14 +537,17 @@ class Sandbox_Win_x86_64(Sandbox, Arch_x86_64, OS_Win): Sandbox.__init__(self, *args, **kwargs) # reserve stack for local reg - for _ in xrange(0x4): + for _ in range(0x4): self.jitter.push_uint64_t(0) # Pre-stack return address self.jitter.push_uint64_t(self.CALL_FINISH_ADDR) # Set the runtime guard - self.jitter.add_breakpoint(self.CALL_FINISH_ADDR, self.__class__.code_sentinelle) + self.jitter.add_breakpoint( + self.CALL_FINISH_ADDR, + self.__class__.code_sentinelle + ) def run(self, addr=None): """ @@ -552,14 +576,16 @@ class Sandbox_Linux_x86_32(Sandbox, Arch_x86_32, OS_Linux): if self.options.mimic_env: env_ptrs = [] for env in self.envp: - env += "\x00" + env = force_bytes(env) + env += b"\x00" self.jitter.cpu.ESP -= len(env) ptr = self.jitter.cpu.ESP self.jitter.vm.set_mem(ptr, env) env_ptrs.append(ptr) argv_ptrs = [] for arg in self.argv: - arg += "\x00" + arg = force_bytes(arg) + arg += b"\x00" self.jitter.cpu.ESP -= len(arg) ptr = self.jitter.cpu.ESP self.jitter.vm.set_mem(ptr, arg) @@ -577,7 +603,10 @@ class Sandbox_Linux_x86_32(Sandbox, Arch_x86_32, OS_Linux): self.jitter.push_uint32_t(self.CALL_FINISH_ADDR) # Set the runtime guard - self.jitter.add_breakpoint(self.CALL_FINISH_ADDR, self.__class__.code_sentinelle) + self.jitter.add_breakpoint( + self.CALL_FINISH_ADDR, + self.__class__.code_sentinelle + ) def run(self, addr=None): """ @@ -607,14 +636,16 @@ class Sandbox_Linux_x86_64(Sandbox, Arch_x86_64, OS_Linux): if self.options.mimic_env: env_ptrs = [] for env in self.envp: - env += "\x00" + env = force_bytes(env) + env += b"\x00" self.jitter.cpu.RSP -= len(env) ptr = self.jitter.cpu.RSP self.jitter.vm.set_mem(ptr, env) env_ptrs.append(ptr) argv_ptrs = [] for arg in self.argv: - arg += "\x00" + arg = force_bytes(arg) + arg += b"\x00" self.jitter.cpu.RSP -= len(arg) ptr = self.jitter.cpu.RSP self.jitter.vm.set_mem(ptr, arg) @@ -632,7 +663,10 @@ class Sandbox_Linux_x86_64(Sandbox, Arch_x86_64, OS_Linux): self.jitter.push_uint64_t(self.CALL_FINISH_ADDR) # Set the runtime guard - self.jitter.add_breakpoint(self.CALL_FINISH_ADDR, self.__class__.code_sentinelle) + self.jitter.add_breakpoint( + self.CALL_FINISH_ADDR, + self.__class__.code_sentinelle + ) def run(self, addr=None): """ @@ -661,14 +695,16 @@ class Sandbox_Linux_arml(Sandbox, Arch_arml, OS_Linux): if self.options.mimic_env: env_ptrs = [] for env in self.envp: - env += "\x00" + env = force_bytes(env) + env += b"\x00" self.jitter.cpu.SP -= len(env) ptr = self.jitter.cpu.SP self.jitter.vm.set_mem(ptr, env) env_ptrs.append(ptr) argv_ptrs = [] for arg in self.argv: - arg += "\x00" + arg = force_bytes(arg) + arg += b"\x00" self.jitter.cpu.SP -= len(arg) ptr = self.jitter.cpu.SP self.jitter.vm.set_mem(ptr, arg) @@ -688,7 +724,10 @@ class Sandbox_Linux_arml(Sandbox, Arch_arml, OS_Linux): self.jitter.cpu.LR = self.CALL_FINISH_ADDR # Set the runtime guard - self.jitter.add_breakpoint(self.CALL_FINISH_ADDR, self.__class__.code_sentinelle) + self.jitter.add_breakpoint( + self.CALL_FINISH_ADDR, + self.__class__.code_sentinelle + ) def run(self, addr=None): if addr is None and self.options.address is None: @@ -714,14 +753,16 @@ class Sandbox_Linux_armtl(Sandbox, Arch_armtl, OS_Linux): if self.options.mimic_env: env_ptrs = [] for env in self.envp: - env += "\x00" + env = force_bytes(env) + env += b"\x00" self.jitter.cpu.SP -= len(env) ptr = self.jitter.cpu.SP self.jitter.vm.set_mem(ptr, env) env_ptrs.append(ptr) argv_ptrs = [] for arg in self.argv: - arg += "\x00" + arg = force_bytes(arg) + arg += b"\x00" self.jitter.cpu.SP -= len(arg) ptr = self.jitter.cpu.SP self.jitter.vm.set_mem(ptr, arg) @@ -741,7 +782,10 @@ class Sandbox_Linux_armtl(Sandbox, Arch_armtl, OS_Linux): self.jitter.cpu.LR = self.CALL_FINISH_ADDR # Set the runtime guard - self.jitter.add_breakpoint(self.CALL_FINISH_ADDR, self.__class__.code_sentinelle) + self.jitter.add_breakpoint( + self.CALL_FINISH_ADDR, + self.__class__.code_sentinelle + ) def run(self, addr=None): if addr is None and self.options.address is None: @@ -768,14 +812,16 @@ class Sandbox_Linux_mips32b(Sandbox, Arch_mips32b, OS_Linux): if self.options.mimic_env: env_ptrs = [] for env in self.envp: - env += "\x00" + env = force_bytes(env) + env += b"\x00" self.jitter.cpu.SP -= len(env) ptr = self.jitter.cpu.SP self.jitter.vm.set_mem(ptr, env) env_ptrs.append(ptr) argv_ptrs = [] for arg in self.argv: - arg += "\x00" + arg = force_bytes(arg) + arg += b"\x00" self.jitter.cpu.SP -= len(arg) ptr = self.jitter.cpu.SP self.jitter.vm.set_mem(ptr, arg) @@ -792,7 +838,10 @@ class Sandbox_Linux_mips32b(Sandbox, Arch_mips32b, OS_Linux): self.jitter.cpu.RA = 0x1337beef # Set the runtime guard - self.jitter.add_breakpoint(0x1337beef, self.__class__.code_sentinelle) + self.jitter.add_breakpoint( + 0x1337beef, + self.__class__.code_sentinelle + ) def run(self, addr=None): if addr is None and self.options.address is None: @@ -850,14 +899,16 @@ class Sandbox_Linux_aarch64l(Sandbox, Arch_aarch64l, OS_Linux): if self.options.mimic_env: env_ptrs = [] for env in self.envp: - env += "\x00" + env = force_bytes(env) + env += b"\x00" self.jitter.cpu.SP -= len(env) ptr = self.jitter.cpu.SP self.jitter.vm.set_mem(ptr, env) env_ptrs.append(ptr) argv_ptrs = [] for arg in self.argv: - arg += "\x00" + arg = force_bytes(arg) + arg += b"\x00" self.jitter.cpu.SP -= len(arg) ptr = self.jitter.cpu.SP self.jitter.vm.set_mem(ptr, arg) @@ -874,7 +925,10 @@ class Sandbox_Linux_aarch64l(Sandbox, Arch_aarch64l, OS_Linux): self.jitter.cpu.LR = self.CALL_FINISH_ADDR # Set the runtime guard - self.jitter.add_breakpoint(self.CALL_FINISH_ADDR, self.__class__.code_sentinelle) + self.jitter.add_breakpoint( + self.CALL_FINISH_ADDR, + self.__class__.code_sentinelle + ) def run(self, addr=None): if addr is None and self.options.address is None: @@ -911,14 +965,16 @@ class Sandbox_Linux_ppc32b(Sandbox, Arch_ppc32b, OS_Linux): if self.options.mimic_env: env_ptrs = [] for env in self.envp: - env += "\x00" + env = force_bytes(env) + env += b"\x00" self.jitter.cpu.R1 -= len(env) ptr = self.jitter.cpu.R1 self.jitter.vm.set_mem(ptr, env) env_ptrs.append(ptr) argv_ptrs = [] for arg in self.argv: - arg += "\x00" + arg = force_bytes(arg) + arg += b"\x00" self.jitter.cpu.R1 -= len(arg) ptr = self.jitter.cpu.R1 self.jitter.vm.set_mem(ptr, arg) @@ -947,8 +1003,10 @@ class Sandbox_Linux_ppc32b(Sandbox, Arch_ppc32b, OS_Linux): self.jitter.cpu.LR = self.CALL_FINISH_ADDR # Set the runtime guard - self.jitter.add_breakpoint(self.CALL_FINISH_ADDR, - self.__class__.code_sentinelle) + self.jitter.add_breakpoint( + self.CALL_FINISH_ADDR, + self.__class__.code_sentinelle + ) def run(self, addr=None): """ diff --git a/miasm2/analysis/simplifier.py b/miasm2/analysis/simplifier.py index ca8e74fb..10d5e092 100644 --- a/miasm2/analysis/simplifier.py +++ b/miasm2/analysis/simplifier.py @@ -24,7 +24,7 @@ log.setLevel(logging.WARNING) def fix_point(func): @wraps(func) def ret_func(self, ircfg, head): - log.debug('[%s]: start', func.func_name) + log.debug('[%s]: start', func.__name__) has_been_modified = False modified = True while modified: @@ -32,7 +32,7 @@ def fix_point(func): has_been_modified |= modified log.debug( '[%s]: stop %r', - func.func_name, + func.__name__, has_been_modified ) return has_been_modified diff --git a/miasm2/analysis/ssa.py b/miasm2/analysis/ssa.py index 501cdd5e..54d17dc1 100644 --- a/miasm2/analysis/ssa.py +++ b/miasm2/analysis/ssa.py @@ -1,4 +1,5 @@ from collections import deque +from future.utils import viewitems, viewvalues from miasm2.expression.expression import ExprId, ExprAssign, ExprOp, \ ExprLoc, get_expr_ids @@ -246,7 +247,7 @@ class SSA(object): instructions = [] # insert SSA instructions for _ in assignblk: - instructions.append(ssa_iter.next()) + instructions.append(next(ssa_iter)) # replace instructions of assignblock in IRBlock new_irs.append(AssignBlock(instructions, assignblk.instr)) return IRBlock(irblock.loc_key, new_irs) @@ -576,7 +577,7 @@ class SSADiGraph(SSA): # if successor is in block's dominance frontier if successor in self._phinodes: # walk over all variables on LHS - for dst, src in self._phinodes[successor].iteritems(): + for dst, src in list(viewitems(self._phinodes[successor])): # transform variable on RHS in non-SSA form expr = self.reverse_variable(dst) # transform expr into it's SSA form using current stack @@ -618,7 +619,7 @@ class SSADiGraph(SSA): """ var_to_insert = set() for loc_key in self._phinodes: - for dst, sources in self._phinodes[loc_key].iteritems(): + for dst, sources in viewitems(self._phinodes[loc_key]): for src in sources.args: if src in self.ssa_variable_to_expr: continue @@ -641,14 +642,14 @@ class SSADiGraph(SSA): # Updt structure for loc_key in self._phinodes: - for dst, sources in self._phinodes[loc_key].items(): + for dst, sources in viewitems(self._phinodes[loc_key]): self._phinodes[loc_key][dst] = sources.replace_expr(var_to_newname) - for var, (loc_key, index) in self.ssa_to_location.items(): + for var, (loc_key, index) in list(viewitems(self.ssa_to_location)): if loc_key == head: self.ssa_to_location[var] = loc_key, index + 1 - for newname, var in newname_to_var.iteritems(): + for newname, var in viewitems(newname_to_var): self.ssa_to_location[newname] = head, 0 self.ssa_variable_to_expr[newname] = var self.expressions[newname] = var @@ -661,7 +662,7 @@ def irblock_has_phi(irblock): """ if not irblock.assignblks: return False - for src in irblock[0].itervalues(): + for src in viewvalues(irblock[0]): return src.is_op('Phi') return False @@ -765,7 +766,7 @@ class UnSSADiGraph(object): """ ircfg = self.ssa.graph - for irblock in ircfg.blocks.values(): + for irblock in list(viewvalues(ircfg.blocks)): if not irblock_has_phi(irblock): continue @@ -788,7 +789,7 @@ class UnSSADiGraph(object): for parent, src in self.phi_parent_sources[dst]: parent_to_parallel_copies.setdefault(parent, {})[new_var] = src - for parent, parallel_copies in parent_to_parallel_copies.iteritems(): + for parent, parallel_copies in viewitems(parent_to_parallel_copies): parent = ircfg.blocks[parent] assignblks = list(parent) assignblks.append(AssignBlock(parallel_copies, parent[-1].instr)) @@ -810,10 +811,10 @@ class UnSSADiGraph(object): node """ ircfg = self.ssa.graph - for irblock in ircfg.blocks.itervalues(): + for irblock in viewvalues(ircfg.blocks): if not irblock_has_phi(irblock): continue - for dst, sources in irblock[0].iteritems(): + for dst, sources in viewitems(irblock[0]): assert sources.is_op('Phi') new_var = self.create_copy_var(dst) self.phi_new_var[dst] = new_var @@ -836,7 +837,7 @@ class UnSSADiGraph(object): """ Generate trivial coalescing of phi variable and itself """ - for phi_new_var in self.phi_new_var.itervalues(): + for phi_new_var in viewvalues(self.phi_new_var): self.merge_state.setdefault(phi_new_var, set([phi_new_var])) def order_ssa_var_dom(self): @@ -1009,7 +1010,7 @@ class UnSSADiGraph(object): assignments. @parent: Optional parent location of the phi source for liveness tests """ - for dst, src in parallel_copies.iteritems(): + for dst, src in viewitems(parallel_copies): dst_merge = self.merge_state.setdefault(dst, set([dst])) src_merge = self.merge_state.setdefault(src, set([src])) if not self.merge_sets_interfere(dst_merge, src_merge, parent): @@ -1023,7 +1024,7 @@ class UnSSADiGraph(object): ircfg = self.ssa.graph # Run coalesce on the post phi parallel copy - for irblock in ircfg.blocks.values(): + for irblock in viewvalues(ircfg.blocks): if not irblock_has_phi(irblock): continue parallel_copies = {} @@ -1041,7 +1042,7 @@ class UnSSADiGraph(object): for parent, src in self.phi_parent_sources[dst]: parent_to_parallel_copies.setdefault(parent, {})[new_var] = src - for parent, parallel_copies in parent_to_parallel_copies.iteritems(): + for parent, parallel_copies in viewitems(parent_to_parallel_copies): self.aggressive_coalesce_parallel_copy(parallel_copies, parent) def get_best_merge_set_name(self, merge_set): @@ -1069,7 +1070,7 @@ class UnSSADiGraph(object): # Elect representative for merge sets merge_set_to_name = {} - for merge_set in self.merge_state.itervalues(): + for merge_set in viewvalues(self.merge_state): frozen_merge_set = frozenset(merge_set) merge_sets.add(frozen_merge_set) var_name = self.get_best_merge_set_name(merge_set) @@ -1090,10 +1091,10 @@ class UnSSADiGraph(object): @ircfg: IRDiGraph instance """ - for irblock in self.ssa.graph.blocks.values(): + for irblock in list(viewvalues(self.ssa.graph.blocks)): assignblks = list(irblock) out = {} - for dst, src in assignblks[0].iteritems(): + for dst, src in viewitems(assignblks[0]): if src.is_op('Phi'): assert set([dst]) == set(src.args) continue @@ -1105,11 +1106,11 @@ class UnSSADiGraph(object): """ Remove trivial expressions (a=a) in the current graph """ - for irblock in self.ssa.graph.blocks.values(): + for irblock in list(viewvalues(self.ssa.graph.blocks)): assignblks = list(irblock) for i, assignblk in enumerate(assignblks): out = {} - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): if dst == src: continue out[dst] = src diff --git a/miasm2/arch/aarch64/arch.py b/miasm2/arch/aarch64/arch.py index 015464d6..3a4f6446 100644 --- a/miasm2/arch/aarch64/arch.py +++ b/miasm2/arch/aarch64/arch.py @@ -1,13 +1,16 @@ #-*- coding:utf-8 -*- +from builtins import range +from future.utils import viewitems, viewvalues + import logging from pyparsing import * from miasm2.expression import expression as m2_expr from miasm2.core.cpu import * from collections import defaultdict from miasm2.core.bin_stream import bin_stream -import regs as regs_module -from regs import * +from miasm2.arch.aarch64 import regs as regs_module +from miasm2.arch.aarch64.regs import * from miasm2.core.cpu import log as log_cpu from miasm2.expression.modint import uint32, uint64, mod_size2int from miasm2.core.asm_ast import AstInt, AstId, AstMem, AstOp @@ -182,7 +185,7 @@ def cb_deref_nooff(t): def cb_deref_post(t): assert len(t) == 2 if isinstance(t[1], AstId) and isinstance(t[1].name, ExprId): - raise StopIteration + return result = AstOp("postinc", *t) return result @@ -190,7 +193,7 @@ def cb_deref_post(t): def cb_deref_pre(t): assert len(t) == 2 if isinstance(t[1], AstId) and isinstance(t[1].name, ExprId): - raise StopIteration + return result = AstOp("preinc", *t) return result @@ -198,7 +201,7 @@ def cb_deref_pre(t): def cb_deref_pre_wb(t): assert len(t) == 2 if isinstance(t[1], AstId) and isinstance(t[1].name, ExprId): - raise StopIteration + return result = AstOp("preinc_wb", *t) return result @@ -234,7 +237,7 @@ def cb_deref_ext2op(t): deref_ext2 = (LBRACK + gpregs_32_64 + COMMA + gpregs_32_64 + Optional(all_extend2_t + base_expr) + RBRACK).setParseAction(cb_deref_ext2op) -class additional_info: +class additional_info(object): def __init__(self): self.except_on_instr = False @@ -275,7 +278,7 @@ class aarch64_arg(m_arg): if isinstance(value.name, ExprId): fixed_size.add(value.name.size) return value.name - loc_key = loc_db.get_or_create_name_location(value.name) + loc_key = loc_db.get_or_create_name_location(value.name.encode()) return m2_expr.ExprLoc(loc_key, size_hint) if isinstance(value, AstInt): assert size_hint is not None @@ -446,7 +449,7 @@ class mn_aarch64(cls_mn): if n > bs.getlen() * 8: raise ValueError('not enough bits %r %r' % (n, len(bs.bin) * 8)) while n: - offset = start / 8 + offset = start // 8 n_offset = cls.endian_offset(attrib, offset) c = cls.getbytes(bs, n_offset, 1) if not c: @@ -897,11 +900,14 @@ class aarch64_gpreg_ext(reg_noarg, aarch64_arg): reg, m2_expr.ExprInt(self.parent.imm.value, reg.size)) return True -EXT2_OP = {0b010: 'UXTW', - 0b011: 'LSL', - 0b110: 'SXTW', - 0b111: 'SXTX'} -EXT2_OP_INV = dict([(items[1], items[0]) for items in EXT2_OP.items()]) +EXT2_OP = { + 0b010: 'UXTW', + 0b011: 'LSL', + 0b110: 'SXTW', + 0b111: 'SXTX' +} + +EXT2_OP_INV = dict((value, key) for key, value in viewitems(EXT2_OP)) class aarch64_gpreg_ext2(reg_noarg, aarch64_arg): @@ -933,7 +939,7 @@ class aarch64_gpreg_ext2(reg_noarg, aarch64_arg): reg = arg1 self.parent.option.value = 0b011 is_reg = True - elif isinstance(arg1, m2_expr.ExprOp) and arg1.op in EXT2_OP.values(): + elif isinstance(arg1, m2_expr.ExprOp) and arg1.op in viewvalues(EXT2_OP): reg = arg1.args[0] else: return False @@ -1069,10 +1075,15 @@ class bits(object): def __init__(self, size, value): """Instantiate a bitvector of size @size with value @value""" - self.size = size + value = int(value) + self.size = int(size) if value & self.mask != value: - raise ValueError("Value %s is too large for %d bits", - hex(value), size) + raise ValueError( + "Value %r is too large for %r bits (mask %r)", + value, + size, + self.mask + ) self.value = value def concat_left(self, other_bits): @@ -1123,11 +1134,11 @@ class bits(object): def __str__(self): return "'%s'" % "".join('1' if self.value & (1 << i) else '0' - for i in reversed(xrange(self.size))) + for i in reversed(range(self.size))) # From J1-6035 def HighestSetBit(x): - for i in reversed(xrange(x.size)): + for i in reversed(range(x.size)): if x.value & (1 << i): return i return - 1 @@ -1198,7 +1209,7 @@ def DecodeBitMasks(M, immN, imms, immr, immediate): def EncodeBitMasks(wmask): # Find replicate M = wmask.size - for i in xrange(1, M + 1): + for i in range(1, M + 1): if M % i != 0: continue if wmask == Replicate(wmask[:i], M): @@ -1211,7 +1222,7 @@ def EncodeBitMasks(wmask): esize = welem_after_ror.size S = welem_after_ror.pop_count - 1 welem = ZeroExtend(Ones(S + 1), esize) - for i in xrange(welem_after_ror.size): + for i in range(welem_after_ror.size): if ROR(welem, i) == welem_after_ror: break else: @@ -1219,7 +1230,7 @@ def EncodeBitMasks(wmask): R = i # Find len value - for i in xrange(M): + for i in range(M): if (1 << i) == esize: break else: @@ -1340,7 +1351,7 @@ class aarch64_imm_hw(aarch64_arg): return False value = int(self.expr) mask = (1 << size) - 1 - for i in xrange(size / 16): + for i in range(size // 16): if ((0xffff << (i * 16)) ^ mask) & value: continue self.parent.hw.value = i @@ -1384,10 +1395,10 @@ class aarch64_imm_hw_sc(aarch64_arg): arg, amount = [int(arg) for arg in self.expr.args] if arg > 0xFFFF: return False - if amount % 16 or amount / 16 > 4: + if amount % 16 or amount // 16 > 4: return False self.value = arg - self.parent.hw.value = amount / 16 + self.parent.hw.value = amount // 16 return True @@ -1852,8 +1863,8 @@ bcond = bs_mod_name(l=4, fname='cond', mn_mod=['EQ', 'NE', 'CS', 'CC', 'HI', 'LS', 'GE', 'LT', 'GT', 'LE', 'AL', 'NV']) -cond_arg = bs(l=4, cls=(aarch64_cond_arg,), fname=cond) -cond_inv_arg = bs(l=4, cls=(aarch64_cond_inv_arg,), fname=cond) +cond_arg = bs(l=4, cls=(aarch64_cond_arg,), fname="cond") +cond_inv_arg = bs(l=4, cls=(aarch64_cond_inv_arg,), fname="cond") # unconditional branch (ret) aarch64op("br", [bs('1101011'), bs('0000'), bs('11111'), bs('000000'), rn64, bs('00000')], [rn64]) aarch64op("blr", [bs('1101011'), bs('0001'), bs('11111'), bs('000000'), rn64, bs('00000')], [rn64]) @@ -2037,7 +2048,7 @@ aarch64op("fcvt", [bs('000'), bs('11110'), bs('01'), bs('1'), bs('0001'), bs('0 -swapargs = bs_swapargs(l=1, fname="swap", mn_mod=range(1 << 1)) +swapargs = bs_swapargs(l=1, fname="swap", mn_mod=list(range(1 << 1))) aarch64op("fmov", [bs('0'), bs('00'), bs('11110'), bs('00'), bs('1'), bs('00'), bs('110'), bs('000000'), sn32, rd32], [rd32, sn32]) aarch64op("fmov", [bs('0'), bs('00'), bs('11110'), bs('00'), bs('1'), bs('00'), bs('111'), bs('000000'), rn32, sd32], [sd32, rn32]) diff --git a/miasm2/arch/aarch64/jit.py b/miasm2/arch/aarch64/jit.py index 9873464a..57b896d3 100644 --- a/miasm2/arch/aarch64/jit.py +++ b/miasm2/arch/aarch64/jit.py @@ -1,3 +1,4 @@ +from builtins import range import logging from miasm2.jitter.jitload import Jitter, named_arguments @@ -35,9 +36,9 @@ class jitter_aarch64l(Jitter): @named_arguments def func_args_stdcall(self, n_args): args = [] - for i in xrange(min(n_args, self.max_reg_arg)): + for i in range(min(n_args, self.max_reg_arg)): args.append(getattr(self.cpu, 'X%d' % i)) - for i in xrange(max(0, n_args - self.max_reg_arg)): + for i in range(max(0, n_args - self.max_reg_arg)): args.append(self.get_stack_arg(i)) ret_ad = self.cpu.LR return ret_ad, args @@ -56,9 +57,9 @@ class jitter_aarch64l(Jitter): return arg def func_prepare_stdcall(self, ret_addr, *args): - for index in xrange(min(len(args), 4)): + for index in range(min(len(args), 4)): setattr(self.cpu, 'X%d' % index, args[index]) - for index in xrange(4, len(args)): + for index in range(4, len(args)): self.vm.set_mem(self.cpu.SP + 8 * (index - 4), pck64(args[index])) self.cpu.LR = ret_addr diff --git a/miasm2/arch/aarch64/regs.py b/miasm2/arch/aarch64/regs.py index 1c693b4c..7ddcc0b8 100644 --- a/miasm2/arch/aarch64/regs.py +++ b/miasm2/arch/aarch64/regs.py @@ -1,5 +1,6 @@ #-*- coding:utf-8 -*- +from builtins import range from miasm2.expression.expression import ExprId from miasm2.core.cpu import gen_reg, gen_regs @@ -7,40 +8,40 @@ exception_flags = ExprId('exception_flags', 32) interrupt_num = ExprId('interrupt_num', 32) -gpregs32_str = ["W%d" % i for i in xrange(0x1f)] + ["WSP"] +gpregs32_str = ["W%d" % i for i in range(0x1f)] + ["WSP"] gpregs32_expr, gpregs32_init, gpregs32_info = gen_regs( gpregs32_str, globals(), 32) -gpregs64_str = ["X%d" % i for i in xrange(0x1E)] + ["LR", "SP"] +gpregs64_str = ["X%d" % i for i in range(0x1E)] + ["LR", "SP"] gpregs64_expr, gpregs64_init, gpregs64_info = gen_regs( gpregs64_str, globals(), 64) -gpregsz32_str = ["W%d" % i for i in xrange(0x1f)] + ["WZR"] +gpregsz32_str = ["W%d" % i for i in range(0x1f)] + ["WZR"] gpregsz32_expr, gpregsz32_init, gpregsz32_info = gen_regs( gpregsz32_str, globals(), 32) -gpregsz64_str = ["X%d" % i for i in xrange(0x1e)] + ["LR", "XZR"] +gpregsz64_str = ["X%d" % i for i in range(0x1e)] + ["LR", "XZR"] gpregsz64_expr, gpregsz64_init, gpregsz64_info = gen_regs( gpregsz64_str, globals(), 64) -cr_str = ["c%d" % i for i in xrange(0xf)] +cr_str = ["c%d" % i for i in range(0xf)] cr_expr, cr_init, cr_info = gen_regs(cr_str, globals(), 32) -simd08_str = ["B%d" % i for i in xrange(0x20)] +simd08_str = ["B%d" % i for i in range(0x20)] simd08_expr, simd08_init, simd08_info = gen_regs(simd08_str, globals(), 8) -simd16_str = ["H%d" % i for i in xrange(0x20)] +simd16_str = ["H%d" % i for i in range(0x20)] simd16_expr, simd16_init, simd16_info = gen_regs(simd16_str, globals(), 16) -simd32_str = ["S%d" % i for i in xrange(0x20)] +simd32_str = ["S%d" % i for i in range(0x20)] simd32_expr, simd32_init, simd32_info = gen_regs(simd32_str, globals(), 32) -simd64_str = ["D%d" % i for i in xrange(0x20)] +simd64_str = ["D%d" % i for i in range(0x20)] simd64_expr, simd64_init, simd64_info = gen_regs(simd64_str, globals(), 64) -simd128_str = ["Q%d" % i for i in xrange(0x20)] +simd128_str = ["Q%d" % i for i in range(0x20)] simd128_expr, simd128_init, simd128_info = gen_regs( simd128_str, globals(), 128) diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py index 7052f423..a840f6b6 100644 --- a/miasm2/arch/aarch64/sem.py +++ b/miasm2/arch/aarch64/sem.py @@ -1,3 +1,6 @@ +from builtins import range +from future.utils import viewitems + from miasm2.expression.expression import ExprId, ExprInt, ExprLoc, ExprMem, \ ExprCond, ExprCompose, ExprOp, ExprAssign from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock @@ -675,7 +678,7 @@ def stp(ir, instr, arg1, arg2, arg3): addr, updt = get_mem_access(arg3) e.append(ExprAssign(ExprMem(addr, arg1.size), arg1)) e.append( - ExprAssign(ExprMem(addr + ExprInt(arg1.size / 8, addr.size), arg2.size), arg2)) + ExprAssign(ExprMem(addr + ExprInt(arg1.size // 8, addr.size), arg2.size), arg2)) if updt: e.append(updt) return e, [] @@ -686,7 +689,7 @@ def ldp(ir, instr, arg1, arg2, arg3): addr, updt = get_mem_access(arg3) e.append(ExprAssign(arg1, ExprMem(addr, arg1.size))) e.append( - ExprAssign(arg2, ExprMem(addr + ExprInt(arg1.size / 8, addr.size), arg2.size))) + ExprAssign(arg2, ExprMem(addr + ExprInt(arg1.size // 8, addr.size), arg2.size))) if updt: e.append(updt) return e, [] @@ -1012,7 +1015,7 @@ def nop(): def rev(ir, instr, arg1, arg2): out = [] - for i in xrange(0, arg2.size, 8): + for i in range(0, arg2.size, 8): out.append(arg2[i:i+8]) out.reverse() e = [] @@ -1023,7 +1026,7 @@ def rev(ir, instr, arg1, arg2): def rev16(ir, instr, arg1, arg2): out = [] - for i in xrange(0, arg2.size / 8): + for i in range(0, arg2.size // 8): index = (i & ~1) + (1 - (i & 1)) out.append(arg2[index * 8:(index + 1) * 8]) e = [] @@ -1248,8 +1251,8 @@ def casp(ir, instr, arg1, arg2, arg3): blk_store = IRBlock(loc_store.loc_key, [AssignBlock(e_store, instr)]) e_do = [] - e_do.append(ExprAssign(regs[index1], data[:data.size / 2])) - e_do.append(ExprAssign(regs[index1 + 1], data[data.size / 2:])) + e_do.append(ExprAssign(regs[index1], data[:data.size // 2])) + e_do.append(ExprAssign(regs[index1 + 1], data[data.size // 2:])) e_do.append(ExprAssign(ir.IRDst, loc_next)) blk_do = IRBlock(loc_do.loc_key, [AssignBlock(e_do, instr)]) @@ -1399,7 +1402,7 @@ def get_mnemo_expr(ir, instr, *args): return instr, extra_ir -class aarch64info: +class aarch64info(object): mode = "aarch64" # offset @@ -1438,7 +1441,7 @@ class ir_aarch64l(IntermediateRepresentation): irs = [] for assignblk in irblock: new_assignblk = dict(assignblk) - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): del(new_assignblk[dst]) # Special case for 64 bits: # If destination is a 32 bit reg, zero extend the 64 bit reg @@ -1480,8 +1483,10 @@ class ir_aarch64l(IntermediateRepresentation): for irblock in extra_ir: irs = [] for assignblk in irblock: - new_dsts = {dst:src for dst, src in assignblk.iteritems() - if dst not in regs_to_fix} + new_dsts = { + dst:src for dst, src in viewitems(assignblk) + if dst not in regs_to_fix + } irs.append(AssignBlock(new_dsts, assignblk.instr)) new_irblocks.append(IRBlock(irblock.loc_key, irs)) diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py index c50748e4..3cafad59 100644 --- a/miasm2/arch/arm/arch.py +++ b/miasm2/arch/arm/arch.py @@ -1,5 +1,8 @@ #-*- coding:utf-8 -*- +from builtins import range +from future.utils import viewitems + import logging from pyparsing import * from miasm2.expression.expression import * @@ -24,7 +27,7 @@ reg_dum = ExprId('DumReg', 32) PC, _ = gen_reg('PC') # GP -regs_str = ['R%d' % r for r in xrange(0x10)] +regs_str = ['R%d' % r for r in range(0x10)] regs_str[13] = 'SP' regs_str[14] = 'LR' regs_str[15] = 'PC' @@ -49,9 +52,9 @@ gpregs_nosp = reg_info(regs_str[:13] + [str(reg_dum), regs_str[14], regs_str[15] sr_flags = "cxsf" cpsr_regs_str = [] spsr_regs_str = [] -for i in xrange(0x10): +for i in range(0x10): o = "" - for j in xrange(4): + for j in range(4): if i & (1 << j): o += sr_flags[j] cpsr_regs_str.append("CPSR_%s" % o) @@ -69,13 +72,13 @@ cpsr_regs = reg_info(cpsr_regs_str, cpsr_regs_expr) spsr_regs = reg_info(spsr_regs_str, spsr_regs_expr) # CP -cpregs_str = ['c%d' % r for r in xrange(0x10)] +cpregs_str = ['c%d' % r for r in range(0x10)] cpregs_expr = [ExprId(x, 32) for x in cpregs_str] cp_regs = reg_info(cpregs_str, cpregs_expr) # P -pregs_str = ['p%d' % r for r in xrange(0x10)] +pregs_str = ['p%d' % r for r in range(0x10)] pregs_expr = [ExprId(x, 32) for x in pregs_str] p_regs = reg_info(pregs_str, pregs_expr) @@ -110,7 +113,7 @@ def cb_tok_reg_duo(tokens): i1 = gpregs.expr.index(tokens[0].name) i2 = gpregs.expr.index(tokens[1].name) o = [] - for i in xrange(i1, i2 + 1): + for i in range(i1, i2 + 1): o.append(AstId(gpregs.expr[i])) return o @@ -155,7 +158,7 @@ allshifts_armt = ['<<', '>>', 'a>>', '>>>', 'rrx'] shift2expr_dct = {'LSL': '<<', 'LSR': '>>', 'ASR': 'a>>', 'ROR': ">>>", 'RRX': "rrx"} -expr2shift_dct = dict([(x[1], x[0]) for x in shift2expr_dct.items()]) +expr2shift_dct = dict((value, key) for key, value in viewitems(shift2expr_dct)) def op_shift2expr(tokens): @@ -321,13 +324,13 @@ def permut_args(order, args): for i, x in enumerate(order): l.append((x.__class__, i)) l = dict(l) - out = [None for x in xrange(len(args))] + out = [None for x in range(len(args))] for a in args: out[l[a.__class__]] = a return out -class additional_info: +class additional_info(object): def __init__(self): self.except_on_instr = False @@ -400,8 +403,10 @@ class instruction_arm(instruction): else: r, s = expr.args[0].args if isinstance(s, ExprOp) and s.op in expr2shift_dct: - s = ' '.join([str(x) - for x in s.args[0], expr2shift_dct[s.op], s.args[1]]) + s = ' '.join( + str(x) + for x in (s.args[0], expr2shift_dct[s.op], s.args[1]) + ) if isinstance(expr, ExprOp) and expr.op == 'postinc': o = '[%s]' % r @@ -563,7 +568,7 @@ class instruction_armt(instruction_arm): def get_asm_offset(self, expr): # ADR XXX, PC, imm => PC is 4 aligned + imm - new_offset = ((self.offset+self.l)/4)*4 + new_offset = ((self.offset + self.l) // 4) * 4 return ExprInt(new_offset, expr.size) @@ -610,7 +615,7 @@ class mn_arm(cls_mn): if n > bs.getlen() * 8: raise ValueError('not enough bits %r %r' % (n, len(bs.bin) * 8)) while n: - offset = start / 8 + offset = start // 8 n_offset = cls.endian_offset(attrib, offset) c = cls.getbytes(bs, n_offset, 1) if not c: @@ -711,7 +716,7 @@ class mn_armt(cls_mn): if n > bs.getlen() * 8: raise ValueError('not enough bits %r %r' % (n, len(bs.bin) * 8)) while n: - offset = start / 8 + offset = start // 8 n_offset = cls.endian_offset(attrib, offset) c = cls.getbytes(bs, n_offset, 1) if not c: @@ -784,7 +789,7 @@ class arm_arg(m_arg): return arg.name if arg.name in gpregs.str: return None - loc_key = loc_db.get_or_create_name_location(arg.name) + loc_key = loc_db.get_or_create_name_location(arg.name.encode()) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] @@ -1025,10 +1030,10 @@ class arm_op2(arm_arg): def str_to_imm_rot_form(self, s, neg=False): if neg: s = -s & 0xffffffff - for i in xrange(0, 32, 2): + for i in range(0, 32, 2): v = myrol32(s, i) if 0 <= v < 0x100: - return ((i / 2) << 8) | v + return ((i // 2) << 8) | v return None def decode(self, v): @@ -1267,7 +1272,7 @@ class arm_rlist(arm_arg): def decode(self, v): v = v & self.lmask out = [] - for i in xrange(0x10): + for i in range(0x10): if 1 << i & v: out.append(gpregs.expr[i]) if not out: @@ -1616,7 +1621,7 @@ data_test_name = {'TST': 8, 'TEQ': 9, 'CMP': 10, 'CMN': 11} data_name = {} for i, n in enumerate(op_list): - if n in data_mov_name.keys() + data_test_name.keys(): + if n in list(data_mov_name) + list(data_test_name): continue data_name[n] = i bs_data_name = bs_name(l=4, name=data_name) @@ -1740,7 +1745,7 @@ class arm_rm_rot2(arm_arg): value = int(value) if not value in [8, 16, 24]: return False - self.parent.rot2.value = value / 8 + self.parent.rot2.value = value // 8 return True class arm_gpreg_nopc(reg_noarg): @@ -2052,7 +2057,7 @@ class armt_rlist(arm_arg): def decode(self, v): v = v & self.lmask out = [] - for i in xrange(0x10): + for i in range(0x10): if 1 << i & v: out.append(gpregs.expr[i]) if not out: @@ -2093,7 +2098,7 @@ class armt_rlist13(armt_rlist): def decode(self, v): v = v & self.lmask out = [] - for i in xrange(13): + for i in range(13): if 1 << i & v: out.append(gpregs_l_13.expr[i]) @@ -2141,7 +2146,7 @@ class armt_rlist13_pc_lr(armt_rlist): def decode(self, v): v = v & self.lmask out = [] - for i in xrange(13): + for i in range(13): if 1 << i & v: out.append(gpregs_l_13.expr[i]) @@ -2184,7 +2189,7 @@ class armt_rlist_pclr(armt_rlist): def decode(self, v): v = v & self.lmask out = [] - for i in xrange(0x10): + for i in range(0x10): if 1 << i & v: out.append(gpregs.expr[i]) @@ -2522,7 +2527,7 @@ class armt2_imm12(arm_imm): value = (3 << 8) | ((v >> 16) & 0xff) else: # rol encoding - for i in xrange(32): + for i in range(32): o = myrol32(v, i) if 0x80 <= o <= 0xFF: value = (i << 7) | (o & 0x7F) @@ -2860,7 +2865,7 @@ class armt_itmask(bs_divert): def divert(self, i, candidates): out = [] for cls, _, bases, dct, fields in candidates: - for value in xrange(1, 0x10): + for value in range(1, 0x10): nfields = fields[:] s = int2bin(value, self.args['l']) args = dict(self.args) @@ -2881,7 +2886,7 @@ class armt_itmask(bs_divert): values = ['E', 'T'] if inv== 1: values.reverse() - for index in xrange(3 - count): + for index in range(3 - count): if value & (1 << (3 - index)): out.append(values[0]) else: @@ -2896,7 +2901,7 @@ class armt_cond_lsb(bs_divert): def divert(self, i, candidates): out = [] for cls, _, bases, dct, fields in candidates: - for value in xrange(2): + for value in range(2): nfields = fields[:] s = int2bin(value, self.args['l']) args = dict(self.args) diff --git a/miasm2/arch/arm/disasm.py b/miasm2/arch/arm/disasm.py index 5e21778d..2a443cc2 100644 --- a/miasm2/arch/arm/disasm.py +++ b/miasm2/arch/arm/disasm.py @@ -1,3 +1,5 @@ +from future.utils import viewvalues + from miasm2.core.asmblock import AsmConstraint, disasmEngine from miasm2.arch.arm.arch import mn_arm, mn_armt @@ -19,7 +21,7 @@ def cb_arm_fix_call(mn, cur_bloc, loc_db, offsets_to_dis, *args, **kwargs): if l2.name != "MOV": return - values = mn.pc.values() + values = viewvalues(mn.pc) if not l1.args[0] in values: return if not l2.args[1] in values: diff --git a/miasm2/arch/arm/jit.py b/miasm2/arch/arm/jit.py index 06fba210..128baffb 100644 --- a/miasm2/arch/arm/jit.py +++ b/miasm2/arch/arm/jit.py @@ -1,3 +1,4 @@ +from builtins import range import logging from miasm2.jitter.jitload import Jitter, named_arguments @@ -85,7 +86,7 @@ class jitter_arml(Jitter): @named_arguments def func_args_stdcall(self, n_args): - args = [self.get_arg_n_stdcall(i) for i in xrange(n_args)] + args = [self.get_arg_n_stdcall(i) for i in range(n_args)] ret_ad = self.cpu.LR return ret_ad, args @@ -98,9 +99,9 @@ class jitter_arml(Jitter): return True def func_prepare_stdcall(self, ret_addr, *args): - for index in xrange(min(len(args), 4)): + for index in range(min(len(args), 4)): setattr(self.cpu, 'R%d' % index, args[index]) - for index in reversed(xrange(4, len(args))): + for index in reversed(range(4, len(args))): self.push_uint32_t(args[index]) self.cpu.LR = ret_addr diff --git a/miasm2/arch/arm/regs.py b/miasm2/arch/arm/regs.py index e20b00bd..f39f2161 100644 --- a/miasm2/arch/arm/regs.py +++ b/miasm2/arch/arm/regs.py @@ -1,11 +1,12 @@ #-*- coding:utf-8 -*- +from builtins import range from miasm2.expression.expression import * # GP -regs32_str = ["R%d" % i for i in xrange(13)] + ["SP", "LR", "PC"] +regs32_str = ["R%d" % i for i in range(13)] + ["SP", "LR", "PC"] regs32_expr = [ExprId(x, 32) for x in regs32_str] exception_flags = ExprId('exception_flags', 32) diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py index 782a99fb..6622a42a 100644 --- a/miasm2/arch/arm/sem.py +++ b/miasm2/arch/arm/sem.py @@ -1,3 +1,6 @@ +from builtins import range +from future.utils import viewitems, viewvalues + from miasm2.expression.expression import * from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock from miasm2.arch.arm.arch import mn_arm, mn_armt @@ -1053,7 +1056,7 @@ def rors(ir, instr, a, b): def push(ir, instr, a): e = [] regs = list(a.args) - for i in xrange(len(regs)): + for i in range(len(regs)): r = SP + ExprInt(-4 * len(regs) + 4 * i, 32) e.append(ExprAssign(ExprMem(r, 32), regs[i])) r = SP + ExprInt(-4 * len(regs), 32) @@ -1065,7 +1068,7 @@ def pop(ir, instr, a): e = [] regs = list(a.args) dst = None - for i in xrange(len(regs)): + for i in range(len(regs)): r = SP + ExprInt(4 * i, 32) e.append(ExprAssign(regs[i], ExprMem(r, 32))) if regs[i] == ir.pc: @@ -1271,7 +1274,7 @@ def uadd8(ir, instr, a, b, c): e = [] sums = [] ges = [] - for i in xrange(0, 32, 8): + for i in range(0, 32, 8): sums.append(b[i:i+8] + c[i:i+8]) ges.append((b[i:i+8].zeroExtend(9) + c[i:i+8].zeroExtend(9))[8:9]) @@ -1286,7 +1289,7 @@ def sel(ir, instr, a, b, c): e = [] cond = nf ^ of ^ ExprInt(1, 1) parts = [] - for i in xrange(4): + for i in range(4): parts.append(ExprCond(ge_regs[i], b[i*8:(i+1)*8], c[i*8:(i+1)*8])) result = ExprCompose(*parts) e.append(ExprAssign(a, result)) @@ -1382,7 +1385,7 @@ cond_dct = { # COND_NV: "NV", } -cond_dct_inv = dict((name, num) for num, name in cond_dct.iteritems()) +cond_dct_inv = dict((name, num) for num, name in viewitems(cond_dct)) """ @@ -1425,7 +1428,7 @@ tab_cond = {COND_EQ: ExprOp("CC_EQ", zf), def is_pc_written(ir, instr_ir): - all_pc = ir.mn.pc.values() + all_pc = viewvalues(ir.mn.pc) for ir in instr_ir: if ir.dst in all_pc: return True, ir.dst @@ -1613,8 +1616,8 @@ mn_cond_x = [mnemo_condm0, mnemo_condm2] for index, mn_base in enumerate(mn_cond_x): - for mn, mf in mn_base.items(): - for cond, cn in cond_dct.items(): + for mn, mf in viewitems(mn_base): + for cond, cn in viewitems(cond_dct): if cond == COND_AL: cn = "" cn = cn.lower() @@ -1625,7 +1628,7 @@ for index, mn_base in enumerate(mn_cond_x): # print mn_mod mnemo_func_cond[mn_mod] = cond, mf -for name, mf in mnemo_nocond.items(): +for name, mf in viewitems(mnemo_nocond): mnemo_func_cond[name] = COND_AL, mf @@ -1652,7 +1655,7 @@ def get_mnemo_expr(ir, instr, *args): get_arm_instr_expr = get_mnemo_expr -class arminfo: +class arminfo(object): mode = "arm" # offset @@ -1775,7 +1778,7 @@ class ir_arml(IntermediateRepresentation): for assignment in assignments: assignment = AssignBlock( { - dst:src for (dst, src) in assignment.iteritems() + dst: src for (dst, src) in viewitems(assignment) if dst not in [zf, nf, of, cf] }, assignment.instr @@ -1789,7 +1792,7 @@ class ir_arml(IntermediateRepresentation): for tmp_assignment in irblock: assignment = AssignBlock( { - dst:src for (dst, src) in assignment.iteritems() + dst: src for (dst, src) in viewitems(assignment) if dst not in [zf, nf, of, cf] }, assignment.instr diff --git a/miasm2/arch/mep/arch.py b/miasm2/arch/mep/arch.py index e4d66a63..2266b596 100644 --- a/miasm2/arch/mep/arch.py +++ b/miasm2/arch/mep/arch.py @@ -1,6 +1,7 @@ # Toshiba MeP-c4 - miasm architecture definition # Guillaume Valadon <guillaume@valadon.net> +from builtins import range from miasm2.core.cpu import * from miasm2.core.utils import Disasm_Exception from miasm2.expression.expression import Expr, ExprId, ExprInt, ExprLoc, \ @@ -279,7 +280,7 @@ class instruction_mep(instruction): self.args[num] = ExprInt(off, 32) -class mep_additional_info: +class mep_additional_info(object): """Additional MeP instructions information """ @@ -432,7 +433,7 @@ class mn_mep(cls_mn): o = 0 # the returned value while n: # Get a byte, the offset is adjusted according to the endianness - offset = start / 8 # the offset in bytes + offset = start // 8 # the offset in bytes n_offset = cls.endian_offset(attrib, offset) # the adjusted offset c = cls.getbytes(bitstream, n_offset, 1) if not c: @@ -552,7 +553,7 @@ class mep_arg(m_arg): return arg.name if isinstance(arg.name, str) and arg.name in gpr_names: return None # GV: why? - loc_key = loc_db.get_or_create_name_location(arg.name) + loc_key = loc_db.get_or_create_name_location(arg.name.encode()) return ExprLoc(loc_key, 32) elif isinstance(arg, AstMem): diff --git a/miasm2/arch/mep/regs.py b/miasm2/arch/mep/regs.py index a515e76a..88248823 100644 --- a/miasm2/arch/mep/regs.py +++ b/miasm2/arch/mep/regs.py @@ -1,6 +1,7 @@ # Toshiba MeP-c4 - miasm registers definition # Guillaume Valadon <guillaume@valadon.net> +from builtins import range from miasm2.expression.expression import ExprId from miasm2.core.cpu import reg_info, gen_reg, gen_regs @@ -19,7 +20,7 @@ in_erepeat_init = ExprId("take_jmp_init", 32) # General-purpose registers (R0 to R15) names -gpr_names = ["R%d" % r for r in xrange(13)] # register names +gpr_names = ["R%d" % r for r in range(13)] # register names gpr_names += ["TP", "GP", "SP"] # according to the manual GP does not exist gpr_exprs, gpr_inits, gpr_infos = gen_regs(gpr_names, globals()) # sz=32 bits (default) @@ -53,7 +54,7 @@ RPC = csr_exprs[6] # Repeat Counter. On MeP, it is the special register R6 # Coprocesssor general-purpose registers (C0 to C15) names # Note: a processor extension allows up to 32 coprocessor general-purpose registers -copro_gpr_names = ["C%d" % r for r in xrange(32)] # register names +copro_gpr_names = ["C%d" % r for r in range(32)] # register names copro_gpr_exprs, copro_gpr_inits, copro_gpr_infos = gen_regs(copro_gpr_names, globals()) diff --git a/miasm2/arch/mep/sem.py b/miasm2/arch/mep/sem.py index fb67becd..c346c535 100644 --- a/miasm2/arch/mep/sem.py +++ b/miasm2/arch/mep/sem.py @@ -929,15 +929,15 @@ def div(rn, rm): tmp_rm_inv = rm_inv if rm_inv else i32(1) # Results if only rn, or rm is negative - LO_rn_neg = (~(rn_inv / tmp_rm) + i32(1)) if sign_rn else (~(rn / tmp_rm_inv) + i32(1)) + LO_rn_neg = (~(rn_inv // tmp_rm) + i32(1)) if sign_rn else (~(rn // tmp_rm_inv) + i32(1)) HI_rn_neg = (~(rn_inv % tmp_rm) + i32(1)) if sign_rn else (~(rn % tmp_rm_inv) + i32(1)) # Results if both numbers are positive - LO_pos = rn / tmp_rm if are_both_pos else LO_rn_neg + LO_pos = rn // tmp_rm if are_both_pos else LO_rn_neg HI_pos = rn % tmp_rm if are_both_pos else HI_rn_neg # Results if both numbers are negative - LO_neg = rn_inv / tmp_rm_inv if are_both_neg else LO_pos + LO_neg = rn_inv // tmp_rm_inv if are_both_neg else LO_pos HI_neg = rn_inv % tmp_rm_inv if are_both_neg else HI_pos # Results if rm is equal to zero @@ -954,7 +954,7 @@ def divu(rn, rm): # LO <- Rn / Rm, HI <- Rn % Rm (Unsigned) tmp_rm = rm if rm else i32(1) # used to delay the arithmetic computations - LO = rn / tmp_rm if rm else LO + LO = rn // tmp_rm if rm else LO HI = rn % tmp_rm if rm else HI exception_flags = i32(0) if rm else i32(EXCEPT_DIV_BY_ZERO) diff --git a/miasm2/arch/mips32/arch.py b/miasm2/arch/mips32/arch.py index 75a1aff0..6046b12c 100644 --- a/miasm2/arch/mips32/arch.py +++ b/miasm2/arch/mips32/arch.py @@ -42,7 +42,7 @@ deref_nooff = (LPARENTHESIS + gpregs.parser + RPARENTHESIS).setParseAction(cb_de deref = deref_off | deref_nooff -class additional_info: +class additional_info(object): def __init__(self): self.except_on_instr = False @@ -200,7 +200,7 @@ class mn_mips32(cpu.cls_mn): return 0 o = 0 while n: - offset = start / 8 + offset = start // 8 n_offset = cls.endian_offset(attrib, offset) c = cls.getbytes(bitstream, n_offset, 1) if not c: @@ -265,7 +265,7 @@ class mips32_arg(cpu.m_arg): return arg.name if arg.name in gpregs.str: return None - loc_key = loc_db.get_or_create_name_location(arg.name) + loc_key = loc_db.get_or_create_name_location(arg.name.encode()) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] diff --git a/miasm2/arch/mips32/jit.py b/miasm2/arch/mips32/jit.py index 4abe0cd4..04690a3e 100644 --- a/miasm2/arch/mips32/jit.py +++ b/miasm2/arch/mips32/jit.py @@ -1,3 +1,4 @@ +from builtins import range import logging from miasm2.jitter.jitload import Jitter, named_arguments @@ -109,7 +110,7 @@ class jitter_mips32l(Jitter): @named_arguments def func_args_stdcall(self, n_args): - args = [self.get_arg_n_stdcall(i) for i in xrange(n_args)] + args = [self.get_arg_n_stdcall(i) for i in range(n_args)] ret_ad = self.cpu.RA return ret_ad, args @@ -122,9 +123,9 @@ class jitter_mips32l(Jitter): return True def func_prepare_stdcall(self, ret_addr, *args): - for index in xrange(min(len(args), 4)): + for index in range(min(len(args), 4)): setattr(self.cpu, 'A%d' % index, args[index]) - for index in xrange(4, len(args)): + for index in range(4, len(args)): self.vm.set_mem(self.cpu.SP + 4 * (index - 4), pck32(args[index])) self.cpu.RA = ret_addr diff --git a/miasm2/arch/mips32/regs.py b/miasm2/arch/mips32/regs.py index ddaaff79..d1d14bdc 100644 --- a/miasm2/arch/mips32/regs.py +++ b/miasm2/arch/mips32/regs.py @@ -1,5 +1,6 @@ #-*- coding:utf-8 -*- +from builtins import range from miasm2.expression.expression import ExprId from miasm2.core.cpu import gen_reg, gen_regs @@ -16,19 +17,19 @@ PC_init = ExprId("PC_init", 32) PC_FETCH_init = ExprId("PC_FETCH_init", 32) regs32_str = ["ZERO", 'AT', 'V0', 'V1'] +\ - ['A%d'%i for i in xrange(4)] +\ - ['T%d'%i for i in xrange(8)] +\ - ['S%d'%i for i in xrange(8)] +\ - ['T%d'%i for i in xrange(8, 10)] +\ + ['A%d'%i for i in range(4)] +\ + ['T%d'%i for i in range(8)] +\ + ['S%d'%i for i in range(8)] +\ + ['T%d'%i for i in range(8, 10)] +\ ['K0', 'K1'] +\ ['GP', 'SP', 'FP', 'RA'] regs32_expr = [ExprId(x, 32) for x in regs32_str] ZERO = regs32_expr[0] -regs_flt_str = ['F%d'%i for i in xrange(0x20)] +regs_flt_str = ['F%d'%i for i in range(0x20)] -regs_fcc_str = ['FCC%d'%i for i in xrange(8)] +regs_fcc_str = ['FCC%d'%i for i in range(8)] R_LO = ExprId('R_LO', 32) R_HI = ExprId('R_HI', 32) @@ -37,7 +38,7 @@ R_LO_init = ExprId('R_LO_init', 32) R_HI_init = ExprId('R_HI_init', 32) -cpr0_str = ["CPR0_%d"%x for x in xrange(0x100)] +cpr0_str = ["CPR0_%d"%x for x in range(0x100)] cpr0_str[0] = "INDEX" cpr0_str[16] = "ENTRYLO0" cpr0_str[24] = "ENTRYLO1" diff --git a/miasm2/arch/msp430/arch.py b/miasm2/arch/msp430/arch.py index f0db98f3..fd31f6c4 100644 --- a/miasm2/arch/msp430/arch.py +++ b/miasm2/arch/msp430/arch.py @@ -1,5 +1,7 @@ #-*- coding:utf-8 -*- +from builtins import range + import logging from pyparsing import * from miasm2.expression.expression import * @@ -69,7 +71,7 @@ class msp430_arg(m_arg): index = gpregs.str.index(name) reg = gpregs.expr[index] return reg - loc_key = loc_db.get_or_create_name_location(value.name) + loc_key = loc_db.get_or_create_name_location(value.name.encode()) return ExprLoc(loc_key, 16) if isinstance(value, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in value.args] @@ -86,7 +88,7 @@ class msp430_arg(m_arg): return None -class additional_info: +class additional_info(object): def __init__(self): self.except_on_instr = False @@ -238,7 +240,7 @@ class mn_msp430(cls_mn): if n > bs.getlen() * 8: raise ValueError('not enough bits %r %r' % (n, len(bs.bin) * 8)) while n: - i = start / 8 + i = start // 8 c = cls.getbytes(bs, i) if not c: raise IOError @@ -255,8 +257,8 @@ class mn_msp430(cls_mn): @classmethod def getbytes(cls, bs, offset, l=1): - out = "" - for _ in xrange(l): + out = b"" + for _ in range(l): n_offset = (offset & ~1) + 1 - offset % 2 out += bs.getbytes(n_offset, 1) offset += 1 @@ -266,7 +268,7 @@ class mn_msp430(cls_mn): tmp = super(mn_msp430, self).decoded2bytes(result) out = [] for x in tmp: - o = "" + o = b"" while x: o += x[:2][::-1] x = x[2:] @@ -524,7 +526,7 @@ class msp430_offs(imm_noarg, msp430_arg): def encodeval(self, v): plen = self.parent.l + self.l assert(plen % 8 == 0) - v -= plen / 8 + v -= plen // 8 if v % 2 != 0: return False return v >> 1 diff --git a/miasm2/arch/msp430/regs.py b/miasm2/arch/msp430/regs.py index 11385779..a3e714b2 100644 --- a/miasm2/arch/msp430/regs.py +++ b/miasm2/arch/msp430/regs.py @@ -1,10 +1,11 @@ +from builtins import range from miasm2.expression.expression import * from miasm2.core.cpu import reg_info # GP -regs16_str = ["PC", "SP", "SR"] + ["R%d" % i for i in xrange(3, 16)] +regs16_str = ["PC", "SP", "SR"] + ["R%d" % i for i in range(3, 16)] regs16_expr = [ExprId(x, 16) for x in regs16_str] exception_flags = ExprId('exception_flags', 32) diff --git a/miasm2/arch/msp430/sem.py b/miasm2/arch/msp430/sem.py index e0110d24..b939c224 100644 --- a/miasm2/arch/msp430/sem.py +++ b/miasm2/arch/msp430/sem.py @@ -96,10 +96,10 @@ def mng_autoinc(a, b, size): return e, a, b a_r = a.args[0] - e.append(ExprAssign(a_r, a_r + ExprInt(size / 8, a_r.size))) + e.append(ExprAssign(a_r, a_r + ExprInt(size // 8, a_r.size))) a = ExprMem(a_r, size) if isinstance(b, ExprMem) and a_r in b.arg: - b = ExprMem(b.arg + ExprInt(size / 8, 16), b.size) + b = ExprMem(b.arg + ExprInt(size // 8, 16), b.size) return e, a, b # Mnemonics diff --git a/miasm2/arch/ppc/arch.py b/miasm2/arch/ppc/arch.py index 37acc1c5..e7661371 100644 --- a/miasm2/arch/ppc/arch.py +++ b/miasm2/arch/ppc/arch.py @@ -1,3 +1,4 @@ +from builtins import range import logging from pyparsing import * @@ -40,7 +41,7 @@ class ppc_arg(m_arg): return arg.name if arg.name in gpregs.str: return None - loc_key = loc_db.get_or_create_name_location(arg.name) + loc_key = loc_db.get_or_create_name_location(arg.name.encode()) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] @@ -57,7 +58,7 @@ class ppc_arg(m_arg): return None -class additional_info: +class additional_info(object): def __init__(self): self.except_on_instr = False @@ -227,7 +228,7 @@ class mn_ppc(cls_mn): if n > bs.getlen() * 8: raise ValueError('not enough bits %r %r' % (n, len(bs.bin) * 8)) while n: - offset = start / 8 + offset = start // 8 n_offset = cls.endian_offset(attrib, offset) c = cls.getbytes(bs, n_offset, 1) if not c: @@ -468,7 +469,7 @@ def ppc_bo_bi_to_mnemo(bo, bi, prefer_taken=True, default_taken=True): def ppc_all_bo_bi(): for bo in [0, 2, 4, 8, 10, 12, 16, 18, 20]: - for bi in xrange(4): + for bi in range(4): yield bo, bi class ppc_divert_conditional_branch(bs_divert): diff --git a/miasm2/arch/ppc/jit.py b/miasm2/arch/ppc/jit.py index 14c203a9..8dc4aa99 100644 --- a/miasm2/arch/ppc/jit.py +++ b/miasm2/arch/ppc/jit.py @@ -1,3 +1,4 @@ +from builtins import range from miasm2.jitter.jitload import Jitter, named_arguments from miasm2.core.locationdb import LocationDB from miasm2.arch.ppc.sem import ir_ppc32b @@ -34,7 +35,7 @@ class jitter_ppc32b(Jitter): @named_arguments def func_args_systemv(self, n_args): - args = [self.get_arg_n_systemv(i) for i in xrange(n_args)] + args = [self.get_arg_n_systemv(i) for i in range(n_args)] ret_ad = self.cpu.LR return ret_ad, args @@ -47,9 +48,9 @@ class jitter_ppc32b(Jitter): return True def func_prepare_systemv(self, ret_addr, *args): - for index in xrange(min(len(args), self.max_reg_arg)): + for index in range(min(len(args), self.max_reg_arg)): setattr(self.cpu, 'R%d' % (index + 3), args[index]) - for index in xrange(len(args) - 1, self.max_reg_arg - 1, -1): + for index in range(len(args) - 1, self.max_reg_arg - 1, -1): self.push_uint32_t(args[index]) # reserve room for LR save word and backchain diff --git a/miasm2/arch/ppc/regs.py b/miasm2/arch/ppc/regs.py index 70b49f82..e70afce2 100644 --- a/miasm2/arch/ppc/regs.py +++ b/miasm2/arch/ppc/regs.py @@ -1,4 +1,5 @@ +from builtins import range from miasm2.expression.expression import * from miasm2.core.cpu import gen_reg, gen_regs @@ -14,13 +15,13 @@ SPR_ACCESS_SPR_OFF = 0 SPR_ACCESS_GPR_MASK = 0x0001F000 SPR_ACCESS_GPR_OFF = 12 -gpregs_str = ["R%d" % i for i in xrange(32)] +gpregs_str = ["R%d" % i for i in range(32)] gpregs_expr, gpregs_init, gpregs = gen_regs(gpregs_str, globals(), 32) -crfregs_str = ["CR%d" % i for i in xrange(8)] +crfregs_str = ["CR%d" % i for i in range(8)] crfregs_expr, crfregs_init, crfregs = gen_regs(crfregs_str, globals(), 4) -crfbitregs_str = ["CR%d_%s" % (i, flag) for i in xrange(8) +crfbitregs_str = ["CR%d_%s" % (i, flag) for i in range(8) for flag in ['LT', 'GT', 'EQ', 'SO'] ] crfbitregs_expr, crfbitregs_init, crfbitregs = gen_regs(crfbitregs_str, globals(), 1) @@ -38,8 +39,8 @@ otherregs_str = ["PC", "CTR", "LR" ] otherregs_expr, otherregs_init, otherregs = gen_regs(otherregs_str, globals(), 32) -superregs_str = (["SPRG%d" % i for i in xrange(4)] + - ["SRR%d" % i for i in xrange(2)] + +superregs_str = (["SPRG%d" % i for i in range(4)] + + ["SRR%d" % i for i in range(2)] + ["DAR", "DSISR", "MSR", "PIR", "PVR", "DEC", "TBL", "TBU"]) superregs_expr, superregs_init, superregs = gen_regs(superregs_str, diff --git a/miasm2/arch/ppc/sem.py b/miasm2/arch/ppc/sem.py index 558450b2..ef44ffe3 100644 --- a/miasm2/arch/ppc/sem.py +++ b/miasm2/arch/ppc/sem.py @@ -1,3 +1,6 @@ +from __future__ import print_function +from builtins import range + import miasm2.expression.expression as expr from miasm2.ir.ir import AssignBlock, IntermediateRepresentation, IRBlock from miasm2.arch.ppc.arch import mn_ppc @@ -15,7 +18,7 @@ spr_dict = { crf_dict = dict((ExprId("CR%d" % i, 4), dict( (bit, ExprId("CR%d_%s" % (i, bit), 1)) for bit in ['LT', 'GT', 'EQ', 'SO' ] )) - for i in xrange(8) ) + for i in range(8) ) ctx = { 'crf_dict': crf_dict, @@ -112,7 +115,7 @@ def mn_do_cntlzw(ir, instr, ra, rs): def crbit_to_reg(bit): bit = bit.arg.arg - crid = bit / 4 + crid = bit // 4 bitname = [ 'LT', 'GT', 'EQ', 'SO' ][bit % 4] return all_regs_ids_byname["CR%d_%s" % (crid, bitname)] @@ -217,8 +220,8 @@ def mn_do_exts(ir, instr, ra, rs): return ret, [] def byte_swap(expr): - nbytes = expr.size / 8 - bytes = [ expr[i*8:i*8+8] for i in xrange(nbytes - 1, -1, -1) ] + nbytes = expr.size // 8 + bytes = [ expr[i*8:i*8+8] for i in range(nbytes - 1, -1, -1) ] return ExprCompose(bytes) def mn_do_load(ir, instr, arg1, arg2, arg3=None): @@ -325,7 +328,7 @@ def mn_do_mcrxr(ir, instr, crfd): def mn_do_mfcr(ir, instr, rd): return ([ ExprAssign(rd, ExprCompose(*[ all_regs_ids_byname["CR%d_%s" % (i, b)] - for i in xrange(7, -1, -1) + for i in range(7, -1, -1) for b in ['SO', 'EQ', 'GT', 'LT']]))], []) @@ -350,7 +353,7 @@ def mn_mfspr(ir, instr, arg1, arg2): def mn_mtcrf(ir, instr, crm, rs): ret = [] - for i in xrange(8): + for i in range(8): if crm.arg.arg & (1 << (7 - i)): j = (28 - 4 * i) + 3 for b in ['LT', 'GT', 'EQ', 'SO']: @@ -361,7 +364,7 @@ def mn_mtcrf(ir, instr, crm, rs): return ret, [] def mn_mtmsr(ir, instr, rs): - print "%08x: MSR assigned" % instr.offset + print("%08x: MSR assigned" % instr.offset) return [ ExprAssign(MSR, rs) ], [] def mn_mtspr(ir, instr, arg1, arg2): @@ -746,7 +749,7 @@ def mn_do_cond_branch(ir, instr, dest): return ret, [] def mn_do_nop_warn(ir, instr, *args): - print "Warning, instruction %s implemented as NOP" % instr + print("Warning, instruction %s implemented as NOP" % instr) return [], [] @sbuild.parse diff --git a/miasm2/arch/sh4/arch.py b/miasm2/arch/sh4/arch.py index 88d734a3..c7ff6ab0 100644 --- a/miasm2/arch/sh4/arch.py +++ b/miasm2/arch/sh4/arch.py @@ -1,5 +1,8 @@ #-*- coding:utf-8 -*- +from __future__ import print_function +from builtins import range + from pyparsing import * from miasm2.core.cpu import * from miasm2.expression.expression import * @@ -102,7 +105,7 @@ class sh4_arg(m_arg): return arg.name if arg.name in gpregs.str: return None - loc_key = loc_db.get_or_create_name_location(arg.name) + loc_key = loc_db.get_or_create_name_location(arg.name.encode()) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] @@ -235,7 +238,7 @@ class sh4_dgpreg_imm(sh4_dgpreg): p = self.parent r = gpregs.expr[v] s = self.sz - d = ExprInt(p.disp.value * s / 8, 32) + d = ExprInt((p.disp.value * s) // 8, 32) e = ExprMem(r + d, s) self.expr = e return True @@ -258,7 +261,7 @@ class sh4_dgpreg_imm(sh4_dgpreg): if not isinstance(res[jrb], ExprInt): return False d = int(res[jrb]) - p.disp.value = d / (s / 8) + p.disp.value = d // (s // 8) if not res[jra] in gpregs.expr: return False v = gpregs.expr.index(res[jra]) @@ -301,7 +304,7 @@ class sh4_dpc16imm(sh4_dgpreg): return True def calcdisp(self, v): - v = (int(v) - 4) / 2 + v = (int(v) - 4) // 2 if not 0 < v <= 0xff: return None return v @@ -324,7 +327,7 @@ class sh4_dgbrimm8(sh4_dgpreg): def decode(self, v): s = self.sz - self.expr = ExprMem(GBR + ExprInt(v * s / 8, 32), s) + self.expr = ExprMem(GBR + ExprInt((v * s) // 8, 32), s) return True def encode(self): @@ -338,7 +341,7 @@ class sh4_dgbrimm8(sh4_dgpreg): return False if not isinstance(res[jra], ExprInt): return False - self.value = int(res[jra]) / (s / 8) + self.value = int(res[jra]) // (s // 8) return True @@ -351,7 +354,7 @@ class sh4_dpc32imm(sh4_dpc16imm): return True def calcdisp(self, v): - v = (int(v) - 4) / 4 + v = (int(v) - 4) // 4 if not 0 < v <= 0xff: return None return v @@ -383,13 +386,13 @@ class sh4_pc32imm(sh4_arg): return False if not isinstance(res[jra], ExprInt): return False - v = (int(res[jra]) - 4) / 4 + v = (int(res[jra]) - 4) // 4 if v is None: return False self.value = v return True -class additional_info: +class additional_info(object): def __init__(self): self.except_on_instr = False @@ -423,8 +426,10 @@ class instruction_sh4(instruction): elif ptr.op == "postinc": s = '%s+' % ptr.args[0] else: - s = ','.join([str(x).replace('(', '').replace(')', '') - for x in ptr.args]) + s = ','.join( + str(x).replace('(', '').replace(')', '') + for x in ptr.args + ) s = "(%s)"%s s = "@%s" % s elif isinstance(ptr, ExprId): @@ -473,11 +478,11 @@ class instruction_sh4(instruction): log.debug('dyn dst %r', e) return off = e.arg - (self.offset + 4 + self.l) - print hex(off) + print(hex(off)) if int(off % 4): raise ValueError('strange offset! %r' % off) self.args[0] = ExprInt(off, 32) - print 'final', self.args[0] + print('final', self.args[0]) def get_args_expr(self): args = [a for a in self.args] @@ -510,7 +515,7 @@ class mn_sh4(cls_mn): if n > bs.getlen() * 8: raise ValueError('not enough bits %r %r' % (n, len(bs.bin) * 8)) while n: - i = start / 8 + i = start // 8 c = cls.getbytes(bs, i) if not c: raise IOError @@ -527,8 +532,8 @@ class mn_sh4(cls_mn): @classmethod def getbytes(cls, bs, offset, l=1): - out = "" - for _ in xrange(l): + out = b"" + for _ in range(l): n_offset = (offset & ~1) + 1 - offset % 2 out += bs.getbytes(n_offset, 1) offset += 1 diff --git a/miasm2/arch/sh4/regs.py b/miasm2/arch/sh4/regs.py index 148e74ba..c294eb8c 100644 --- a/miasm2/arch/sh4/regs.py +++ b/miasm2/arch/sh4/regs.py @@ -1,20 +1,21 @@ +from builtins import range from miasm2.expression.expression import * from miasm2.core.cpu import reg_info, gen_reg # GP -gpregs_str = ['R%d' % r for r in xrange(0x10)] +gpregs_str = ['R%d' % r for r in range(0x10)] gpregs_expr = [ExprId(x, 32) for x in gpregs_str] gpregs = reg_info(gpregs_str, gpregs_expr) -bgpregs_str = ['R%d_BANK' % r for r in xrange(0x8)] +bgpregs_str = ['R%d_BANK' % r for r in range(0x8)] bgpregs_expr = [ExprId(x, 32) for x in bgpregs_str] bgpregs = reg_info(bgpregs_str, bgpregs_expr) -fregs_str = ['FR%d' % r for r in xrange(0x10)] +fregs_str = ['FR%d' % r for r in range(0x10)] fregs_expr = [ExprId(x, 32) for x in fregs_str] fregs = reg_info(fregs_str, fregs_expr) -dregs_str = ['DR%d' % r for r in xrange(0x8)] +dregs_str = ['DR%d' % r for r in range(0x8)] dregs_expr = [ExprId(x, 32) for x in dregs_str] dregs = reg_info(dregs_str, dregs_expr) diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index b625647e..7a2c371c 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -1,6 +1,12 @@ #-*- coding:utf-8 -*- +from __future__ import print_function +from builtins import range import re + +from future.utils import viewitems + +from miasm2.core.utils import int_to_byte from miasm2.expression.expression import * from pyparsing import * from miasm2.core.cpu import * @@ -123,7 +129,7 @@ replace_regs = {16: replace_regs16, segm2enc = {CS: 1, SS: 2, DS: 3, ES: 4, FS: 5, GS: 6} -enc2segm = dict([(x[1], x[0]) for x in segm2enc.items()]) +enc2segm = dict((value, key) for key, value in viewitems(segm2enc)) segm_info = reg_info_dct(enc2segm) @@ -215,7 +221,7 @@ XMMWORD = Literal('XMMWORD') MEMPREFIX2SIZE = {'BYTE': 8, 'WORD': 16, 'DWORD': 32, 'QWORD': 64, 'TBYTE': 80, 'XMMWORD': 128} -SIZE2MEMPREFIX = dict((x[1], x[0]) for x in MEMPREFIX2SIZE.items()) +SIZE2MEMPREFIX = dict((value, key) for key, value in viewitems(MEMPREFIX2SIZE)) def cb_deref_mem(tokens): if len(tokens) == 2: @@ -272,7 +278,7 @@ class x86_arg(m_arg): if value.name in ["FAR"]: return None - loc_key = loc_db.get_or_create_name_location(value.name) + loc_key = loc_db.get_or_create_name_location(value.name.encode()) return ExprLoc(loc_key, size_hint) if isinstance(value, AstOp): # First pass to retrieve fixed_size @@ -430,13 +436,13 @@ repeat_mn = ["INS", "OUTS", ] -class group: +class group(object): def __init__(self): self.value = None -class additional_info: +class additional_info(object): def __init__(self): self.except_on_instr = False @@ -446,7 +452,7 @@ class additional_info: self.stk = False self.v_opmode = None self.v_admode = None - self.prefixed = '' + self.prefixed = b'' class instruction_x86(instruction): @@ -537,7 +543,7 @@ class instruction_x86(instruction): self.additional_info.v_opmode = c.v_opmode() self.additional_info.v_admode = c.v_admode() self.additional_info.prefix = c.prefix - self.additional_info.prefixed = getattr(c, "prefixed", "") + self.additional_info.prefixed = getattr(c, "prefixed", b"") def __str__(self): return self.to_string() @@ -547,13 +553,13 @@ class instruction_x86(instruction): if self.additional_info.g1.value & 1: o = "LOCK %s" % o if self.additional_info.g1.value & 2: - if getattr(self.additional_info.prefixed, 'default', "") != "\xF2": + if getattr(self.additional_info.prefixed, 'default', b"") != b"\xF2": o = "REPNE %s" % o if self.additional_info.g1.value & 8: - if getattr(self.additional_info.prefixed, 'default', "") != "\xF3": + if getattr(self.additional_info.prefixed, 'default', b"") != b"\xF3": o = "REP %s" % o elif self.additional_info.g1.value & 4: - if getattr(self.additional_info.prefixed, 'default', "") != "\xF3": + if getattr(self.additional_info.prefixed, 'default', b"") != b"\xF3": o = "REPE %s" % o return o @@ -650,7 +656,7 @@ class mn_x86(cls_mn): info.g2.value = self.g2.value info.stk = hasattr(self, 'stk') info.v_opmode = self.v_opmode() - info.prefixed = "" + info.prefixed = b"" if hasattr(self, 'prefixed'): info.prefixed = self.prefixed.default return info @@ -705,40 +711,40 @@ class mn_x86(cls_mn): 'rex_r': 0, 'rex_x': 0, 'rex_b': 0, - 'prefix': "", - 'prefixed': "", + 'prefix': b"", + 'prefixed': b"", } while True: c = v.getbytes(offset) - if c == '\x66': + if c == b'\x66': pre_dis_info['opmode'] = 1 - elif c == '\x67': + elif c == b'\x67': pre_dis_info['admode'] = 1 - elif c == '\xf0': + elif c == b'\xf0': pre_dis_info['g1'] = 1 - elif c == '\xf2': + elif c == b'\xf2': pre_dis_info['g1'] = 2 - elif c == '\xf3': + elif c == b'\xf3': pre_dis_info['g1'] = 12 - elif c == '\x2e': + elif c == b'\x2e': pre_dis_info['g2'] = 1 - elif c == '\x36': + elif c == b'\x36': pre_dis_info['g2'] = 2 - elif c == '\x3e': + elif c == b'\x3e': pre_dis_info['g2'] = 3 - elif c == '\x26': + elif c == b'\x26': pre_dis_info['g2'] = 4 - elif c == '\x64': + elif c == b'\x64': pre_dis_info['g2'] = 5 - elif c == '\x65': + elif c == b'\x65': pre_dis_info['g2'] = 6 else: break pre_dis_info['prefix'] += c offset += 1 - if mode == 64 and c in '@ABCDEFGHIJKLMNO': + if mode == 64 and c in b'@ABCDEFGHIJKLMNO': x = ord(c) pre_dis_info['rex_p'] = 1 pre_dis_info['rex_w'] = (x >> 3) & 1 @@ -746,7 +752,7 @@ class mn_x86(cls_mn): pre_dis_info['rex_x'] = (x >> 1) & 1 pre_dis_info['rex_b'] = (x >> 0) & 1 offset += 1 - elif pre_dis_info.get('g1', None) == 12 and c in ['\xa6', '\xa7', '\xae', '\xaf']: + elif pre_dis_info.get('g1', None) == 12 and c in [b'\xa6', b'\xa7', b'\xae', b'\xaf']: pre_dis_info['g1'] = 4 return pre_dis_info, v, mode, offset, offset - offset_o @@ -793,14 +799,14 @@ class mn_x86(cls_mn): def add_pre_dis_info(self, pre_dis_info=None): if pre_dis_info is None: return True - if hasattr(self, "prefixed") and self.prefixed.default == "\x66": + if hasattr(self, "prefixed") and self.prefixed.default == b"\x66": pre_dis_info['opmode'] = 0 self.opmode = pre_dis_info['opmode'] self.admode = pre_dis_info['admode'] if hasattr(self, 'no_xmm_pref') and\ pre_dis_info['prefix'] and\ - pre_dis_info['prefix'][-1] in '\x66\xf2\xf3': + pre_dis_info['prefix'][-1] in b'\x66\xf2\xf3': return False if (hasattr(self, "prefixed") and not pre_dis_info['prefix'].endswith(self.prefixed.default)): @@ -831,7 +837,7 @@ class mn_x86(cls_mn): def gen_prefix(self): - v = "" + v = b"" rex = 0x40 if self.g1.value is None: self.g1.value = 0 @@ -847,36 +853,40 @@ class mn_x86(cls_mn): if self.rex_b.value: rex |= 0x1 if rex != 0x40 or self.rex_p.value == 1: - v = chr(rex) + v + v = int_to_byte(rex) + v if hasattr(self, 'no_rex'): return None - - if hasattr(self, 'prefixed'): v = self.prefixed.default + v if self.g1.value & 1: - v = "\xf0" + v + v = b"\xf0" + v if self.g1.value & 2: if hasattr(self, 'no_xmm_pref'): return None - v = "\xf2" + v + v = b"\xf2" + v if self.g1.value & 12: if hasattr(self, 'no_xmm_pref'): return None - v = "\xf3" + v + v = b"\xf3" + v if self.g2.value: - v = {1: '\x2e', 2: '\x36', 3: '\x3e', 4: - '\x26', 5: '\x64', 6: '\x65'}[self.g2.value] + v + v = { + 1: b'\x2e', + 2: b'\x36', + 3: b'\x3e', + 4: b'\x26', + 5: b'\x64', + 6: b'\x65' + }[self.g2.value] + v # mode prefix if hasattr(self, "admode") and self.admode: - v = "\x67" + v + v = b"\x67" + v if hasattr(self, "opmode") and self.opmode: if hasattr(self, 'no_xmm_pref'): return None - v = "\x66" + v + v = b"\x66" + v return v def encodefields(self, decoded): @@ -1436,25 +1446,25 @@ def gen_modrm_form(): sib_u32 = [{f_isad: True} for i in range(0x100)] sib_u64 = [] - for rex_x in xrange(2): + for rex_x in range(2): o = [] - for rex_b in xrange(2): + for rex_b in range(2): x = [{f_isad: True} for i in range(0x100)] o.append(x) sib_u64.append(o) sib_u64_ebp = [] - for rex_x in xrange(2): + for rex_x in range(2): o = [] - for rex_b in xrange(2): + for rex_b in range(2): x = [{f_isad: True} for i in range(0x100)] o.append(x) sib_u64_ebp.append(o) sib_64_s08_ebp = [] - for rex_x in xrange(2): + for rex_x in range(2): o = [] - for rex_b in xrange(2): + for rex_b in range(2): x = [{f_isad: True} for i in range(0x100)] o.append(x) sib_64_s08_ebp.append(o) @@ -1479,17 +1489,17 @@ def gen_modrm_form(): elif sib_rez == sib_u32: sib_rez[index][f_imm] = f_u32 elif sib_rez == sib_u64_ebp: - for rex_b in xrange(2): - for rex_x in xrange(2): + for rex_b in range(2): + for rex_x in range(2): sib_rez[rex_x][rex_b][index][f_imm] = f_u32 sib_rez[rex_x][rex_b][index][ebp + 8 * rex_b] = 1 elif sib_rez == sib_u64: - for rex_b in xrange(2): - for rex_x in xrange(2): + for rex_b in range(2): + for rex_x in range(2): sib_rez[rex_x][rex_b][index][f_imm] = f_u32 elif sib_rez == sib_64_s08_ebp: - for rex_b in xrange(2): - for rex_x in xrange(2): + for rex_b in range(2): + for rex_x in range(2): sib_rez[rex_x][rex_b][index][f_imm] = f_s08 sib_rez[rex_x][rex_b][index][ebp + 8 * rex_b] = 1 @@ -1503,17 +1513,17 @@ def gen_modrm_form(): elif sib_rez == sib_u32: sib_rez[index][b] = 1 elif sib_rez == sib_u64_ebp: - for rex_b in xrange(2): - for rex_x in xrange(2): + for rex_b in range(2): + for rex_x in range(2): sib_rez[rex_x][rex_b][index][b + 8 * rex_b] = 1 sib_rez[rex_x][rex_b][index][f_imm] = f_u32 elif sib_rez == sib_u64: - for rex_b in xrange(2): - for rex_x in xrange(2): + for rex_b in range(2): + for rex_x in range(2): sib_rez[rex_x][rex_b][index][b + 8 * rex_b] = 1 elif sib_rez == sib_64_s08_ebp: - for rex_b in xrange(2): - for rex_x in xrange(2): + for rex_b in range(2): + for rex_x in range(2): sib_rez[rex_x][rex_b][index][f_imm] = f_s08 sib_rez[rex_x][rex_b][index][b + 8 * rex_b] = 1 @@ -1526,8 +1536,8 @@ def gen_modrm_form(): sib_rez[index][tmp] = 0 # 1 << ss sib_rez[index][tmp] += 1 << ss else: - for rex_b in xrange(2): - for rex_x in xrange(2): + for rex_b in range(2): + for rex_x in range(2): tmp = i + 8 * rex_x if i == 0b100 and rex_x == 0: continue @@ -1649,18 +1659,16 @@ def gen_modrm_form(): 32: defaultdict(list), 64: defaultdict(list), } - for size, db_afs in byte2modrm.items(): + for size, db_afs in viewitems(byte2modrm): for i, modrm in enumerate(db_afs): if not isinstance(modrm, list): - modrm = modrm.items() - modrm.sort() - modrm = tuple(modrm) + # We only need sort for determinism + modrm = tuple(sorted(viewitems(modrm), key=str)) modrm2byte[size][modrm].append(i) continue for j, modrm_f in enumerate(modrm): - modrm_f = modrm_f.items() - modrm_f.sort() - modrm_f = tuple(modrm_f) + # We only need sort for determinism + modrm_f = tuple(sorted(viewitems(modrm_f), key=str)) modrm2byte[size][modrm_f].append((i, j)) return byte2modrm, modrm2byte @@ -1870,7 +1878,7 @@ def expr2modrm(expr, parent, w8, sx=0, xmm=0, mm=0, bnd=0): def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0, bnd=0): o = [] if not modrm[f_isad]: - modrm_k = [x[0] for x in modrm.iteritems() if x[1] == 1] + modrm_k = [key for key, value in viewitems(modrm) if value == 1] if len(modrm_k) != 1: raise ValueError('strange reg encoding %r' % modrm) modrm_k = modrm_k[0] @@ -1895,8 +1903,8 @@ def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0, bnd=0): return expr admode = parent.v_admode() opmode = parent.v_opmode() - for modrm_k, scale in modrm.items(): - if isinstance(modrm_k, (int, long)): + for modrm_k, scale in viewitems(modrm): + if isinstance(modrm_k, int): expr = size2gpregs[admode].expr[modrm_k] if scale != 1: expr = ExprInt(scale, admode) * expr @@ -1965,9 +1973,9 @@ class x86_rm_arg(x86_arg): def gen_cand(self, v_cand, admode): if not admode in modrm2byte: # XXX TODO: 64bit - raise StopIteration + return if not v_cand: - raise StopIteration + return p = self.parent o_rex_x = p.rex_x.value @@ -1995,9 +2003,8 @@ class x86_rm_arg(x86_arg): v[f_imm] = size vo = v - v = v.items() - v.sort() - v = tuple(v) + # We only need sort for determinism + v = tuple(sorted(viewitems(v), key=str)) admode = 64 if p.mode == 64 else admode if not v in modrm2byte[admode]: continue @@ -2047,11 +2054,11 @@ class x86_rm_arg(x86_arg): yield True - raise StopIteration + return def encode(self): if isinstance(self.expr, ExprInt): - raise StopIteration + return p = self.parent admode = p.v_admode() mode = self.expr.size @@ -2091,11 +2098,11 @@ class x86_rm_mem_far(x86_rm_arg): def encode(self): if not (isinstance(self.expr, m2_expr.ExprOp) and self.expr.op == 'far'): - raise StopIteration + return expr = self.expr.args[0] if isinstance(expr, ExprInt): - raise StopIteration + return p = self.parent admode = p.v_admode() mode = expr.size @@ -2115,7 +2122,7 @@ class x86_rm_w8(x86_rm_arg): def encode(self): if isinstance(self.expr, ExprInt): - raise StopIteration + return p = self.parent if p.w8.value is None: if self.expr.size == 8: @@ -2140,7 +2147,7 @@ class x86_rm_sx(x86_rm_arg): def encode(self): if isinstance(self.expr, ExprInt): - raise StopIteration + return p = self.parent if p.w8.value is None: if self.expr.size == 8: @@ -2164,7 +2171,7 @@ class x86_rm_sxd(x86_rm_arg): def encode(self): if isinstance(self.expr, ExprInt): - raise StopIteration + return p = self.parent v_cand, segm, ok = expr2modrm(self.expr, p, 1, 2) if segm: @@ -2195,10 +2202,10 @@ class x86_rm_sd(x86_rm_arg): def encode(self): if isinstance(self.expr, ExprInt): - raise StopIteration + return p = self.parent if not self.expr.size in [32, 64]: - raise StopIteration + return self.set_s_value(0) v_cand, segm, ok = expr2modrm(self.expr, p, 1) for x in self.gen_cand(v_cand, p.v_admode()): @@ -2214,7 +2221,7 @@ class x86_rm_wd(x86_rm_sd): def encode(self): if isinstance(self.expr, ExprInt): - raise StopIteration + return p = self.parent p.wd.value = 0 v_cand, segm, ok = expr2modrm(self.expr, p, 1) @@ -2237,7 +2244,7 @@ class x86_rm_08(x86_rm_arg): def encode(self): if isinstance(self.expr, ExprInt): - raise StopIteration + return p = self.parent v_cand, segm, ok = expr2modrm(self.expr, p, 0, 0, 0, 0) for x in self.gen_cand(v_cand, p.v_admode()): @@ -2257,7 +2264,7 @@ class x86_rm_reg_m08(x86_rm_arg): def encode(self): if isinstance(self.expr, ExprInt): - raise StopIteration + return p = self.parent if isinstance(self.expr, ExprMem): expr = ExprMem(self.expr.ptr, 32) @@ -2284,7 +2291,7 @@ class x86_rm_m64(x86_rm_arg): def encode(self): if isinstance(self.expr, ExprInt): - raise StopIteration + return p = self.parent v_cand, segm, ok = expr2modrm(self.expr, p, 0, 0, 0, 1) for x in self.gen_cand(v_cand, p.v_admode()): @@ -2296,9 +2303,9 @@ class x86_rm_m80(x86_rm_m64): def encode(self): if isinstance(self.expr, ExprInt): - raise StopIteration + return if not isinstance(self.expr, ExprMem) or self.expr.size != self.msize: - raise StopIteration + return p = self.parent mode = p.mode if mode == 64: @@ -2320,7 +2327,7 @@ class x86_rm_m08(x86_rm_arg): def encode(self): if self.expr.size != 8: - raise StopIteration + return p = self.parent mode = p.mode v_cand, segm, ok = expr2modrm(self.expr, p, 0) @@ -2354,9 +2361,9 @@ class x86_rm_mm(x86_rm_m80): def encode(self): expr = self.expr if isinstance(expr, ExprInt): - raise StopIteration + return if isinstance(expr, ExprMem) and expr.size != self.msize: - raise StopIteration + return p = self.parent mode = p.mode if mode == 64: @@ -2458,7 +2465,7 @@ class x86_rm_reg_noarg(object): self.parent.w8.value = 0 return start, stop try: - result, start, stop = self.parser.scanString(text).next() + result, start, stop = next(self.parser.scanString(text)) except StopIteration: return None, None expr = self.asm_ast_to_expr(result[0], loc_db) @@ -2753,7 +2760,7 @@ class bs_cond_imm(bs_cond_scale, x86_arg): expr, start, stop = parser_result[self.parser] else: try: - expr, start, stop = self.parser.scanString(text).next() + expr, start, stop = next(self.parser.scanString(text)) except StopIteration: expr = None self.expr = expr @@ -2788,7 +2795,7 @@ class bs_cond_imm(bs_cond_scale, x86_arg): def encode(self): if not isinstance(self.expr, ExprInt): - raise StopIteration + return arg0_expr = self.parent.args[0].expr self.parent.rex_w.value = 0 # special case for push @@ -2800,10 +2807,10 @@ class bs_cond_imm(bs_cond_scale, x86_arg): self.l = l mask = ((1 << self.l) - 1) if v != sign_ext(v & mask, self.l, l): - raise StopIteration + return self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) yield True - raise StopIteration + return # assume 2 args; use first arg to guess op size if arg0_expr.size == 64: @@ -2813,7 +2820,7 @@ class bs_cond_imm(bs_cond_scale, x86_arg): v = int(self.expr) if arg0_expr.size == 8: if not hasattr(self.parent, 'w8'): - raise StopIteration + return self.parent.w8.value = 0 l = 8 if hasattr(self.parent, 'se'): @@ -2838,7 +2845,7 @@ class bs_cond_imm(bs_cond_scale, x86_arg): mask = ((1 << self.l) - 1) if v != sign_ext(v & mask, self.l, l): - raise StopIteration + return self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) yield True @@ -2880,7 +2887,7 @@ class bs_rel_off(bs_cond_imm): expr, start, stop = parser_result[self.parser] else: try: - expr, start, stop = self.parser.scanString(text).next() + expr, start, stop = next(self.parser.scanString(text)) except StopIteration: expr = None self.expr = expr @@ -2901,7 +2908,7 @@ class bs_rel_off(bs_cond_imm): def encode(self): if not isinstance(self.expr, ExprInt): - raise StopIteration + return arg0_expr = self.parent.args[0].expr if self.l == 0: l = self.parent.v_opmode() @@ -2911,14 +2918,14 @@ class bs_rel_off(bs_cond_imm): parent_len = len(prefix) * 8 + self.parent.l + self.l assert(parent_len % 8 == 0) - v = int(self.expr.arg - parent_len/8) + v = int(self.expr.arg) - parent_len // 8 if prefix is None: - raise StopIteration + return mask = ((1 << self.l) - 1) if self.l > l: - raise StopIteration + return if v != sign_ext(v & mask, self.l, l): - raise StopIteration + return self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) yield True @@ -2939,7 +2946,7 @@ class bs_s08(bs_rel_off): def encode(self): if not isinstance(self.expr, ExprInt): - raise StopIteration + return arg0_expr = self.parent.args[0].expr if self.l != 0: l = self.l @@ -2950,9 +2957,9 @@ class bs_s08(bs_rel_off): v = int(self.expr) mask = ((1 << self.l) - 1) if self.l > l: - raise StopIteration + return if v != sign_ext(v & mask, self.l, l): - raise StopIteration + return self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) yield True @@ -2983,12 +2990,12 @@ class bs_moff(bsi): def encode(self): if not hasattr(self.parent, "mseg"): - raise StopIteration + return m = self.parent.mseg.expr if not (isinstance(m, ExprOp) and m.op == 'segm'): - raise StopIteration + return if not isinstance(m.args[1], ExprInt): - raise StopIteration + return l = self.parent.v_opmode() if l == 16: self.l = 16 @@ -2997,7 +3004,7 @@ class bs_moff(bsi): v = int(m.args[1]) mask = ((1 << self.l) - 1) if v != sign_ext(v & mask, self.l, l): - raise StopIteration + return self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) yield True @@ -3027,7 +3034,7 @@ class bs_movoff(x86_arg): return None, None return start, stop try: - v, start, stop = self.parser.scanString(text).next() + v, start, stop = next(self.parser.scanString(text)) except StopIteration: return None, None if not isinstance(e, ExprMem): @@ -3051,12 +3058,12 @@ class bs_movoff(x86_arg): def encode(self): p = self.parent if not isinstance(self.expr, ExprMem) or not isinstance(self.expr.ptr, ExprInt): - raise StopIteration + return self.l = p.v_admode() v = int(self.expr.ptr) mask = ((1 << self.l) - 1) if v != mask & v: - raise StopIteration + return self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) yield True @@ -3092,7 +3099,7 @@ class bs_msegoff(x86_arg): return None, None return start, stop try: - v, start, stop = self.parser.scanString(text).next() + v, start, stop = next(self.parser.scanString(text)) except StopIteration: return None, None self.expr = v[0] @@ -3103,16 +3110,16 @@ class bs_msegoff(x86_arg): def encode(self): if not (isinstance(self.expr, ExprOp) and self.expr.op == 'segm'): - raise StopIteration + return if not isinstance(self.expr.args[0], ExprInt): - raise StopIteration + return if not isinstance(self.expr.args[1], ExprInt): - raise StopIteration + return l = self.parent.v_opmode() v = int(self.expr.args[0]) mask = ((1 << self.l) - 1) if v != sign_ext(v & mask, self.l, l): - raise StopIteration + return self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) yield True @@ -3148,9 +3155,9 @@ sxd = bs(l=0, fname="sx") xmmreg = bs(l=0, fname="xmmreg") mmreg = bs(l=0, fname="mmreg") -pref_f2 = bs(l=0, fname="prefixed", default="\xf2") -pref_f3 = bs(l=0, fname="prefixed", default="\xf3") -pref_66 = bs(l=0, fname="prefixed", default="\x66") +pref_f2 = bs(l=0, fname="prefixed", default=b"\xf2") +pref_f3 = bs(l=0, fname="prefixed", default=b"\xf3") +pref_66 = bs(l=0, fname="prefixed", default=b"\x66") no_xmm_pref = bs(l=0, fname="no_xmm_pref") no_rex = bs(l=0, fname="no_rex") @@ -3186,7 +3193,7 @@ wd = bs(l=1, fname="wd") stk = bs(l=0, fname="stk") -class field_size: +class field_size(object): prio = default_prio def __init__(self, d=None): @@ -3287,7 +3294,7 @@ rm_arg_bnd_m128 = bs(l=0, cls=(x86_rm_bnd_m128,), fname='rmarg') rm_arg_bnd_reg = bs(l=0, cls=(x86_rm_bnd_reg,), fname='rmarg') -swapargs = bs_swapargs(l=1, fname="swap", mn_mod=range(1 << 1)) +swapargs = bs_swapargs(l=1, fname="swap", mn_mod=list(range(1 << 1))) class bs_op_mode(bsi): @@ -4626,5 +4633,5 @@ mod reg r/m def print_size(e): - print e, e.size + print(e, e.size) return e diff --git a/miasm2/arch/x86/jit.py b/miasm2/arch/x86/jit.py index f0a9875e..14418902 100644 --- a/miasm2/arch/x86/jit.py +++ b/miasm2/arch/x86/jit.py @@ -1,3 +1,4 @@ +from builtins import range import logging from miasm2.jitter.jitload import Jitter, named_arguments @@ -53,12 +54,12 @@ class jitter_x86_16(Jitter): return self.orig_irbloc_fix_regs_for_mode(irblock, 64) def push_uint16_t(self, value): - self.cpu.SP -= self.ir_arch.sp.size / 8 + self.cpu.SP -= self.ir_arch.sp.size // 8 self.vm.set_u16(self.cpu.SP, value) def pop_uint16_t(self): value = self.vm.get_u16(self.cpu.SP) - self.cpu.SP += self.ir_arch.sp.size / 8 + self.cpu.SP += self.ir_arch.sp.size // 8 return value def get_stack_arg(self, index): @@ -86,21 +87,21 @@ class jitter_x86_32(Jitter): return self.orig_irbloc_fix_regs_for_mode(irblock, 64) def push_uint16_t(self, value): - self.cpu.ESP -= self.ir_arch.sp.size / 8 + self.cpu.ESP -= self.ir_arch.sp.size // 8 self.vm.set_u16(self.cpu.ESP, value) def pop_uint16_t(self): value = self.vm.get_u16(self.cpu.ESP) - self.cpu.ESP += self.ir_arch.sp.size / 8 + self.cpu.ESP += self.ir_arch.sp.size // 8 return value def push_uint32_t(self, value): - self.cpu.ESP -= self.ir_arch.sp.size / 8 + self.cpu.ESP -= self.ir_arch.sp.size // 8 self.vm.set_u32(self.cpu.ESP, value) def pop_uint32_t(self): value = self.vm.get_u32(self.cpu.ESP) - self.cpu.ESP += self.ir_arch.sp.size / 8 + self.cpu.ESP += self.ir_arch.sp.size // 8 return value def get_stack_arg(self, index): @@ -116,7 +117,7 @@ class jitter_x86_32(Jitter): @named_arguments def func_args_stdcall(self, n_args): ret_ad = self.pop_uint32_t() - args = [self.pop_uint32_t() for _ in xrange(n_args)] + args = [self.pop_uint32_t() for _ in range(n_args)] return ret_ad, args def func_ret_stdcall(self, ret_addr, ret_value1=None, ret_value2=None): @@ -137,7 +138,7 @@ class jitter_x86_32(Jitter): @named_arguments def func_args_cdecl(self, n_args): ret_ad = self.pop_uint32_t() - args = [self.get_stack_arg(i) for i in xrange(n_args)] + args = [self.get_stack_arg(i) for i in range(n_args)] return ret_ad, args def func_ret_cdecl(self, ret_addr, ret_value1=None, ret_value2=None): @@ -162,13 +163,13 @@ class jitter_x86_32(Jitter): args_regs = ['ECX', 'EDX'] ret_ad = self.pop_uint32_t() args = [] - for i in xrange(n_args): + for i in range(n_args): args.append(self.get_arg_n_fastcall(i)) return ret_ad, args def func_prepare_fastcall(self, ret_addr, *args): args_regs = ['ECX', 'EDX'] - for i in xrange(min(len(args), len(args_regs))): + for i in range(min(len(args), len(args_regs))): setattr(self.cpu, args_regs[i], args[i]) remaining_args = args[len(args_regs):] for arg in reversed(remaining_args): @@ -202,12 +203,12 @@ class jitter_x86_64(Jitter): return self.orig_irbloc_fix_regs_for_mode(irblock, 64) def push_uint64_t(self, value): - self.cpu.RSP -= self.ir_arch.sp.size / 8 + self.cpu.RSP -= self.ir_arch.sp.size // 8 self.vm.set_u64(self.cpu.RSP, value) def pop_uint64_t(self): value = self.vm.get_u64(self.cpu.RSP) - self.cpu.RSP += self.ir_arch.sp.size / 8 + self.cpu.RSP += self.ir_arch.sp.size // 8 return value def get_stack_arg(self, index): @@ -225,15 +226,15 @@ class jitter_x86_64(Jitter): args_regs = self.args_regs_stdcall ret_ad = self.pop_uint64_t() args = [] - for i in xrange(min(n_args, 4)): + for i in range(min(n_args, 4)): args.append(self.cpu.get_gpreg()[args_regs[i]]) - for i in xrange(max(0, n_args - 4)): + for i in range(max(0, n_args - 4)): args.append(self.get_stack_arg(i)) return ret_ad, args def func_prepare_stdcall(self, ret_addr, *args): args_regs = self.args_regs_stdcall - for i in xrange(min(len(args), len(args_regs))): + for i in range(min(len(args), len(args_regs))): setattr(self.cpu, args_regs[i], args[i]) remaining_args = args[len(args_regs):] for arg in reversed(remaining_args): @@ -262,7 +263,7 @@ class jitter_x86_64(Jitter): @named_arguments def func_args_systemv(self, n_args): ret_ad = self.pop_uint64_t() - args = [self.get_arg_n_systemv(index) for index in xrange(n_args)] + args = [self.get_arg_n_systemv(index) for index in range(n_args)] return ret_ad, args func_ret_systemv = func_ret_cdecl @@ -270,7 +271,7 @@ class jitter_x86_64(Jitter): def func_prepare_systemv(self, ret_addr, *args): args_regs = self.args_regs_systemv self.push_uint64_t(ret_addr) - for i in xrange(min(len(args), len(args_regs))): + for i in range(min(len(args), len(args_regs))): setattr(self.cpu, args_regs[i], args[i]) remaining_args = args[len(args_regs):] for arg in reversed(remaining_args): diff --git a/miasm2/arch/x86/regs.py b/miasm2/arch/x86/regs.py index ef1095e2..b3f6534b 100644 --- a/miasm2/arch/x86/regs.py +++ b/miasm2/arch/x86/regs.py @@ -1,3 +1,4 @@ +from builtins import range from miasm2.expression.expression import ExprId from miasm2.core.cpu import reg_info @@ -12,20 +13,20 @@ interrupt_num = ExprId('interrupt_num', 8) regs08_str = ["AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH"] + \ - ["R%dB" % (i + 8) for i in xrange(8)] + ["R%dB" % (i + 8) for i in range(8)] regs08_expr = [ExprId(x, 8) for x in regs08_str] regs08_64_str = ["AL", "CL", "DL", "BL", "SPL", "BPL", "SIL", "DIL"] + \ - ["R%dB" % (i + 8) for i in xrange(8)] + ["R%dB" % (i + 8) for i in range(8)] regs08_64_expr = [ExprId(x, 8) for x in regs08_64_str] regs16_str = ["AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI"] + \ - ["R%dW" % (i + 8) for i in xrange(8)] + ["R%dW" % (i + 8) for i in range(8)] regs16_expr = [ExprId(x, 16) for x in regs16_str] regs32_str = ["EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI"] + \ - ["R%dD" % (i + 8) for i in xrange(8)] + ["R%dD" % (i + 8) for i in range(8)] regs32_expr = [ExprId(x, 32) for x in regs32_str] regs64_str = ["RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", @@ -34,13 +35,13 @@ regs64_str = ["RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", regs64_expr = [ExprId(x, 64) for x in regs64_str] -regs_xmm_str = ["XMM%d" % i for i in xrange(16)] +regs_xmm_str = ["XMM%d" % i for i in range(16)] regs_xmm_expr = [ExprId(x, 128) for x in regs_xmm_str] -regs_mm_str = ["MM%d" % i for i in xrange(16)] +regs_mm_str = ["MM%d" % i for i in range(16)] regs_mm_expr = [ExprId(x, 64) for x in regs_mm_str] -regs_bnd_str = ["BND%d" % i for i in xrange(4)] +regs_bnd_str = ["BND%d" % i for i in range(4)] regs_bnd_expr = [ExprId(x, 128) for x in regs_bnd_str] gpregs08 = reg_info(regs08_str, regs08_expr) @@ -74,17 +75,17 @@ selectr_str = ["ES", "CS", "SS", "DS", "FS", "GS"] selectr_expr = [ExprId(x, 16) for x in selectr_str] segmreg = reg_info(selectr_str, selectr_expr) -crregs32_str = ["CR%d" % i for i in xrange(8)] +crregs32_str = ["CR%d" % i for i in range(8)] crregs32_expr = [ExprId(x, 32) for x in crregs32_str] crregs = reg_info(crregs32_str, crregs32_expr) -drregs32_str = ["DR%d" % i for i in xrange(8)] +drregs32_str = ["DR%d" % i for i in range(8)] drregs32_expr = [ExprId(x, 32) for x in drregs32_str] drregs = reg_info(drregs32_str, drregs32_expr) -fltregs32_str = ["ST(%d)" % i for i in xrange(8)] +fltregs32_str = ["ST(%d)" % i for i in range(8)] fltregs32_expr = [ExprId(x, 64) for x in fltregs32_str] fltregs = reg_info(fltregs32_str, fltregs32_expr) @@ -345,7 +346,7 @@ float_st7 = ExprId("float_st7", 64) float_list = [float_st0, float_st1, float_st2, float_st3, float_st4, float_st5, float_st6, float_st7] -float_replace = {fltregs32_expr[i]: float_list[i] for i in xrange(8)} +float_replace = {fltregs32_expr[i]: float_list[i] for i in range(8)} float_replace[r_st_all.expr[0]] = float_st0 diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index d03a7cd4..bec09249 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -16,6 +16,10 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # +from builtins import range + +from future.utils import viewitems + import logging import miasm2.expression.expression as m2_expr from miasm2.expression.simplifications import expr_simp @@ -882,7 +886,7 @@ def push_gen(ir, instr, src, size): off_size = src.size sp = mRSP[instr.mode] - new_sp = sp - m2_expr.ExprInt(off_size / 8, sp.size) + new_sp = sp - m2_expr.ExprInt(off_size // 8, sp.size) e.append(m2_expr.ExprAssign(sp, new_sp)) if ir.do_stk_segm: new_sp = ir.gen_segm_expr(SS, new_sp) @@ -905,7 +909,7 @@ def pop_gen(ir, instr, src, size): raise ValueError('bad size stacker!') sp = mRSP[instr.mode] - new_sp = sp + m2_expr.ExprInt(src.size / 8, sp.size) + new_sp = sp + m2_expr.ExprInt(src.size // 8, sp.size) # don't generate ESP incrementation on POP ESP if src != ir.sp: e.append(m2_expr.ExprAssign(sp, new_sp)) @@ -1187,7 +1191,7 @@ def cmps(ir, instr, size): src1_sgm = src1 src2_sgm = src2 - offset = m2_expr.ExprInt(size / 8, src1.size) + offset = m2_expr.ExprInt(size // 8, src1.size) e, _ = l_cmp(ir, instr, ir.ExprMem(src1_sgm, size), @@ -1226,7 +1230,7 @@ def scas(ir, instr, size): else: src_sgm = src - offset = m2_expr.ExprInt(size / 8, src.size) + offset = m2_expr.ExprInt(size // 8, src.size) e, extra = l_cmp(ir, instr, mRAX[instr.mode][:size], ir.ExprMem(src_sgm, size)) @@ -1298,7 +1302,7 @@ def popfd(ir, instr): e.append(m2_expr.ExprAssign(vip, m2_expr.ExprSlice(tmp, 20, 21))) e.append(m2_expr.ExprAssign(i_d, m2_expr.ExprSlice(tmp, 21, 22))) e.append(m2_expr.ExprAssign(mRSP[instr.mode], - mRSP[instr.mode] + m2_expr.ExprInt(instr.mode / 8, mRSP[instr.mode].size))) + mRSP[instr.mode] + m2_expr.ExprInt(instr.mode // 8, mRSP[instr.mode].size))) e.append(m2_expr.ExprAssign(exception_flags, m2_expr.ExprCond(m2_expr.ExprSlice(tmp, 8, 9), m2_expr.ExprInt( @@ -1339,7 +1343,7 @@ def pusha_gen(ir, instr, size): e = [] cur_sp = mRSP[instr.mode] for i, reg in enumerate(pa_regs): - stk_ptr = cur_sp + m2_expr.ExprInt(-(size / 8) * (i + 1), instr.mode) + stk_ptr = cur_sp + m2_expr.ExprInt(-(size // 8) * (i + 1), instr.mode) e.append(m2_expr.ExprAssign(ir.ExprMem(stk_ptr, size), reg[size])) e.append(m2_expr.ExprAssign(cur_sp, stk_ptr)) return e, [] @@ -1359,10 +1363,10 @@ def popa_gen(ir, instr, size): for i, reg in enumerate(reversed(pa_regs)): if reg == mRSP: continue - stk_ptr = cur_sp + m2_expr.ExprInt((size / 8) * i, instr.mode) + stk_ptr = cur_sp + m2_expr.ExprInt((size // 8) * i, instr.mode) e.append(m2_expr.ExprAssign(reg[size], ir.ExprMem(stk_ptr, size))) - stk_ptr = cur_sp + m2_expr.ExprInt((size / 8) * (i + 1), instr.mode) + stk_ptr = cur_sp + m2_expr.ExprInt((size // 8) * (i + 1), instr.mode) e.append(m2_expr.ExprAssign(cur_sp, stk_ptr)) return e, [] @@ -1407,19 +1411,19 @@ def call(ir, instr, dst): e.append(m2_expr.ExprAssign(ir.IRDst, m2)) - c = myesp + m2_expr.ExprInt(-s / 8, s) + c = myesp + m2_expr.ExprInt(-s // 8, s) e.append(m2_expr.ExprAssign(ir.ExprMem(c, size=s).zeroExtend(s), CS.zeroExtend(s))) - c = myesp + m2_expr.ExprInt(-2 * s / 8, s) + c = myesp + m2_expr.ExprInt((-2 * s) // 8, s) e.append(m2_expr.ExprAssign(ir.ExprMem(c, size=s).zeroExtend(s), meip.zeroExtend(s))) - c = myesp + m2_expr.ExprInt((-2 * s) / 8, s) + c = myesp + m2_expr.ExprInt((-2 * s) // 8, s) e.append(m2_expr.ExprAssign(myesp, c)) return e, [] - c = myesp + m2_expr.ExprInt((-s / 8), s) + c = myesp + m2_expr.ExprInt(-s // 8, s) e.append(m2_expr.ExprAssign(myesp, c)) if ir.do_stk_segm: c = ir.gen_segm_expr(SS, c) @@ -1437,10 +1441,10 @@ def ret(ir, instr, src=None): myesp = mRSP[instr.mode][:size] if src is None: - value = (myesp + (m2_expr.ExprInt((size / 8), size))) + value = (myesp + (m2_expr.ExprInt(size // 8, size))) else: src = m2_expr.ExprInt(int(src), size) - value = (myesp + (m2_expr.ExprInt((size / 8), size) + src)) + value = (myesp + (m2_expr.ExprInt(size // 8, size) + src)) e.append(m2_expr.ExprAssign(myesp, value)) result = myesp @@ -1473,13 +1477,13 @@ def retf(ir, instr, src=None): e.append(m2_expr.ExprAssign(ir.IRDst, ir.ExprMem(result, size=size).zeroExtend(size))) # e.append(m2_expr.ExprAssign(meip, ir.ExprMem(c, size = s))) - result = myesp + m2_expr.ExprInt(size / 8, size) + result = myesp + m2_expr.ExprInt(size // 8, size) if ir.do_stk_segm: result = ir.gen_segm_expr(SS, result) e.append(m2_expr.ExprAssign(CS, ir.ExprMem(result, size=16))) - value = myesp + (m2_expr.ExprInt((2 * size) / 8, size) + src) + value = myesp + (m2_expr.ExprInt((2 * size) // 8, size) + src) e.append(m2_expr.ExprAssign(myesp, value)) return e, [] @@ -1490,7 +1494,7 @@ def leave(ir, instr): e = [] e.append(m2_expr.ExprAssign(mRBP[size], ir.ExprMem(mRBP[size], size=size))) e.append(m2_expr.ExprAssign(myesp, - m2_expr.ExprInt(size / 8, size) + mRBP[size])) + m2_expr.ExprInt(size // 8, size) + mRBP[size])) return e, [] @@ -1502,12 +1506,12 @@ def enter(ir, instr, src1, src2): src1 = src1.zeroExtend(size) e = [] - esp_tmp = myesp - m2_expr.ExprInt(size / 8, size) + esp_tmp = myesp - m2_expr.ExprInt(size // 8, size) e.append(m2_expr.ExprAssign(ir.ExprMem(esp_tmp, size=size), myebp)) e.append(m2_expr.ExprAssign(myebp, esp_tmp)) e.append(m2_expr.ExprAssign(myesp, - myesp - (src1 + m2_expr.ExprInt(size / 8, size)))) + myesp - (src1 + m2_expr.ExprInt(size // 8, size)))) return e, [] @@ -1930,8 +1934,8 @@ def stos(ir, instr, size): addr_o = mRDI[instr.mode][:instr.v_admode()] addr = addr_o - addr_p = addr + m2_expr.ExprInt(size / 8, addr.size) - addr_m = addr - m2_expr.ExprInt(size / 8, addr.size) + addr_p = addr + m2_expr.ExprInt(size // 8, addr.size) + addr_m = addr - m2_expr.ExprInt(size // 8, addr.size) if ir.do_str_segm: mss = ES if instr.additional_info.g2.value: @@ -1966,8 +1970,8 @@ def lods(ir, instr, size): addr_o = mRSI[instr.mode][:instr.v_admode()] addr = addr_o - addr_p = addr + m2_expr.ExprInt(size / 8, addr.size) - addr_m = addr - m2_expr.ExprInt(size / 8, addr.size) + addr_p = addr + m2_expr.ExprInt(size // 8, addr.size) + addr_m = addr - m2_expr.ExprInt(size // 8, addr.size) if ir.do_str_segm: mss = DS if instr.additional_info.g2.value: @@ -2018,7 +2022,7 @@ def movs(ir, instr, size): src_sgm = src dst_sgm = dst - offset = m2_expr.ExprInt(size / 8, src.size) + offset = m2_expr.ExprInt(size // 8, src.size) e.append(m2_expr.ExprAssign(ir.ExprMem(dst_sgm, size), ir.ExprMem(src_sgm, size))) @@ -2081,12 +2085,12 @@ def float_pop(avoid_flt=None, popcount=1): """ avoid_flt = float_prev(avoid_flt, popcount) e = [] - for i in xrange(8 - popcount): + for i in range(8 - popcount): if avoid_flt != float_list[i]: e.append(m2_expr.ExprAssign(float_list[i], float_list[i + popcount])) fill_value = m2_expr.ExprOp("sint_to_fp", m2_expr.ExprInt(0, 64)) - for i in xrange(8 - popcount, 8): + for i in range(8 - popcount, 8): e.append(m2_expr.ExprAssign(float_list[i], fill_value)) e.append( @@ -2619,20 +2623,45 @@ def fnstenv(ir, instr, dst): size = min(32, s) ad = ir.ExprMem(dst.ptr, size=16) e.append(m2_expr.ExprAssign(ad, float_control)) - ad = ir.ExprMem(dst.ptr + m2_expr.ExprInt(size / - 8 * 1, dst.ptr.size), size=16) + ad = ir.ExprMem( + dst.ptr + m2_expr.ExprInt( + size // (8 * 1), + dst.ptr.size + ), + size=16 + ) e.append(m2_expr.ExprAssign(ad, status_word)) - ad = ir.ExprMem(dst.ptr + m2_expr.ExprInt(size / - 8 * 3, dst.ptr.size), size=size) + ad = ir.ExprMem( + dst.ptr + m2_expr.ExprInt( + size // (8 * 3), + dst.ptr.size + ), + size=size + ) e.append(m2_expr.ExprAssign(ad, float_eip[:size])) - ad = ir.ExprMem(dst.ptr + m2_expr.ExprInt(size / - 8 * 4, dst.ptr.size), size=16) + ad = ir.ExprMem( + dst.ptr + m2_expr.ExprInt( + size // (8 * 4), + dst.ptr.size + ), + size=16 + ) e.append(m2_expr.ExprAssign(ad, float_cs)) - ad = ir.ExprMem(dst.ptr + m2_expr.ExprInt(size / - 8 * 5, dst.ptr.size), size=size) + ad = ir.ExprMem( + dst.ptr + m2_expr.ExprInt( + size // (8 * 5), + dst.ptr.size + ), + size=size + ) e.append(m2_expr.ExprAssign(ad, float_address[:size])) - ad = ir.ExprMem(dst.ptr + m2_expr.ExprInt(size / - 8 * 6, dst.ptr.size), size=16) + ad = ir.ExprMem( + dst.ptr + m2_expr.ExprInt( + size // (8 * 6), + dst.ptr.size + ), + size=16 + ) e.append(m2_expr.ExprAssign(ad, float_ds)) return e, [] @@ -2651,23 +2680,35 @@ def fldenv(ir, instr, src): e.append(m2_expr.ExprAssign(float_control, ad)) # Status word - ad = ir.ExprMem(src.ptr + m2_expr.ExprInt(size / 8 * 1, size=src.ptr.size), - size=16) - e += [m2_expr.ExprAssign(x, y) for x, y in ((float_c0, ad[8:9]), - (float_c1, ad[9:10]), - (float_c2, ad[10:11]), - (float_stack_ptr, ad[11:14]), - (float_c3, ad[14:15])) - ] + ad = ir.ExprMem( + src.ptr + m2_expr.ExprInt( + size // (8 * 1), + size=src.ptr.size + ), + size=16 + ) + e += [ + m2_expr.ExprAssign(x, y) for x, y in ((float_c0, ad[8:9]), + (float_c1, ad[9:10]), + (float_c2, ad[10:11]), + (float_stack_ptr, ad[11:14]), + (float_c3, ad[14:15])) + ] # EIP, CS, Address, DS - for offset, target in ((3, float_eip[:size]), - (4, float_cs), - (5, float_address[:size]), - (6, float_ds)): - ad = ir.ExprMem(src.ptr + m2_expr.ExprInt(size / 8 * offset, - size=src.ptr.size), - size=target.size) + for offset, target in ( + (3, float_eip[:size]), + (4, float_cs), + (5, float_address[:size]), + (6, float_ds) + ): + ad = ir.ExprMem( + src.ptr + m2_expr.ExprInt( + size // ( 8 * offset), + size=src.ptr.size + ), + size=target.size + ) e.append(m2_expr.ExprAssign(target, ad)) return e, [] @@ -3243,7 +3284,7 @@ def sidt(ir, instr, dst): if not isinstance(dst, m2_expr.ExprMem) or dst.size != 32: raise ValueError('not exprmem 32bit instance!!') ptr = dst.ptr - LOG_X86_SEM.warning("DEFAULT SIDT ADDRESS %s!!", str(dst)) + LOG_X86_SEM.warning("DEFAULT SIDT ADDRESS %s!!", dst) e.append(m2_expr.ExprAssign(ir.ExprMem(ptr, 32), m2_expr.ExprInt(0xe40007ff, 32))) e.append( @@ -3253,7 +3294,7 @@ def sidt(ir, instr, dst): def sldt(_, instr, dst): - LOG_X86_SEM.warning("DEFAULT SLDT ADDRESS %s!!", str(dst)) + LOG_X86_SEM.warning("DEFAULT SLDT ADDRESS %s!!", dst) e = [m2_expr.ExprAssign(dst, m2_expr.ExprInt(0, dst.size))] return e, [] @@ -3531,7 +3572,7 @@ def cmpxchg16b(arg1): def lds(ir, instr, dst, src): e = [] e.append(m2_expr.ExprAssign(dst, ir.ExprMem(src.ptr, size=dst.size))) - DS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size / 8, src.ptr.size), + DS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size // 8, src.ptr.size), size=16) e.append(m2_expr.ExprAssign(DS, DS_value)) return e, [] @@ -3540,7 +3581,7 @@ def lds(ir, instr, dst, src): def les(ir, instr, dst, src): e = [] e.append(m2_expr.ExprAssign(dst, ir.ExprMem(src.ptr, size=dst.size))) - ES_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size / 8, src.ptr.size), + ES_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size // 8, src.ptr.size), size=16) e.append(m2_expr.ExprAssign(ES, ES_value)) return e, [] @@ -3549,7 +3590,7 @@ def les(ir, instr, dst, src): def lss(ir, instr, dst, src): e = [] e.append(m2_expr.ExprAssign(dst, ir.ExprMem(src.ptr, size=dst.size))) - SS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size / 8, src.ptr.size), + SS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size // 8, src.ptr.size), size=16) e.append(m2_expr.ExprAssign(SS, SS_value)) return e, [] @@ -3558,7 +3599,7 @@ def lss(ir, instr, dst, src): def lfs(ir, instr, dst, src): e = [] e.append(m2_expr.ExprAssign(dst, ir.ExprMem(src.ptr, size=dst.size))) - FS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size / 8, src.ptr.size), + FS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size // 8, src.ptr.size), size=16) e.append(m2_expr.ExprAssign(FS, FS_value)) return e, [] @@ -3567,7 +3608,7 @@ def lfs(ir, instr, dst, src): def lgs(ir, instr, dst, src): e = [] e.append(m2_expr.ExprAssign(dst, ir.ExprMem(src.ptr, size=dst.size))) - GS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size / 8, src.ptr.size), + GS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size // 8, src.ptr.size), size=16) e.append(m2_expr.ExprAssign(GS, GS_value)) return e, [] @@ -3704,18 +3745,18 @@ def vec_op_clip(op, size, callback=None): def vec_vertical_sem(op, elt_size, reg_size, dst, src, apply_on_output): assert reg_size % elt_size == 0 - n = reg_size / elt_size + n = reg_size // elt_size if op == '-': ops = [ apply_on_output((dst[i * elt_size:(i + 1) * elt_size] - src[i * elt_size:(i + 1) * elt_size])) - for i in xrange(0, n) + for i in range(0, n) ] else: ops = [ apply_on_output(m2_expr.ExprOp(op, dst[i * elt_size:(i + 1) * elt_size], src[i * elt_size:(i + 1) * elt_size])) - for i in xrange(0, n) + for i in range(0, n) ] return m2_expr.ExprCompose(*ops) @@ -3857,7 +3898,7 @@ def pmaddwd(ir, instr, dst, src): sizedst = 32 sizesrc = 16 out = [] - for start in xrange(0, dst.size, sizedst): + for start in range(0, dst.size, sizedst): base = start mul1 = src[base: base + sizesrc].signExtend(sizedst) * dst[base: base + sizesrc].signExtend(sizedst) base += sizesrc @@ -3877,9 +3918,9 @@ def psadbw(ir, instr, dst, src): sizedst = 16 sizesrc = 8 out_dst = [] - for start in xrange(0, dst.size, 64): + for start in range(0, dst.size, 64): out = [] - for src_start in xrange(0, 64, sizesrc): + for src_start in range(0, 64, sizesrc): beg = start + src_start end = beg + sizesrc # Not clear in the doc equations, but in the text, src and dst are: @@ -4311,7 +4352,7 @@ def pshufb(_, instr, dst, src): bit_l = 4 else: raise NotImplementedError("bad size") - for i in xrange(0, src.size, 8): + for i in range(0, src.size, 8): index = src[ i:i + bit_l].zeroExtend(dst.size) << m2_expr.ExprInt(3, dst.size) value = (dst >> index)[:8] @@ -4325,7 +4366,7 @@ def pshufb(_, instr, dst, src): def pshufd(_, instr, dst, src, imm): control = int(imm) out = [] - for i in xrange(4): + for i in range(4): shift = ((control >> (i * 2)) & 3) * 32 # shift is 2 bits long, expr.size is 128 # => shift + 32 <= src.size @@ -4336,7 +4377,7 @@ def pshufd(_, instr, dst, src, imm): def pshuflw(_, instr, dst, src, imm): control = int(imm) out = [] - for i in xrange(4): + for i in range(4): shift = ((control >> (i * 2)) & 3) * 16 out.append(src[shift: shift + 16]) out.append(src[64:]) @@ -4346,7 +4387,7 @@ def pshuflw(_, instr, dst, src, imm): def pshufhw(_, instr, dst, src, imm): control = int(imm) out = [src[:64]] - for i in xrange(4): + for i in range(4): shift = ((control >> (i * 2)) & 3) * 16 out.append(src[shift + 64: shift + 16 + 64]) return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out))], [] @@ -4369,7 +4410,7 @@ def ps_rl_ll(ir, instr, dst, src, op, size): count = expr_simp(count) out = [] - for i in xrange(0, dst.size, size): + for i in range(0, dst.size, size): out.append(m2_expr.ExprOp(op, dst[i:i + size], count)) return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out))], [] @@ -4430,15 +4471,15 @@ def iret(ir, instr): XXX: only support "no-privilege change" """ size = instr.v_opmode() - exprs, _ = retf(ir, instr, m2_expr.ExprInt(size / 8, size=size)) - tmp = mRSP[instr.mode][:size] + m2_expr.ExprInt((2 * size) / 8, size=size) + exprs, _ = retf(ir, instr, m2_expr.ExprInt(size // 8, size=size)) + tmp = mRSP[instr.mode][:size] + m2_expr.ExprInt((2 * size) // 8, size=size) exprs += _tpl_eflags(tmp) return exprs, [] def pcmpeq(_, instr, dst, src, size): e = [] - for i in xrange(0, dst.size, size): + for i in range(0, dst.size, size): test = m2_expr.expr_is_equal(dst[i:i + size], src[i:i + size]) e.append(m2_expr.ExprAssign(dst[i:i + size], m2_expr.ExprCond(test, @@ -4449,7 +4490,7 @@ def pcmpeq(_, instr, dst, src, size): def pcmpgt(_, instr, dst, src, size): e = [] - for i in xrange(0, dst.size, size): + for i in range(0, dst.size, size): test = m2_expr.expr_is_signed_greater(dst[i:i + size], src[i:i + size]) e.append(m2_expr.ExprAssign(dst[i:i + size], m2_expr.ExprCond(test, @@ -4490,7 +4531,7 @@ def pcmpgtq(ir, instr, dst, src): def punpck(_, instr, dst, src, size, off): e = [] slices = [] - for i in xrange(dst.size / (2 * size)): + for i in range(dst.size // (2 * size)): slices.append(dst[size * i + off: size * i + off + size]) slices.append(src[size * i + off: size * i + off + size]) e.append(m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*slices))) @@ -4498,19 +4539,19 @@ def punpck(_, instr, dst, src, size, off): def punpckhbw(ir, instr, dst, src): - return punpck(ir, instr, dst, src, 8, dst.size / 2) + return punpck(ir, instr, dst, src, 8, dst.size // 2) def punpckhwd(ir, instr, dst, src): - return punpck(ir, instr, dst, src, 16, dst.size / 2) + return punpck(ir, instr, dst, src, 16, dst.size // 2) def punpckhdq(ir, instr, dst, src): - return punpck(ir, instr, dst, src, 32, dst.size / 2) + return punpck(ir, instr, dst, src, 32, dst.size // 2) def punpckhqdq(ir, instr, dst, src): - return punpck(ir, instr, dst, src, 64, dst.size / 2) + return punpck(ir, instr, dst, src, 64, dst.size // 2) def punpcklbw(ir, instr, dst, src): @@ -4667,7 +4708,7 @@ def movq2dq(_, instr, dst, src): def sqrt_gen(_, instr, dst, src, size): e = [] out = [] - for i in xrange(src.size / size): + for i in range(src.size // size): out.append(m2_expr.ExprOp('fsqrt', src[i * size: (i + 1) * size])) src = m2_expr.ExprCompose(*out) @@ -4702,7 +4743,7 @@ def sqrtss(_, instr, dst, src): def pmovmskb(_, instr, dst, src): e = [] out = [] - for i in xrange(src.size / 8): + for i in range(src.size // 8): out.append(src[8 * i + 7:8 * (i + 1)]) src = m2_expr.ExprCompose(*out) e.append(m2_expr.ExprAssign(dst, src.zeroExtend(dst.size))) @@ -4807,7 +4848,7 @@ def _unsigned_saturation(expr, dst_size): def packsswb(ir, instr, dst, src): out = [] for source in [dst, src]: - for start in xrange(0, dst.size, 16): + for start in range(0, dst.size, 16): out.append(_signed_saturation(source[start:start + 16], 8)) return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out))], [] @@ -4815,7 +4856,7 @@ def packsswb(ir, instr, dst, src): def packssdw(ir, instr, dst, src): out = [] for source in [dst, src]: - for start in xrange(0, dst.size, 32): + for start in range(0, dst.size, 32): out.append(_signed_saturation(source[start:start + 32], 16)) return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out))], [] @@ -4823,7 +4864,7 @@ def packssdw(ir, instr, dst, src): def packuswb(ir, instr, dst, src): out = [] for source in [dst, src]: - for start in xrange(0, dst.size, 16): + for start in range(0, dst.size, 16): out.append(_unsigned_saturation(source[start:start + 16], 8)) return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out))], [] @@ -4894,13 +4935,13 @@ def maskmovq(ir, instr, src, mask): # For each possibility, check if a write is necessary check_labels = [m2_expr.ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) - for _ in xrange(0, mask.size, 8)] + for _ in range(0, mask.size, 8)] # If the write has to be done, do it (otherwise, nothing happen) write_labels = [m2_expr.ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) - for _ in xrange(0, mask.size, 8)] + for _ in range(0, mask.size, 8)] # Build check blocks - for i, start in enumerate(xrange(0, mask.size, 8)): + for i, start in enumerate(range(0, mask.size, 8)): bit = mask[start + 7: start + 8] cur_label = check_labels[i] next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else loc_next_expr @@ -4913,7 +4954,7 @@ def maskmovq(ir, instr, src, mask): # Build write blocks dst_addr = mRDI[instr.mode] - for i, start in enumerate(xrange(0, mask.size, 8)): + for i, start in enumerate(range(0, mask.size, 8)): cur_label = write_labels[i] next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else loc_next_expr write_addr = dst_addr + m2_expr.ExprInt(i, dst_addr.size) @@ -4972,7 +5013,7 @@ def _select4(src, control): def shufps(ir, instr, dst, src, imm8): out = [] control = int(imm8) - for i in xrange(4): + for i in range(4): if i < 2: source = dst else: @@ -4990,13 +5031,13 @@ def shufpd(ir, instr, dst, src, imm8): def movmskps(ir, instr, dst, src): out = [] - for i in xrange(4): + for i in range(4): out.append(src[(32 * i) + 31:(32 * i) + 32]) return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out).zeroExtend(dst.size))], [] def movmskpd(ir, instr, dst, src): out = [] - for i in xrange(2): + for i in range(2): out.append(src[(64 * i) + 63:(64 * i) + 64]) return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out).zeroExtend(dst.size))], [] @@ -5720,7 +5761,7 @@ class ir_x86_16(IntermediateRepresentation): irs = [] for assignblk in irblock: new_assignblk = dict(assignblk) - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): del new_assignblk[dst] # Special case for 64 bits: # If destination is a 32 bit reg, zero extend the 64 bit reg diff --git a/miasm2/core/asm_ast.py b/miasm2/core/asm_ast.py index 3b06ce62..69ff1f9c 100644 --- a/miasm2/core/asm_ast.py +++ b/miasm2/core/asm_ast.py @@ -1,3 +1,5 @@ +from builtins import int as int_types + class AstNode(object): """ Ast node object @@ -68,7 +70,7 @@ class AstMem(AstNode): """ def __init__(self, ptr, size): assert isinstance(ptr, AstNode) - assert isinstance(size, (int, long)) + assert isinstance(size, int_types) self.ptr = ptr self.size = size diff --git a/miasm2/core/asmblock.py b/miasm2/core/asmblock.py index f6e68a0e..811cc824 100644 --- a/miasm2/core/asmblock.py +++ b/miasm2/core/asmblock.py @@ -1,8 +1,13 @@ #-*- coding:utf-8 -*- +from builtins import map +from builtins import range import logging import warnings from collections import namedtuple +from builtins import int as int_types + +from future.utils import viewitems, viewvalues from miasm2.expression.expression import ExprId, ExprInt, get_expr_locs from miasm2.expression.expression import LocKey @@ -22,14 +27,12 @@ log_asmblock.setLevel(logging.WARNING) def is_int(a): - return isinstance(a, int) or isinstance(a, long) or \ - isinstance(a, moduint) or isinstance(a, modint) - + return isinstance(a, (modint, moduint, int_types)) class AsmRaw(object): - def __init__(self, raw=""): + def __init__(self, raw=b""): self.raw = raw def __str__(self): @@ -41,7 +44,7 @@ class AsmRaw(object): class asm_raw(AsmRaw): - def __init__(self, raw=""): + def __init__(self, raw=b""): warnings.warn('DEPRECATION WARNING: use "AsmRaw" instead of "asm_raw"') super(asm_label, self).__init__(raw) @@ -190,7 +193,8 @@ class AsmBlock(object): for xx in self.bto: log_asmblock.debug('lbl %s', xx) c_next = set( - [x for x in self.bto if x.c_t == AsmConstraint.c_next]) + x for x in self.bto if x.c_t == AsmConstraint.c_next + ) c_to = [x for x in self.bto if x.c_t != AsmConstraint.c_next] self.bto = set([c] + c_to) new_bloc.bto = c_next @@ -223,7 +227,7 @@ class AsmBlock(object): def get_flow_instr(self): if not self.lines: return None - for i in xrange(-1, -1 - self.lines[0].delayslot - 1, -1): + for i in range(-1, -1 - self.lines[0].delayslot - 1, -1): if not 0 <= i < len(self.lines): return None l = self.lines[i] @@ -236,7 +240,7 @@ class AsmBlock(object): delayslot = self.lines[0].delayslot end_index = len(self.lines) - 1 ds_max_index = max(end_index - delayslot, 0) - for i in xrange(end_index, ds_max_index - 1, -1): + for i in range(end_index, ds_max_index - 1, -1): l = self.lines[i] if l.is_subcall(): return l @@ -280,8 +284,10 @@ class AsmBlock(object): for constraint in self.bto: dests.setdefault(constraint.loc_key, set()).add(constraint) - self.bto = set(self._filter_constraint(constraints) - for constraints in dests.itervalues()) + self.bto = set( + self._filter_constraint(constraints) + for constraints in viewvalues(dests) + ) class asm_bloc(object): @@ -324,8 +330,10 @@ class AsmBlockBad(AsmBlock): def __str__(self): error_txt = self.ERROR_TYPES.get(self._errno, self._errno) - return "\n".join([str(self.loc_key), - "\tBad block: %s" % error_txt]) + return "%s\n\tBad block: %s" % ( + self.loc_key, + error_txt + ) def addline(self, *args, **kwargs): raise RuntimeError("An AsmBlockBad cannot have line") @@ -421,7 +429,9 @@ class AsmCFG(DiGraph): """Return the number of blocks in AsmCFG""" return len(self._nodes) - blocks = property(lambda x:x._loc_key_to_block.itervalues()) + @property + def blocks(self): + return viewvalues(self._loc_key_to_block) # Manage graph with associated constraints def add_edge(self, src, dst, constraint): @@ -536,7 +546,7 @@ class AsmCFG(DiGraph): def node2lines(self, node): if self.loc_db is None: - loc_key_name = str(node) + loc_key_name = node else: loc_key_name = self.loc_db.pretty_str(node) yield self.DotCellDescription(text=loc_key_name, @@ -545,7 +555,7 @@ class AsmCFG(DiGraph): 'bgcolor': 'grey'}) block = self._loc_key_to_block.get(node, None) if block is None: - raise StopIteration + return if isinstance(block, AsmBlockBad): yield [ self.DotCellDescription( @@ -554,7 +564,7 @@ class AsmCFG(DiGraph): ), attr={}) ] - raise StopIteration + return for line in block.lines: if self._dot_offset: yield [self.DotCellDescription(text="%.8X" % line.offset, @@ -700,14 +710,20 @@ class AsmCFG(DiGraph): """ if len(self._pendings) != 0: - raise RuntimeError("Some blocks are missing: %s" % map( - str, - self._pendings.keys() - )) + raise RuntimeError( + "Some blocks are missing: %s" % list( + map( + str, + self._pendings + ) + ) + ) - next_edges = {edge: constraint - for edge, constraint in self.edges2constraint.iteritems() - if constraint == AsmConstraint.c_next} + next_edges = { + edge: constraint + for edge, constraint in viewitems(self.edges2constraint) + if constraint == AsmConstraint.c_next + } for loc_key in self._nodes: if loc_key not in self._loc_key_to_block: @@ -740,8 +756,11 @@ class AsmCFG(DiGraph): if len(instr.raw) == 0: l = 0 else: - l = instr.raw[0].size / 8 * len(instr.raw) + l = (instr.raw[0].size // 8) * len(instr.raw) elif isinstance(instr.raw, str): + data = instr.raw.encode() + l = len(data) + elif isinstance(instr.raw, bytes): data = instr.raw l = len(data) else: @@ -1148,7 +1167,7 @@ def resolve_symbol(blockChains, loc_db, dst_interval=None): if chain.pinned: continue fixed = False - for i in xrange(1, len(fixed_chains)): + for i in range(1, len(fixed_chains)): prev_chain = fixed_chains[i - 1] next_chain = fixed_chains[i] @@ -1187,7 +1206,7 @@ def assemble_block(mnemo, block, loc_db, conservative=False): if isinstance(instr, AsmRaw): if isinstance(instr.raw, list): # Fix special AsmRaw - data = "" + data = b"" for expr in instr.raw: expr_int = fix_expr_val(expr, loc_db) data += pck[expr_int.size](expr_int.arg) @@ -1471,7 +1490,7 @@ class disasmEngine(object): # XXX TODO nul start block option if (self.dont_dis_nulstart_bloc and not cur_block.lines and - instr.b.count('\x00') == instr.l): + instr.b.count(b'\x00') == instr.l): log_asmblock.warning("reach nul instr at %X", int(off_i)) # Block is empty -> bad block cur_block = AsmBlockBad(loc_key, errno=AsmBlockBad.ERROR_NULL_STARTING_BLOCK) diff --git a/miasm2/core/bin_stream.py b/miasm2/core/bin_stream.py index af31a52c..4977e2ae 100644 --- a/miasm2/core/bin_stream.py +++ b/miasm2/core/bin_stream.py @@ -16,6 +16,9 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # +from builtins import str +from future.utils import PY3 + from miasm2.core.utils import BIG_ENDIAN, LITTLE_ENDIAN from miasm2.core.utils import upck8le, upck16le, upck32le, upck64le from miasm2.core.utils import upck8be, upck16be, upck32be, upck64be @@ -35,6 +38,11 @@ class bin_stream(object): def __repr__(self): return "<%s !!>" % self.__class__.__name__ + def __str__(self): + if PY3: + return repr(self) + return self.__bytes__() + def hexdump(self, offset, l): return @@ -81,8 +89,8 @@ class bin_stream(object): # Get initial bytes if n > self.getlen() * 8: raise IOError('not enough bits %r %r' % (n, len(self.bin) * 8)) - byte_start = start / 8 - byte_stop = (start + n + 7) / 8 + byte_start = start // 8 + byte_stop = (start + n + 7) // 8 temp = self.getbytes(byte_start, byte_stop - byte_start) if not temp: raise IOError('cannot get bytes') @@ -92,8 +100,8 @@ class bin_stream(object): out = 0 while n: # Get needed bits, working on maximum 8 bits at a time - cur_byte_idx = start / 8 - new_bits = ord(temp[cur_byte_idx]) + cur_byte_idx = start // 8 + new_bits = ord(temp[cur_byte_idx:cur_byte_idx + 1]) to_keep = 8 - start % 8 new_bits &= (1 << to_keep) - 1 cur_len = min(to_keep, n) @@ -160,7 +168,7 @@ class bin_stream(object): class bin_stream_str(bin_stream): - def __init__(self, input_str="", offset=0L, base_address=0, shift=None): + def __init__(self, input_str=b"", offset=0, base_address=0, shift=None): bin_stream.__init__(self) if shift is not None: raise DeprecationWarning("use base_address instead of shift") @@ -185,9 +193,8 @@ class bin_stream_str(bin_stream): self.offset += l return self.bin[self.offset - l - self.base_address:self.offset - self.base_address] - def __str__(self): - out = self.bin[self.offset - self.base_address:] - return out + def __bytes__(self): + return self.bin[self.offset - self.base_address:] def setoffset(self, val): self.offset = val @@ -198,7 +205,7 @@ class bin_stream_str(bin_stream): class bin_stream_file(bin_stream): - def __init__(self, binary, offset=0L, base_address=0, shift=None): + def __init__(self, binary, offset=0, base_address=0, shift=None): bin_stream.__init__(self) if shift is not None: raise DeprecationWarning("use base_address instead of shift") @@ -222,8 +229,8 @@ class bin_stream_file(bin_stream): raise IOError("Negative offset") return self.bin.read(l) - def __str__(self): - return str(self.bin) + def __bytes__(self): + return self.bin.read() def getlen(self): return self.l - (self.offset - self.base_address) @@ -231,7 +238,7 @@ class bin_stream_file(bin_stream): class bin_stream_container(bin_stream): - def __init__(self, binary, offset=0L): + def __init__(self, binary, offset=0): bin_stream.__init__(self) self.bin = binary self.l = binary.virt.max_addr() @@ -257,9 +264,8 @@ class bin_stream_container(bin_stream): except ValueError: raise IOError("cannot get bytes") - def __str__(self): - out = self.bin.virt.get(self.offset, self.offset + self.l) - return out + def __bytes__(self): + return self.bin.virt.get(self.offset, self.offset + self.l) def setoffset(self, val): self.offset = val @@ -279,7 +285,7 @@ class bin_stream_elf(bin_stream_container): class bin_stream_vm(bin_stream): - def __init__(self, vm, offset=0L, base_offset=0L): + def __init__(self, vm, offset=0, base_offset=0): self.offset = offset self.base_offset = base_offset self.vm = vm diff --git a/miasm2/core/bin_stream_ida.py b/miasm2/core/bin_stream_ida.py index fcd89f9f..44cf9367 100644 --- a/miasm2/core/bin_stream_ida.py +++ b/miasm2/core/bin_stream_ida.py @@ -1,7 +1,9 @@ +from builtins import range from idc import Byte, SegEnd from idautils import Segments from idaapi import is_mapped +from miasm2.core.utils import int_to_byte from miasm2.core.bin_stream import bin_stream_str @@ -13,13 +15,13 @@ class bin_stream_ida(bin_stream_str): It can raise error on overflow 7FFFFFFF with 32 bit python """ def _getbytes(self, start, l=1): - o = "" - for ad in xrange(l): + out = [] + for ad in range(l): offset = ad + start + self.base_address if not is_mapped(offset): raise IOError("not enough bytes") - o += chr(Byte(offset)) - return o + out.append(int_to_byte(Byte(offset))) + return b''.join(out) def readbs(self, l=1): if self.offset + l > self.l: diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py index c2fbd3cd..c24b693d 100644 --- a/miasm2/core/cpu.py +++ b/miasm2/core/cpu.py @@ -1,12 +1,17 @@ #-*- coding:utf-8 -*- +from builtins import range import re import struct import logging from collections import defaultdict + +from future.utils import viewitems, viewvalues + import pyparsing +from miasm2.core.utils import decode_hex import miasm2.expression.expression as m2_expr from miasm2.core.bin_stream import bin_stream, bin_stream_str from miasm2.core.utils import Disasm_Exception @@ -15,6 +20,7 @@ from miasm2.core.locationdb import LocationDB from miasm2.core.asm_ast import AstNode, AstInt, AstId, AstOp +from future.utils import with_metaclass log = logging.getLogger("cpuhelper") console_handler = logging.StreamHandler() @@ -23,17 +29,15 @@ log.addHandler(console_handler) log.setLevel(logging.WARN) -class bitobj: +class bitobj(object): - def __init__(self, s=""): + def __init__(self, s=b""): if not s: bits = [] else: - bits = list(bin(int(str(s).encode('hex'), 16))[2:]) - bits = [int(x) for x in bits] + bits = [int(x) for x in bin(int(encode_hex(s), 16))[2:]] if len(bits) % 8: - bits = [0 for x in xrange(8 - (len(bits) % 8))] + bits - bits = ['0' for x in xrange(len(s) * 8 - len(bits))] + bits + bits = [0 for x in range(8 - (len(bits) % 8))] + bits self.bits = bits self.offset = 0 @@ -46,7 +50,7 @@ class bitobj: if n > len(self.bits) - self.offset: raise ValueError('not enough bits %r %r' % (n, len(self.bits))) b = self.bits[self.offset:self.offset + n] - b = int("".join([str(x) for x in b]), 2) + b = int("".join(str(x) for x in b), 2) self.offset += n return b @@ -55,17 +59,18 @@ class bitobj: return bits = list(bin(b)[2:]) bits = [int(x) for x in bits] - bits = [0 for x in xrange(n - len(bits))] + bits + bits = [0 for x in range(n - len(bits))] + bits self.bits += bits def tostring(self): if len(self.bits) % 8: raise ValueError( - 'num bits must be 8 bit aligned: %d' % len(self.bits)) - b = int("".join([str(x) for x in self.bits]), 2) + 'num bits must be 8 bit aligned: %d' % len(self.bits) + ) + b = int("".join(str(x) for x in self.bits), 2) b = "%X" % b - b = '0' * (len(self.bits) / 4 - len(b)) + b - b = b.decode('hex') + b = '0' * (len(self.bits) // 4 - len(b)) + b + b = decode_hex(b.encode()) return b def reset(self): @@ -113,10 +118,10 @@ class reg_info(object): class reg_info_dct(object): def __init__(self, reg_expr): - self.dct_str_inv = dict((v.name, k) for k, v in reg_expr.iteritems()) + self.dct_str_inv = dict((v.name, k) for k, v in viewitems(reg_expr)) self.dct_expr = reg_expr - self.dct_expr_inv = dict((v, k) for k, v in reg_expr.iteritems()) - reg_str = [v.name for v in reg_expr.itervalues()] + self.dct_expr_inv = dict((v, k) for k, v in viewitems(reg_expr)) + reg_str = [v.name for v in viewvalues(reg_expr)] self.parser = literal_list(reg_str).setParseAction(self.cb_parse) def cb_parse(self, tokens): @@ -412,11 +417,11 @@ def int2bin(i, l): def myror32(v, r): - return ((v & 0xFFFFFFFFL) >> r) | ((v << (32 - r)) & 0xFFFFFFFFL) + return ((v & 0xFFFFFFFF) >> r) | ((v << (32 - r)) & 0xFFFFFFFF) def myrol32(v, r): - return ((v & 0xFFFFFFFFL) >> (32 - r)) | ((v << r) & 0xFFFFFFFFL) + return ((v & 0xFFFFFFFF) >> (32 - r)) | ((v << r) & 0xFFFFFFFF) class bs(object): @@ -563,7 +568,7 @@ class bsi(object): def __hash__(self): kargs = [] - for k, v in self.kargs.items(): + for k, v in list(viewitems(self.kargs)): if isinstance(v, list): v = tuple(v) kargs.append((k, v)) @@ -595,7 +600,7 @@ class bs_name(bs_divert): def divert(self, i, candidates): out = [] for cls, _, bases, dct, fields in candidates: - for new_name, value in self.args['name'].iteritems(): + for new_name, value in viewitems(self.args['name']): nfields = fields[:] s = int2bin(value, self.args['l']) args = dict(self.args) @@ -620,7 +625,7 @@ class bs_mod_name(bs_divert): for j, v in enumerate(tab): tmp[j] = v tab = tmp - for value, new_name in tab.iteritems(): + for value, new_name in viewitems(tab): nfields = fields[:] s = int2bin(value, self.args['l']) args = dict(self.args) @@ -676,7 +681,7 @@ class m_arg(object): self.expr = e return start, stop try: - v, start, stop = self.parser.scanString(text).next() + v, start, stop = next(self.parser.scanString(text)) except StopIteration: return None, None arg = v[0] @@ -713,7 +718,7 @@ class reg_noarg(object): self.expr = e return start, stop try: - v, start, stop = self.parser.scanString(text).next() + v, start, stop = next(self.parser.scanString(text)) except StopIteration: return None, None arg = v[0] @@ -743,7 +748,7 @@ class reg_noarg(object): return v & self.fmask == self.fbits -class mn_prefix: +class mn_prefix(object): pass @@ -756,7 +761,7 @@ def swap32(v): def perm_inv(p): - o = [None for x in xrange(len(p))] + o = [None for x in range(len(p))] for i, x in enumerate(p): o[x] = i return o @@ -775,10 +780,10 @@ total_scans = 0 def branch2nodes(branch, nodes=None): if nodes is None: nodes = [] - for k, v in branch.items(): + for k, v in viewitems(branch): if not isinstance(v, dict): continue - for k2 in v.keys(): + for k2 in v: nodes.append((k, k2)) branch2nodes(v, nodes) @@ -789,7 +794,7 @@ def factor_one_bit(tree): new_keys = defaultdict(lambda: defaultdict(dict)) if len(tree) == 1: return tree - for k, v in tree.items(): + for k, v in viewitems(tree): if k == "mn": new_keys[k] = v continue @@ -806,15 +811,15 @@ def factor_one_bit(tree): if nk in new_keys[ck]: raise NotImplementedError('not fully functional') new_keys[ck][nk] = v - for k, v in new_keys.items(): + for k, v in list(viewitems(new_keys)): new_keys[k] = factor_one_bit(v) # try factor sons if len(new_keys) != 1: return new_keys - subtree = new_keys.values()[0] + subtree = next(iter(viewvalues(new_keys))) if len(subtree) != 1: return new_keys - if subtree.keys()[0] == 'mn': + if next(iter(subtree)) == 'mn': return new_keys return new_keys @@ -826,7 +831,7 @@ def factor_fields(tree): if len(tree) != 1: return tree # merge - k1, v1 = tree.items()[0] + k1, v1 = next(iter(viewitems(tree))) if k1 == "mn": return tree l1, fmask1, fbits1, fname1, flen1 = k1 @@ -839,7 +844,7 @@ def factor_fields(tree): return tree if len(v1) != 1: return tree - k2, v2 = v1.items()[0] + k2, v2 = next(iter(viewitems(v1))) if k2 == "mn": return tree l2, fmask2, fbits2, fname2, flen2 = k2 @@ -861,7 +866,7 @@ def factor_fields_all(tree): if not isinstance(tree, dict): return tree new_keys = {} - for k, v in tree.items(): + for k, v in viewitems(tree): v = factor_fields(v) new_keys[k] = factor_fields_all(v) return new_keys @@ -902,7 +907,7 @@ def add_candidate(bases, c): def getfieldby_name(fields, fname): - f = filter(lambda x: hasattr(x, 'fname') and x.fname == fname, fields) + f = [x for x in fields if hasattr(x, 'fname') and x.fname == fname] if len(f) != 1: raise ValueError('more than one field with name: %s' % fname) return f[0] @@ -1023,10 +1028,10 @@ class instruction(object): loc_key = exprloc.loc_key names = symbols.get_location_names(loc_key) # special symbols - if '$' in names: + if b'$' in names: fixed_expr[exprloc] = self.get_asm_offset(exprloc) continue - if '_' in names: + if b'_' in names: fixed_expr[exprloc] = self.get_asm_next_offset(exprloc) continue arg_int = symbols.get_location_offset(loc_key) @@ -1059,8 +1064,7 @@ class instruction(object): return -class cls_mn(object): - __metaclass__ = metamn +class cls_mn(with_metaclass(metamn, object)): args_symb = [] instruction = instruction # Block's offset alignment @@ -1073,8 +1077,10 @@ class cls_mn(object): candidates = set() fname_values = pre_dis_info - todo = [(dict(fname_values), branch, offset * 8) - for branch in cls.bintree.items()] + todo = [ + (dict(fname_values), branch, offset * 8) + for branch in list(viewitems(cls.bintree)) + ] for fname_values, branch, offset_b in todo: (l, fmask, fbits, fname, flen), vals = branch @@ -1091,7 +1097,7 @@ class cls_mn(object): continue if fname is not None and not fname in fname_values: fname_values[fname] = v - for nb, v in vals.items(): + for nb, v in viewitems(vals): if 'mn' in nb: candidates.update(v) else: @@ -1128,7 +1134,7 @@ class cls_mn(object): setattr(self, f.fname, f) if hasattr(self, 'args_permut'): args = [args[self.args_permut[i]] - for i in xrange(len(self.args_permut))] + for i in range(len(self.args_permut))] to_decode.sort(key=lambda x: (x[1].order, x[0])) to_decode = [fields_order.index(f[1]) for f in to_decode] self.args = args @@ -1236,7 +1242,7 @@ class cls_mn(object): if not getok: continue - c.l = prefix_len + total_l / 8 + c.l = prefix_len + total_l // 8 for i in c.to_decode: f = c.fields_order[i] if f.is_present: @@ -1258,7 +1264,7 @@ class cls_mn(object): c_args = [a.expr for a in c.args] instr = cls.instruction(c.name, mode, c_args, additional_info=c.additional_info()) - instr.l = prefix_len + total_l / 8 + instr.l = prefix_len + total_l // 8 instr.b = cls.getbytes(bs, offset_o, instr.l) instr.offset = offset_o instr.get_info(c) @@ -1278,8 +1284,10 @@ class cls_mn(object): for i, o in enumerate(out_c): if o.alias: return out[i] - raise NotImplementedError('Multiple disas: \n' + - "\n".join([str(x) for x in out])) + raise NotImplementedError( + 'Multiple disas: \n' + + "\n".join(str(x) for x in out) + ) return out[0] @classmethod @@ -1317,7 +1325,7 @@ class cls_mn(object): continue try: total_scans += 1 - v, start, stop = p.scanString(args_str).next() + v, start, stop = next(p.scanString(args_str)) except StopIteration: v, start, stop = [None], None, None if start != 0: @@ -1396,7 +1404,7 @@ class cls_mn(object): continue # only fix args expr - for i in xrange(len(c.args)): + for i in range(len(c.args)): c.args[i].expr = args[i] v = c.value(instr.mode) @@ -1408,8 +1416,10 @@ class cls_mn(object): vals += v candidates.append((c, v)) if len(vals) == 0: - raise ValueError('cannot asm %r %r' % - (instr.name, [str(x) for x in instr.args])) + raise ValueError( + 'cannot asm %r %r' % + (instr.name, [str(x) for x in instr.args]) + ) if len(vals) != 1: log.debug('asm multiple args ret default') @@ -1571,7 +1581,7 @@ class imm_noarg(object): e, start, stop = parser_result[self.parser] else: try: - e, start, stop = self.parser.scanString(text).next() + e, start, stop = next(self.parser.scanString(text)) except StopIteration: return None, None if e == [None]: diff --git a/miasm2/core/ctypesmngr.py b/miasm2/core/ctypesmngr.py index 7dafd7e1..94c96f7e 100644 --- a/miasm2/core/ctypesmngr.py +++ b/miasm2/core/ctypesmngr.py @@ -522,15 +522,15 @@ class CAstTypes(object): if isinstance(ast, c_ast.BinaryOp): left = self.ast_eval_int(ast.left) right = self.ast_eval_int(ast.right) - is_pure_int = (isinstance(left, (int, long)) and - isinstance(right, (int, long))) + is_pure_int = (isinstance(left, int) and + isinstance(right, int)) if is_pure_int: if ast.op == '*': result = left * right elif ast.op == '/': assert left % right == 0 - result = left / right + result = left // right elif ast.op == '+': result = left + right elif ast.op == '-': diff --git a/miasm2/core/graph.py b/miasm2/core/graph.py index e385b044..f585379b 100644 --- a/miasm2/core/graph.py +++ b/miasm2/core/graph.py @@ -1,4 +1,6 @@ from collections import defaultdict, namedtuple + +from future.utils import viewitems, viewvalues import re @@ -54,8 +56,9 @@ class DiGraph(object): def __eq__(self, graph): if not isinstance(graph, self.__class__): return False - return all((self._nodes == graph.nodes(), - sorted(self._edges) == sorted(graph.edges()))) + if self._nodes != graph.nodes(): + return False + return sorted(self._edges) == sorted(graph.edges()) def __ne__(self, other): return not self.__eq__(other) @@ -110,7 +113,7 @@ class DiGraph(object): def predecessors_iter(self, node): if not node in self._nodes_pred: - raise StopIteration + return for n_pred in self._nodes_pred[node]: yield n_pred @@ -119,7 +122,7 @@ class DiGraph(object): def successors_iter(self, node): if not node in self._nodes_succ: - raise StopIteration + return for n_suc in self._nodes_succ[node]: yield n_suc @@ -165,7 +168,7 @@ class DiGraph(object): if path and path[0] == src: out.append(path + [dst]) return out - + def find_path_from_src(self, src, dst, cycles_count=0, done=None): """ This function does the same as function find_path. @@ -177,7 +180,7 @@ class DiGraph(object): @done: dictionary of already processed loc_keys, it's value is number of times it was processed @out: list of paths from @src to @dst """ - + if done is None: done = {} if src == dst: @@ -229,10 +232,12 @@ class DiGraph(object): @staticmethod def _attr2str(default_attr, attr): - return ' '.join('%s="%s"' % (name, value) - for name, value in - dict(default_attr, - **attr).iteritems()) + return ' '.join( + '%s="%s"' % (name, value) + for name, value in + viewitems(dict(default_attr, + **attr)) + ) def dot(self): """Render dot graph with HTML""" @@ -277,8 +282,10 @@ class DiGraph(object): for src, dst in self.edges(): attrs = self.edge_attr(src, dst) - attrs = ' '.join('%s="%s"' % (name, value) - for name, value in attrs.iteritems()) + attrs = ' '.join( + '%s="%s"' % (name, value) + for name, value in viewitems(attrs) + ) out.append('%s -> %s' % (self.nodeid(src), self.nodeid(dst)) + '[' + attrs + '];') @@ -304,7 +311,7 @@ class DiGraph(object): def predecessors_stop_node_iter(self, node, head): if node == head: - raise StopIteration + return for next_node in self.predecessors_iter(node): yield next_node @@ -515,7 +522,7 @@ class DiGraph(object): frontier = {} for node in idoms: - if self._nodes_pred[node] >= 2: + if len(self._nodes_pred[node]) >= 2: for predecessor in self.predecessors_iter(node): runner = predecessor if runner not in idoms: @@ -894,7 +901,7 @@ class MatchGraph(DiGraph): standing for a partial solution """ # Avoid having 2 different joker for the same node - if partial_sol and candidate in partial_sol.values(): + if partial_sol and candidate in viewvalues(partial_sol): return False # Check lambda filtering @@ -1008,5 +1015,3 @@ class MatchGraph(DiGraph): MatchGraph._propagate_successors) self._propagate_sol(node, partial_sol, graph, todo, MatchGraph._propagate_predecessors) - - raise StopIteration diff --git a/miasm2/core/interval.py b/miasm2/core/interval.py index 3fde83ad..06dc546f 100644 --- a/miasm2/core/interval.py +++ b/miasm2/core/interval.py @@ -1,3 +1,5 @@ +from __future__ import print_function + INT_EQ = 0 # Equivalent INT_B_IN_A = 1 # B in A INT_A_IN_B = -1 # A in B @@ -232,16 +234,16 @@ class interval(object): import Image import ImageDraw except ImportError: - print 'cannot import python PIL imaging' + print('cannot import python PIL imaging') return img = Image.new('RGB', (img_x, img_y), (100, 100, 100)) draw = ImageDraw.Draw(img) i_min, i_max = self.hull() - print hex(i_min), hex(i_max) + print(hex(i_min), hex(i_max)) - addr2x = lambda addr: (addr - i_min) * img_x / (i_max - i_min) + addr2x = lambda addr: ((addr - i_min) * img_x) // (i_max - i_min) for a, b in self.intervals: draw.rectangle((addr2x(a), 0, addr2x(b), img_y), (200, 0, 0)) diff --git a/miasm2/core/locationdb.py b/miasm2/core/locationdb.py index 4c5da29e..906a247a 100644 --- a/miasm2/core/locationdb.py +++ b/miasm2/core/locationdb.py @@ -1,11 +1,16 @@ import warnings +from builtins import int as int_types +from functools import reduce +from future.utils import viewitems, viewvalues + +from miasm2.core.utils import printable, force_bytes from miasm2.expression.expression import LocKey, ExprLoc from miasm2.expression.modint import moduint, modint def is_int(a): - return isinstance(a, (int, long, moduint, modint)) + return isinstance(a, (int_types, moduint, modint)) class LocationDB(object): @@ -85,6 +90,7 @@ class LocationDB(object): Return the LocKey of @name if any, None otherwise. @name: target name """ + name = force_bytes(name) return self._name_to_loc_key.get(name) def get_or_create_name_location(self, name): @@ -92,6 +98,7 @@ class LocationDB(object): Return the LocKey of @name if any, create one otherwise. @name: target name """ + name = force_bytes(name) loc_key = self._name_to_loc_key.get(name) if loc_key is not None: return loc_key @@ -100,7 +107,7 @@ class LocationDB(object): def get_offset_location(self, offset): """ Return the LocKey of @offset if any, None otherwise. - @name: target offset + @offset: target offset """ return self._offset_to_loc_key.get(offset) @@ -119,6 +126,7 @@ class LocationDB(object): Return the offset of @name if any, None otherwise. @name: target name """ + name = force_bytes(name) loc_key = self.get_name_location(name) if loc_key is None: return None @@ -129,6 +137,7 @@ class LocationDB(object): @name: str instance @loc_key: LocKey instance """ + name = force_bytes(name) assert loc_key in self._loc_keys already_existing_loc = self._name_to_loc_key.get(name) if already_existing_loc is not None and already_existing_loc != loc_key: @@ -144,6 +153,7 @@ class LocationDB(object): @loc_key: LocKey instance """ assert loc_key in self._loc_keys + name = force_bytes(name) already_existing_loc = self._name_to_loc_key.get(name) if already_existing_loc is None: raise KeyError("%r is not already associated" % name) @@ -195,13 +205,13 @@ class LocationDB(object): """Ensure internal structures are consistent with each others""" assert set(self._loc_key_to_names).issubset(self._loc_keys) assert set(self._loc_key_to_offset).issubset(self._loc_keys) - assert self._loc_key_to_offset == {v: k for k, v in self._offset_to_loc_key.iteritems()} + assert self._loc_key_to_offset == {v: k for k, v in viewitems(self._offset_to_loc_key)} assert reduce( lambda x, y:x.union(y), - self._loc_key_to_names.itervalues(), + viewvalues(self._loc_key_to_names), set(), ) == set(self._name_to_loc_key) - for name, loc_key in self._name_to_loc_key.iteritems(): + for name, loc_key in viewitems(self._name_to_loc_key): assert name in self._loc_key_to_names[loc_key] def find_free_name(self, name): @@ -211,6 +221,7 @@ class LocationDB(object): @name: string """ + name = force_bytes(name) if self.get_name_location(name) is None: return name i = 0 @@ -233,6 +244,7 @@ class LocationDB(object): LocKey may be updated and will be returned. """ + name = force_bytes(name) # Deprecation handling if is_int(name): assert offset is None or offset == name @@ -321,6 +333,14 @@ class LocationDB(object): """Return a human readable version of @loc_key, according to information available in this LocationDB instance""" names = self.get_location_names(loc_key) + new_names = set() + for name in names: + try: + name = name.decode() + except AttributeError: + pass + new_names.add(name) + names = new_names if names: return ",".join(names) offset = self.get_location_offset(loc_key) @@ -336,23 +356,25 @@ class LocationDB(object): @property def names(self): """Return all known names""" - return self._name_to_loc_key.keys() + return list(self._name_to_loc_key) @property def offsets(self): """Return all known offsets""" - return self._offset_to_loc_key.keys() + return list(self._offset_to_loc_key) def __str__(self): out = [] for loc_key in self._loc_keys: names = self.get_location_names(loc_key) offset = self.get_location_offset(loc_key) - out.append("%s: %s - %s" % ( - loc_key, - "0x%x" % offset if offset is not None else None, - ",".join(names) - )) + out.append( + "%s: %s - %s" % ( + loc_key, + "0x%x" % offset if offset is not None else None, + ",".join(printable(name) for name in names) + ) + ) return "\n".join(out) def merge(self, location_db): diff --git a/miasm2/core/objc.py b/miasm2/core/objc.py index 14352c7b..30b00682 100644 --- a/miasm2/core/objc.py +++ b/miasm2/core/objc.py @@ -5,10 +5,14 @@ C helper for Miasm: * Miasm expression to C type """ +from builtins import zip +from builtins import int as int_types import warnings from pycparser import c_parser, c_ast +from functools import total_ordering +from miasm2.core.utils import cmp_elts from miasm2.expression.expression_reduce import ExprReducer from miasm2.expression.expression import ExprInt, ExprId, ExprOp, ExprMem @@ -65,6 +69,7 @@ def objc_to_str(objc, result=None): return result +@total_ordering class ObjC(object): """Generic ObjC""" @@ -87,10 +92,13 @@ class ObjC(object): assert other.__class__ in OBJC_PRIO if OBJC_PRIO[self.__class__] != OBJC_PRIO[other.__class__]: - return cmp(OBJC_PRIO[self.__class__], OBJC_PRIO[other.__class__]) + return cmp_elts( + OBJC_PRIO[self.__class__], + OBJC_PRIO[other.__class__] + ) if self.align != other.align: - return cmp(self.align, other.align) - return cmp(self.size, other.size) + return cmp_elts(self.align, other.align) + return cmp_elts(self.size, other.size) def __hash__(self): return hash((self.__class__, self._align, self._size)) @@ -98,7 +106,18 @@ class ObjC(object): def __str__(self): return objc_to_str(self) + def __eq__(self, other): + return self.cmp_base(other) == 0 + + def __ne__(self, other): + # required Python 2.7.14 + return not self == other + + def __lt__(self, other): + return self.cmp_base(other) < 0 + +@total_ordering class ObjCDecl(ObjC): """C Declaration identified""" @@ -117,11 +136,19 @@ class ObjCDecl(ObjC): def __str__(self): return str(self.name) - def __cmp__(self, other): + def __eq__(self, other): + ret = self.cmp_base(other) + if ret: + return False + return self.name == other.name + + def __lt__(self, other): ret = self.cmp_base(other) if ret: - return ret - return cmp(self.name, other.name) + if ret < 0: + return True + return False + return self.name < other.name class ObjCInt(ObjC): @@ -133,10 +160,8 @@ class ObjCInt(ObjC): def __str__(self): return 'int' - def __cmp__(self, other): - return self.cmp_base(other) - +@total_ordering class ObjCPtr(ObjC): """C Pointer""" @@ -172,16 +197,27 @@ class ObjCPtr(ObjC): return hash((super(ObjCPtr, self).__hash__(), hash(self._objtype))) def __repr__(self): - return '<%s %r>' % (self.__class__.__name__, - self.objtype.__class__) + return '<%s %r>' % ( + self.__class__.__name__, + self.objtype.__class__ + ) + + def __eq__(self, other): + ret = self.cmp_base(other) + if ret: + return False + return self.objtype == other.objtype - def __cmp__(self, other): + def __lt__(self, other): ret = self.cmp_base(other) if ret: - return ret - return cmp(self.objtype, other.objtype) + if ret < 0: + return True + return False + return self.objtype < other.objtype +@total_ordering class ObjCArray(ObjC): """C array (test[XX])""" @@ -205,16 +241,23 @@ class ObjCArray(ObjC): def __repr__(self): return '<%r[%d]>' % (self.objtype, self.elems) - def __cmp__(self, other): + def __eq__(self, other): ret = self.cmp_base(other) if ret: - return ret - ret = cmp(self.elems, other.elems) - if ret: - return ret - return cmp(self.objtype, other.objtype) + return False + if self.objtype != other.objtype: + return False + return self.elems == other.elems + def __lt__(self, other): + ret = self.cmp_base(other) + if ret > 0: + return False + if self.objtype > other.objtype: + return False + return self.elems < other.elems +@total_ordering class ObjCStruct(ObjC): """C object for structures""" @@ -241,12 +284,22 @@ class ObjCStruct(ObjC): def __str__(self): return 'struct %s' % (self.name) - def __cmp__(self, other): + def __eq__(self, other): ret = self.cmp_base(other) if ret: - return ret - return cmp(self.name, other.name) + return False + return self.name == other.name + + def __lt__(self, other): + ret = self.cmp_base(other) + if ret: + if ret < 0: + return True + return False + return self.name < other.name + +@total_ordering class ObjCUnion(ObjC): """C object for unions""" @@ -273,11 +326,19 @@ class ObjCUnion(ObjC): def __str__(self): return 'union %s' % (self.name) - def __cmp__(self, other): + def __eq__(self, other): + ret = self.cmp_base(other) + if ret: + return False + return self.name == other.name + + def __lt__(self, other): ret = self.cmp_base(other) if ret: - return ret - return cmp(self.name, other.name) + if ret < 0: + return True + return False + return self.name < other.name class ObjCEllipsis(ObjC): """C integer""" @@ -288,10 +349,7 @@ class ObjCEllipsis(ObjC): align = property(lambda self: self._align) size = property(lambda self: self._size) - def __cmp__(self, other): - return self.cmp_base(other) - - +@total_ordering class ObjCFunc(ObjC): """C object for Functions""" @@ -311,8 +369,10 @@ class ObjCFunc(ObjC): return hash((super(ObjCFunc, self).__hash__(), hash(self._args), self._name)) def __repr__(self): - return "<%s %s>" % (self.__class__.__name__, - self.name) + return "<%s %s>" % ( + self.__class__.__name__, + self.name + ) def __str__(self): out = [] @@ -323,11 +383,19 @@ class ObjCFunc(ObjC): out.append(" %s %s" % (name, arg)) return '\n'.join(out) - def __cmp__(self, other): + def __eq__(self, other): + ret = self.cmp_base(other) + if ret: + return False + return self.name == other.name + + def __lt__(self, other): ret = self.cmp_base(other) if ret: - return ret - return cmp(self.name, other.name) + if ret < 0: + return True + return False + return self.name < other.name OBJC_PRIO = { ObjC: 0, @@ -448,7 +516,7 @@ class CGenInt(CGen): """Int C object""" def __init__(self, integer): - assert isinstance(integer, (int, long)) + assert isinstance(integer, int_types) self._integer = integer super(CGenInt, self).__init__(ObjCInt()) @@ -898,7 +966,7 @@ class ExprToAccessC(ExprReducer): if base_type.objtype.size == 0: missing_definition(base_type.objtype) return set() - element_num = offset / (base_type.objtype.size) + element_num = offset // (base_type.objtype.size) field_offset = offset % base_type.objtype.size if element_num >= base_type.elems: return set() @@ -919,7 +987,7 @@ class ExprToAccessC(ExprReducer): elif isinstance(base_type, ObjCDecl): if self.enforce_strict_access and offset % base_type.size != 0: return set() - elem_num = offset / base_type.size + elem_num = offset // base_type.size nobj = CGenArray(cgenobj, elem_num, void_type.align, void_type.size) @@ -942,7 +1010,7 @@ class ExprToAccessC(ExprReducer): new_type = out elif isinstance(base_type, ObjCPtr): - elem_num = offset / base_type.size + elem_num = offset // base_type.size if self.enforce_strict_access and offset % base_type.size != 0: return set() nobj = CGenArray(cgenobj, elem_num, @@ -1025,7 +1093,7 @@ class ExprToAccessC(ExprReducer): target = nobj.ctype.objtype for finalcgenobj in self.cgen_access(nobj, target, 0, True, lvl): assert isinstance(finalcgenobj.ctype, ObjCPtr) - if self.enforce_strict_access and finalcgenobj.ctype.objtype.size != node.expr.size / 8: + if self.enforce_strict_access and finalcgenobj.ctype.objtype.size != node.expr.size // 8: continue found.add(CGenDeref(finalcgenobj)) @@ -1035,16 +1103,16 @@ class ExprToAccessC(ExprReducer): if isinstance(target, (ObjCStruct, ObjCUnion)): for finalcgenobj in self.cgen_access(subcgenobj, target, 0, True, lvl): target = finalcgenobj.ctype.objtype - if self.enforce_strict_access and target.size != node.expr.size / 8: + if self.enforce_strict_access and target.size != node.expr.size // 8: continue found.add(CGenDeref(finalcgenobj)) elif isinstance(target, ObjCArray): - if self.enforce_strict_access and subcgenobj.ctype.size != node.expr.size / 8: + if self.enforce_strict_access and subcgenobj.ctype.size != node.expr.size // 8: continue found.update(self.cgen_access(CGenDeref(subcgenobj), target, 0, False, lvl)) else: - if self.enforce_strict_access and target.size != node.expr.size / 8: + if self.enforce_strict_access and target.size != node.expr.size // 8: continue found.add(CGenDeref(subcgenobj)) if not found: @@ -1504,14 +1572,14 @@ class CTypesManager(object): elif size.operator == "*": return arg0 * arg1 elif size.operator == "/": - return arg0 / arg1 + return arg0 // arg1 elif size.operator == "<<": return arg0 << arg1 elif size.operator == ">>": return arg0 >> arg1 else: raise ValueError("Unknown operator %s" % size.operator) - elif isinstance(size, (int, long)): + elif isinstance(size, int_types): return size elif isinstance(size, CTypeSizeof): obj = self._get_objc(size.target) diff --git a/miasm2/core/parse_asm.py b/miasm2/core/parse_asm.py index 7ddf838c..e9982503 100644 --- a/miasm2/core/parse_asm.py +++ b/miasm2/core/parse_asm.py @@ -1,5 +1,7 @@ #-*- coding:utf-8 -*- import re +import codecs +from builtins import range from miasm2.expression.expression import ExprId, ExprInt, ExprOp, LocKey import miasm2.core.asmblock as asmblock @@ -63,7 +65,7 @@ def guess_next_new_label(loc_db): """Generate a new label @loc_db: the LocationDB instance""" i = 0 - gen_name = "loc_%.8X" + gen_name = b"loc_%.8X" while True: name = gen_name % i label = loc_db.get_name_location(name) @@ -78,7 +80,7 @@ STATE_IN_BLOC = 1 def asm_ast_to_expr_with_size(arg, loc_db, size): if isinstance(arg, AstId): - return ExprId(arg.name, size) + return ExprId(arg.name.encode(), size) if isinstance(arg, AstOp): args = [asm_ast_to_expr_with_size(tmp, loc_db, size) for tmp in arg.args] return ExprOp(arg.op, *args) @@ -119,7 +121,7 @@ def parse_txt(mnemo, attrib, txt, loc_db=None): # label beginning with .L match_re = LABEL_RE.match(line) if match_re: - label_name = match_re.group(1) + label_name = match_re.group(1).encode() label = loc_db.get_or_create_name_location(label_name) lines.append(label) continue @@ -133,18 +135,20 @@ def parse_txt(mnemo, attrib, txt, loc_db=None): # XXX HACK line = line.replace(r'\n', '\n').replace(r'\r', '\r') raw = line[line.find(r'"') + 1:line.rfind(r'"')] - raw = raw.decode('string_escape') + raw = codecs.escape_decode(raw)[0] if directive == 'string': - raw += "\x00" + raw += b"\x00" lines.append(asmblock.AsmRaw(raw)) continue if directive == 'ustring': # XXX HACK line = line.replace(r'\n', '\n').replace(r'\r', '\r') raw = line[line.find(r'"') + 1:line.rfind(r'"')] + "\x00" - raw = raw.decode('string_escape') - raw = "".join([string + '\x00' for string in raw]) - lines.append(asmblock.AsmRaw(raw)) + raw = codecs.escape_decode(raw)[0] + out = b'' + for i in range(len(raw)): + out += raw[i:i+1] + b'\x00' + lines.append(asmblock.AsmRaw(out)) continue if directive in declarator: data_raw = line[match_re.end():].split(' ', 1)[1] @@ -183,12 +187,12 @@ def parse_txt(mnemo, attrib, txt, loc_db=None): if directive[0:4] == 'cfi_': continue - raise ValueError("unknown directive %s" % str(directive)) + raise ValueError("unknown directive %s" % directive) # label match_re = LABEL_RE.match(line) if match_re: - label_name = match_re.group(1) + label_name = match_re.group(1).encode() label = loc_db.get_or_create_name_location(label_name) lines.append(label) continue diff --git a/miasm2/core/sembuilder.py b/miasm2/core/sembuilder.py index 5694ffa3..8ea4c4ac 100644 --- a/miasm2/core/sembuilder.py +++ b/miasm2/core/sembuilder.py @@ -4,6 +4,8 @@ import inspect import ast import re +from future.utils import PY3 + import miasm2.expression.expression as m2_expr from miasm2.ir.ir import IRBlock, AssignBlock @@ -30,7 +32,6 @@ class MiasmTransformer(ast.NodeTransformer): # Recursive visit node = self.generic_visit(node) - if isinstance(node.func, ast.Name): # iX(Y) -> ExprInt(Y, X) fc_name = node.func.id @@ -110,6 +111,17 @@ class MiasmTransformer(ast.NodeTransformer): starargs=None, kwargs=None) +if PY3: + def get_arg_name(name): + return name.arg + def gen_arg(name, ctx): + return ast.arg(arg=name, ctx=ctx) +else: + def get_arg_name(name): + return name.id + def gen_arg(name, ctx): + return ast.Name(id=name, ctx=ctx) + class SemBuilder(object): """Helper for building instruction's semantic side effects method @@ -300,7 +312,7 @@ class SemBuilder(object): # Get the function AST parsed = ast.parse(inspect.getsource(func)) fc_ast = parsed.body[0] - argument_names = [name.id for name in fc_ast.args.args] + argument_names = [get_arg_name(name) for name in fc_ast.args.args] # Init local cache self._local_ctx = {} @@ -309,8 +321,10 @@ class SemBuilder(object): blocks, body = self._parse_body(fc_ast.body, argument_names) # Build the new function - fc_ast.args.args[0:0] = [ast.Name(id='ir', ctx=ast.Param()), - ast.Name(id='instr', ctx=ast.Param())] + fc_ast.args.args[0:0] = [ + gen_arg('ir', ast.Param()), + gen_arg('instr', ast.Param()) + ] cur_instr = blocks[0][0] if len(blocks[-1][0]) == 0: ## Last block can be empty diff --git a/miasm2/core/types.py b/miasm2/core/types.py index 051c4cca..b915c27f 100644 --- a/miasm2/core/types.py +++ b/miasm2/core/types.py @@ -102,9 +102,13 @@ Note that some structures (e.g. MemStr or MemArray) do not have a static size and cannot be allocated automatically. """ +from builtins import range, zip +from builtins import int as int_types import itertools import logging import struct +from future.utils import PY3 +from future.utils import viewitems, with_metaclass log = logging.getLogger(__name__) console_handler = logging.StreamHandler() @@ -155,7 +159,7 @@ def indent(s, size=4): # String generic getter/setter/len-er # TODO: make miasm2.os_dep.common and jitter ones use these ones -def get_str(vm, addr, enc, max_char=None, end='\x00'): +def get_str(vm, addr, enc, max_char=None, end=u'\x00'): """Get a @end (by default '\\x00') terminated @enc encoded string from a VmMngr. @@ -186,7 +190,7 @@ def get_str(vm, addr, enc, max_char=None, end='\x00'): break s.append(c) i += step - return ''.join(s).decode(enc) + return b''.join(s).decode(enc) def raw_str(s, enc, end=u'\x00'): """Returns a string representing @s as an @end (by default \\x00) @@ -225,7 +229,7 @@ def raw_len(py_unic_str, enc, end=u'\x00'): """ return len(raw_str(py_unic_str, enc)) -def enc_triplet(enc, max_char=None, end='\x00'): +def enc_triplet(enc, max_char=None, end=u'\x00'): """Returns a triplet of functions (get_str_enc, set_str_enc, raw_len_enc) for a given encoding (as needed by Str to add an encoding). The prototypes are: @@ -310,8 +314,11 @@ class Type(object): Called by self.lval when it is not in cache. """ pinned_base_class = self._get_pinned_base_class() - pinned_type = type("Mem%r" % self, (pinned_base_class,), - {'_type': self}) + pinned_type = type( + "Mem%r" % self, + (pinned_base_class,), + {'_type': self} + ) return pinned_type def _get_pinned_base_class(self): @@ -344,7 +351,7 @@ class Type(object): raise NotImplementedError("Abstract method") def __ne__(self, other): - return not self.__eq__(other) + return not self == other class RawStruct(Type): @@ -373,7 +380,7 @@ class RawStruct(Type): return self.__class__ == other.__class__ and self._fmt == other._fmt def __ne__(self, other): - return not self.__eq__(other) + return not self == other def __hash__(self): return hash((self.__class__, self._fmt)) @@ -495,7 +502,7 @@ class Ptr(Num): # Actual job dst_addr = self.get_val(vm, addr) - vm.set_mem(dst_addr, str(val)) + vm.set_mem(dst_addr, bytes(val)) def _get_pinned_base_class(self): return MemPtr @@ -510,7 +517,7 @@ class Ptr(Num): self._type_kwargs == other._type_kwargs def __ne__(self, other): - return not self.__eq__(other) + return not self == other def __hash__(self): return hash((super(Ptr, self).__hash__(), self.dst_type, @@ -587,7 +594,7 @@ class Struct(Type): # But the current offset is added 'offset': fd['offset'] + offset, } - for name, fd in field._fields_desc.iteritems() + for name, fd in viewitems(field._fields_desc) } # Add the newly generated fields from the anon field @@ -629,7 +636,7 @@ class Struct(Type): return self._fields def set(self, vm, addr, val): - raw = str(val) + raw = bytes(val) vm.set_mem(addr, raw) def get(self, vm, addr): @@ -683,7 +690,7 @@ class Struct(Type): self.name == other.name def __ne__(self, other): - return not self.__eq__(other) + return not self == other def __hash__(self): # Only hash name, not fields, because if a field is a Ptr to this @@ -771,7 +778,7 @@ class Array(Type): if isinstance(val, MemSizedArray): if val.array_len != self.array_len or len(val) != self.size: raise ValueError("Size mismatch in MemSizedArray assignment") - raw = str(val) + raw = bytes(val) vm.set_mem(addr, raw) # list assignment @@ -810,7 +817,7 @@ class Array(Type): if isinstance(idx, slice): res = [] idx = self._normalize_slice(idx) - for i in xrange(idx.start, idx.stop, idx.step): + for i in range(idx.start, idx.stop, idx.step): res.append(self.field_type.get(vm, addr + self.get_offset(i))) return res else: @@ -823,9 +830,9 @@ class Array(Type): """ if isinstance(idx, slice): idx = self._normalize_slice(idx) - if len(item) != len(xrange(idx.start, idx.stop, idx.step)): + if len(item) != len(range(idx.start, idx.stop, idx.step)): raise ValueError("Mismatched lengths in slice assignment") - for i, val in itertools.izip(xrange(idx.start, idx.stop, idx.step), + for i, val in zip(range(idx.start, idx.stop, idx.step), item): self.field_type.set(vm, addr + self.get_offset(i), val) else: @@ -855,7 +862,7 @@ class Array(Type): return slice(start, stop, step) def _check_bounds(self, idx): - if not isinstance(idx, (int, long)): + if not isinstance(idx, int_types): raise ValueError("index must be an int or a long") if idx < 0 or (self.is_sized() and idx >= self.size): raise IndexError("Index %s out of bounds" % idx) @@ -875,7 +882,7 @@ class Array(Type): self.array_len == other.array_len def __ne__(self, other): - return not self.__eq__(other) + return not self == other def __hash__(self): return hash((self.__class__, self.field_type, self.array_len)) @@ -942,7 +949,7 @@ class Bits(Type): self._bit_offset == other._bit_offset def __ne__(self, other): - return not self.__eq__(other) + return not self == other def __hash__(self): return hash((self.__class__, self._num, self._bits, self._bit_offset)) @@ -1002,7 +1009,7 @@ class BitField(Union): self._num == other._num and super(BitField, self).__eq__(other) def __ne__(self, other): - return not self.__eq__(other) + return not self == other def __hash__(self): return hash((super(BitField, self).__hash__(), self._num)) @@ -1117,7 +1124,7 @@ class Str(Type): return self.__class__ == other.__class__ and self._enc == other._enc def __ne__(self, other): - return not self.__eq__(other) + return not self == other def __hash__(self): return hash((self.__class__, self._enc)) @@ -1136,7 +1143,7 @@ class Void(Type): return self.__class__ == other.__class__ def __ne__(self, other): - return not self.__eq__(other) + return not self == other def __hash__(self): return hash(self.__class__) @@ -1191,7 +1198,7 @@ class _MetaMemStruct(_MetaMemType): cls.gen_fields() -class MemType(object): +class MemType(with_metaclass(_MetaMemType, object)): """Base class for classes that allow to map python objects to C types in virtual memory. Represents an lvalue of a given type. @@ -1200,7 +1207,6 @@ class MemType(object): The main exception is MemStruct, which you may want to subclass yourself for syntactic ease. """ - __metaclass__ = _MetaMemType # allocator is a function(vm, size) -> allocated_address allocator = None @@ -1278,12 +1284,12 @@ class MemType(object): """ return self.sizeof() - def memset(self, byte='\x00'): + def memset(self, byte=b'\x00'): """Fill the memory space of this MemType with @byte ('\x00' by default). The size is retrieved with self.get_size() (dynamic size). """ # TODO: multibyte patterns - if not isinstance(byte, str) or not len(byte) == 1: + if not isinstance(byte, bytes) or len(byte) != 1: raise ValueError("byte must be a 1-lengthed str") self._vm.set_mem(self.get_addr(), byte * self.get_size()) @@ -1319,6 +1325,11 @@ class MemType(object): return self.get_size() def __str__(self): + if PY3: + return repr(self) + return self.__bytes__() + + def __bytes__(self): return self.raw() def __repr__(self): @@ -1327,7 +1338,7 @@ class MemType(object): def __eq__(self, other): return self.__class__ == other.__class__ and \ self.get_type() == other.get_type() and \ - str(self) == str(other) + bytes(self) == bytes(other) def __ne__(self, other): return not self == other @@ -1350,7 +1361,7 @@ class MemValue(MemType): return "%r: %r" % (self.__class__, self.val) -class MemStruct(MemType): +class MemStruct(with_metaclass(_MetaMemStruct, MemType)): """Base class to easily implement VmMngr backed C-like structures in miasm. Represents a structure in virtual memory. @@ -1403,7 +1414,6 @@ class MemStruct(MemType): doc for more information on how to handle recursive types and cyclic dependencies. """ - __metaclass__ = _MetaMemStruct fields = None def get_addr(self, field_name=None): @@ -1667,7 +1677,7 @@ class MemSizedArray(MemArray): return self.get_type().size def __iter__(self): - for i in xrange(self.get_type().array_len): + for i in range(self.get_type().array_len): yield self[i] def raw(self): diff --git a/miasm2/core/utils.py b/miasm2/core/utils.py index c1f48418..9856d4f2 100644 --- a/miasm2/core/utils.py +++ b/miasm2/core/utils.py @@ -1,7 +1,15 @@ +from __future__ import print_function +from builtins import range import struct import inspect -import UserDict +from collections import MutableMapping as DictMixin + from operator import itemgetter +import codecs + +from future.utils import viewitems + +import collections upck8 = lambda x: struct.unpack('B', x)[0] upck16 = lambda x: struct.unpack('H', x)[0] @@ -62,23 +70,57 @@ class Disasm_Exception(Exception): pass +def printable(string): + if isinstance(string, bytes): + return "".join( + c.decode() if b" " <= c < b"~" else "." + for c in (string[i:i+1] for i in range(len(string))) + ) + return string + + +def force_bytes(value): + try: + return value.encode() + except AttributeError: + return value + + +def iterbytes(string): + for i in range(len(string)): + yield string[i:i+1] + + +def int_to_byte(value): + return struct.pack('B', value) + +def cmp_elts(elt1, elt2): + return (elt1 > elt2) - (elt1 < elt2) + + +_DECODE_HEX = codecs.getdecoder("hex_codec") +_ENCODE_HEX = codecs.getencoder("hex_codec") + +def decode_hex(value): + return _DECODE_HEX(value)[0] + +def encode_hex(value): + return _ENCODE_HEX(value)[0] + + def hexdump(src, length=16): - FILTER = ''.join( - [(len(repr(chr(x))) == 3) and chr(x) or '.' for x in range(256)]) lines = [] - for c in xrange(0, len(src), length): + for c in range(0, len(src), length): chars = src[c:c + length] - hexa = ' '.join(["%02x" % ord(x) for x in chars]) + hexa = ' '.join("%02x" % ord(x) for x in iterbytes(chars)) printable = ''.join( - ["%s" % ((ord(x) <= 127 and FILTER[ord(x)]) or '.') for x in chars]) + x.decode() if 32 <= ord(x) <= 126 else '.' for x in iterbytes(chars) + ) lines.append("%04x %-*s %s\n" % (c, length * 3, hexa, printable)) - print ''.join(lines) - -# stackoverflow.com/questions/2912231 - -import collections + print(''.join(lines)) +# stackoverflow.com/questions/2912231 class keydefaultdict(collections.defaultdict): def __missing__(self, key): @@ -88,7 +130,7 @@ class keydefaultdict(collections.defaultdict): return value -class BoundedDict(UserDict.DictMixin): +class BoundedDict(DictMixin): """Limited in size dictionary. @@ -108,7 +150,7 @@ class BoundedDict(UserDict.DictMixin): @delete_cb: (optional) callback called when an element is removed """ self._data = initialdata.copy() if initialdata else {} - self._min_size = min_size if min_size else max_size / 3 + self._min_size = min_size if min_size else max_size // 3 self._max_size = max_size self._size = len(self._data) # Do not use collections.Counter as it is quite slow @@ -122,8 +164,11 @@ class BoundedDict(UserDict.DictMixin): # Bound can only be reached on a new element if (self._size >= self._max_size): - most_common = sorted(self._counter.iteritems(), - key=itemgetter(1), reverse=True) + most_common = sorted( + viewitems(self._counter), + key=itemgetter(1), + reverse=True + ) # Handle callback if self._delete_cb is not None: @@ -154,7 +199,7 @@ class BoundedDict(UserDict.DictMixin): def keys(self): "Return the list of dict's keys" - return self._data.keys() + return list(self._data) @property def data(self): @@ -180,3 +225,10 @@ class BoundedDict(UserDict.DictMixin): if self._delete_cb: for key in self._data: self._delete_cb(key) + + + def __len__(self): + return len(self._data) + + def __iter__(self): + return iter(self._data) diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py index 925190ca..03febbfd 100644 --- a/miasm2/expression/expression.py +++ b/miasm2/expression/expression.py @@ -29,11 +29,19 @@ # +from builtins import zip +from builtins import range import warnings import itertools +from builtins import int as int_types +from functools import cmp_to_key, total_ordering +from future.utils import viewitems + +from miasm2.core.utils import force_bytes, cmp_elts from miasm2.expression.modint import mod_size2uint, is_modint, size2mask, \ define_uint from miasm2.core.graph import DiGraph +from functools import reduce # Define tokens TOK_INF = "<" @@ -145,7 +153,7 @@ class DiGraphExpr(DiGraph): return "" - +@total_ordering class LocKey(object): def __init__(self, key): self._key = key @@ -163,7 +171,11 @@ class LocKey(object): return self.key == other.key def __ne__(self, other): - return not self.__eq__(other) + # required Python 2.7.14 + return not self == other + + def __lt__(self, other): + return self.key < other.key def __repr__(self): return "<%s %d>" % (self.__class__.__name__, self._key) @@ -202,11 +214,11 @@ class Expr(object): @staticmethod def get_object(expr_cls, args): if not expr_cls.use_singleton: - return object.__new__(expr_cls, args) + return object.__new__(expr_cls) expr = Expr.args2expr.get((expr_cls, args)) if expr is None: - expr = object.__new__(expr_cls, args) + expr = object.__new__(expr_cls) Expr.args2expr[(expr_cls, args)] = expr return expr @@ -276,6 +288,9 @@ class Expr(object): def __div__(self, other): return ExprOp('/', self, other) + def __floordiv__(self, other): + return self.__div__(other) + def __mod__(self, other): return ExprOp('%', self, other) @@ -524,7 +539,7 @@ class ExprInt(Expr): return int(self.arg) def __long__(self): - return long(self.arg) + return int(self.arg) def is_int(self, value=None): if value is not None and self._arg != value: @@ -552,7 +567,7 @@ class ExprId(Expr): if size is None: warnings.warn('DEPRECATION WARNING: size is a mandatory argument: use ExprId(name, SIZE)') size = 32 - assert isinstance(name, str) + assert isinstance(name, (str, bytes)) super(ExprId, self).__init__(size) self._name = name @@ -896,7 +911,7 @@ class ExprMem(Expr): # ptr must be Expr assert isinstance(ptr, Expr) - assert isinstance(size, (int, long)) + assert isinstance(size, int_types) if not isinstance(ptr, Expr): raise ValueError( @@ -1169,8 +1184,8 @@ class ExprSlice(Expr): # arg must be Expr assert isinstance(arg, Expr) - assert isinstance(start, (int, long)) - assert isinstance(stop, (int, long)) + assert isinstance(start, int_types) + assert isinstance(stop, int_types) assert start < stop self._arg, self._start, self._stop = arg, start, stop @@ -1344,45 +1359,46 @@ class ExprCompose(Expr): return True # Expression order for comparison -EXPR_ORDER_DICT = {ExprId: 1, - ExprLoc: 2, - ExprCond: 3, - ExprMem: 4, - ExprOp: 5, - ExprSlice: 6, - ExprCompose: 7, - ExprInt: 8, - } +EXPR_ORDER_DICT = { + ExprId: 1, + ExprLoc: 2, + ExprCond: 3, + ExprMem: 4, + ExprOp: 5, + ExprSlice: 6, + ExprCompose: 7, + ExprInt: 8, +} def compare_exprs_compose(expr1, expr2): - # Sort by start bit address, then expr, then stop but address - ret = cmp(expr1[1], expr2[1]) + # Sort by start bit address, then expr, then stop bit address + ret = cmp_elts(expr1[1], expr2[1]) if ret: return ret ret = compare_exprs(expr1[0], expr2[0]) if ret: return ret - ret = cmp(expr1[2], expr2[2]) + ret = cmp_elts(expr1[2], expr2[2]) return ret def compare_expr_list_compose(l1_e, l2_e): # Sort by list elements in incremental order, then by list size - for i in xrange(min(len(l1_e), len(l2_e))): + for i in range(min(len(l1_e), len(l2_e))): ret = compare_exprs(l1_e[i], l2_e[i]) if ret: return ret - return cmp(len(l1_e), len(l2_e)) + return cmp_elts(len(l1_e), len(l2_e)) def compare_expr_list(l1_e, l2_e): # Sort by list elements in incremental order, then by list size - for i in xrange(min(len(l1_e), len(l2_e))): + for i in range(min(len(l1_e), len(l2_e))): ret = compare_exprs(l1_e[i], l2_e[i]) if ret: return ret - return cmp(len(l1_e), len(l2_e)) + return cmp_elts(len(l1_e), len(l2_e)) def compare_exprs(expr1, expr2): @@ -1396,27 +1412,30 @@ def compare_exprs(expr1, expr2): cls1 = expr1.__class__ cls2 = expr2.__class__ if cls1 != cls2: - return cmp(EXPR_ORDER_DICT[cls1], EXPR_ORDER_DICT[cls2]) + return cmp_elts(EXPR_ORDER_DICT[cls1], EXPR_ORDER_DICT[cls2]) if expr1 == expr2: return 0 if cls1 == ExprInt: - ret = cmp(expr1.size, expr2.size) + ret = cmp_elts(expr1.size, expr2.size) if ret != 0: return ret - return cmp(expr1.arg, expr2.arg) + return cmp_elts(expr1.arg, expr2.arg) elif cls1 == ExprId: - ret = cmp(expr1.name, expr2.name) + name1 = force_bytes(expr1.name) + name2 = force_bytes(expr2.name) + ret = cmp_elts(name1, name2) if ret: return ret - return cmp(expr1.size, expr2.size) + return cmp_elts(expr1.size, expr2.size) elif cls1 == ExprLoc: - ret = cmp(expr1.loc_key, expr2.loc_key) + ret = cmp_elts(expr1.loc_key, expr2.loc_key) if ret: return ret - return cmp(expr1.size, expr2.size) + return cmp_elts(expr1.size, expr2.size) elif cls1 == ExprAssign: raise NotImplementedError( - "Comparison from an ExprAssign not yet implemented") + "Comparison from an ExprAssign not yet implemented" + ) elif cls2 == ExprCond: ret = compare_exprs(expr1.cond, expr2.cond) if ret: @@ -1430,36 +1449,33 @@ def compare_exprs(expr1, expr2): ret = compare_exprs(expr1.ptr, expr2.ptr) if ret: return ret - return cmp(expr1.size, expr2.size) + return cmp_elts(expr1.size, expr2.size) elif cls1 == ExprOp: if expr1.op != expr2.op: - return cmp(expr1.op, expr2.op) + return cmp_elts(expr1.op, expr2.op) return compare_expr_list(expr1.args, expr2.args) elif cls1 == ExprSlice: ret = compare_exprs(expr1.arg, expr2.arg) if ret: return ret - ret = cmp(expr1.start, expr2.start) + ret = cmp_elts(expr1.start, expr2.start) if ret: return ret - ret = cmp(expr1.stop, expr2.stop) + ret = cmp_elts(expr1.stop, expr2.stop) return ret elif cls1 == ExprCompose: return compare_expr_list_compose(expr1.args, expr2.args) raise NotImplementedError( - "Comparison between %r %r not implemented" % (expr1, expr2)) + "Comparison between %r %r not implemented" % (expr1, expr2) + ) def canonize_expr_list(expr_list): - expr_list = list(expr_list) - expr_list.sort(cmp=compare_exprs) - return expr_list + return sorted(expr_list, key=cmp_to_key(compare_exprs)) def canonize_expr_list_compose(expr_list): - expr_list = list(expr_list) - expr_list.sort(cmp=compare_exprs_compose) - return expr_list + return sorted(expr_list, key=cmp_to_key(compare_exprs_compose)) # Generate ExprInt with common size @@ -1604,7 +1620,7 @@ def match_expr(expr, pattern, tks, result=None): break if good is True: # We found a possibility - for joker, value in myresult.items(): + for joker, value in viewitems(myresult): # Updating result in place (to keep pointer in recursion) result[joker] = value return result diff --git a/miasm2/expression/expression_helper.py b/miasm2/expression/expression_helper.py index 8065df9b..a50e0d5b 100644 --- a/miasm2/expression/expression_helper.py +++ b/miasm2/expression/expression_helper.py @@ -17,17 +17,20 @@ # # Expressions manipulation functions +from builtins import range import itertools import collections import random import string import warnings +from future.utils import viewitems, viewvalues + import miasm2.expression.expression as m2_expr def parity(a): - tmp = (a) & 0xFFL + tmp = (a) & 0xFF cpt = 1 while tmp != 0: cpt ^= tmp & 1 @@ -174,13 +177,15 @@ class Variables_Identifier(object): has_change = True while has_change: has_change = False - for var_id, var_value in self._vars.iteritems(): + for var_id, var_value in list(viewitems(self._vars)): cur = var_value # Do not replace with itself - to_replace = {v_val:v_id - for v_id, v_val in self._vars.iteritems() - if v_id != var_id} + to_replace = { + v_val:v_id + for v_id, v_val in viewitems(self._vars) + if v_id != var_id + } var_value = var_value.replace_expr(to_replace) if cur != var_value: @@ -190,23 +195,29 @@ class Variables_Identifier(object): break # Replace in the original equation - self._equation = expr.replace_expr({v_val: v_id for v_id, v_val - in self._vars.iteritems()}) + self._equation = expr.replace_expr( + { + v_val: v_id for v_id, v_val + in viewitems(self._vars) + } + ) # Compute variables dependencies self._vars_ordered = collections.OrderedDict() - todo = set(self._vars.iterkeys()) + todo = set(self._vars) needs = {} ## Build initial needs - for var_id, var_expr in self._vars.iteritems(): + for var_id, var_expr in viewitems(self._vars): ### Handle corner cases while using Variable Identifier on an ### already computed equation - needs[var_id] = [var_name - for var_name in var_expr.get_r(mem_read=True) - if self.is_var_identifier(var_name) and \ - var_name in todo and \ - var_name != var_id] + needs[var_id] = [ + var_name + for var_name in var_expr.get_r(mem_read=True) + if self.is_var_identifier(var_name) and \ + var_name in todo and \ + var_name != var_id + ] ## Build order list while todo: @@ -244,12 +255,15 @@ class Variables_Identifier(object): if (expr in self.var_asked): # Expr has already been asked - - if (expr not in self._vars.values()): + if expr not in viewvalues(self._vars): # Create var - identifier = m2_expr.ExprId("%s%s" % (self.var_prefix, - self.var_indice.next()), - size = expr.size) + identifier = m2_expr.ExprId( + "%s%s" % ( + self.var_prefix, + next(self.var_indice) + ), + size = expr.size + ) self._vars[identifier] = expr # Recursion stop case @@ -300,7 +314,7 @@ class Variables_Identifier(object): def __str__(self): "Display variables and final equation" out = "" - for var_id, var_expr in self.vars.iteritems(): + for var_id, var_expr in viewitems(self.vars): out += "%s = %s\n" % (var_id, var_expr) out += "Final: %s" % self.equation return out @@ -312,7 +326,7 @@ class ExprRandom(object): # Identifiers length identifier_len = 5 # Identifiers' name charset - identifier_charset = string.letters + identifier_charset = string.ascii_letters # Number max value number_max = 0xFFFFFFFF # Available operations @@ -340,7 +354,7 @@ class ExprRandom(object): @size: (optional) identifier size """ return m2_expr.ExprId("".join([random.choice(cls.identifier_charset) - for _ in xrange(cls.identifier_len)]), + for _ in range(cls.identifier_len)]), size=size) @classmethod @@ -365,15 +379,17 @@ class ExprRandom(object): @size: (optional) Operation size @depth: (optional) Expression depth """ - operand_type = random.choice(cls.operations_by_args_number.keys()) + operand_type = random.choice(list(cls.operations_by_args_number)) if isinstance(operand_type, str) and "+" in operand_type: - number_args = random.randint(int(operand_type[:-1]), - cls.operations_max_args_number) + number_args = random.randint( + int(operand_type[:-1]), + cls.operations_max_args_number + ) else: number_args = operand_type args = [cls._gen(size=size, depth=depth - 1) - for _ in xrange(number_args)] + for _ in range(number_args)] operand = random.choice(cls.operations_by_args_number[operand_type]) return m2_expr.ExprOp(operand, *args) @@ -593,8 +609,10 @@ def possible_values(expr): elif isinstance(expr, m2_expr.ExprCompose): # Generate each possibility for sub-argument, associated with the start # and stop bit - consvals_args = [map(lambda x: x, possible_values(arg)) - for arg in expr.args] + consvals_args = [ + list(possible_values(arg)) + for arg in expr.args + ] for consvals_possibility in itertools.product(*consvals_args): # Merge constraint of each sub-element args_constraint = itertools.chain(*[consval.constraints diff --git a/miasm2/expression/modint.py b/miasm2/expression/modint.py index 51a2620e..22d17b9b 100644 --- a/miasm2/expression/modint.py +++ b/miasm2/expression/modint.py @@ -1,9 +1,13 @@ #-*- coding:utf-8 -*- +from builtins import range +from functools import total_ordering + +@total_ordering class moduint(object): def __init__(self, arg): - self.arg = long(arg) % self.__class__.limit + self.arg = int(arg) % self.__class__.limit assert(self.arg >= 0 and self.arg < self.__class__.limit) def __repr__(self): @@ -20,11 +24,19 @@ class moduint(object): else: return c2 - def __cmp__(self, y): + def __eq__(self, y): if isinstance(y, moduint): - return cmp(self.arg, y.arg) - else: - return cmp(self.arg, y) + return self.arg == y.arg + return self.arg == y + + def __ne__(self, y): + # required Python 2.7.14 + return not self == y + + def __lt__(self, y): + if isinstance(y, moduint): + return self.arg < y.arg + return self.arg < y def __add__(self, y): if isinstance(y, moduint): @@ -49,13 +61,19 @@ class moduint(object): cls = self.__class__ if isinstance(y, moduint): cls = self.maxcast(y) - return ((abs(num) / abs(den)) * result_sign) + return (abs(num) // abs(den)) * result_sign + + def __floordiv__(self, y): + return self.__div__(y) def __int__(self): return int(self.arg) def __long__(self): - return long(self.arg) + return int(self.arg) + + def __index__(self): + return int(self.arg) def __invert__(self): return self.__class__(~self.arg) @@ -72,7 +90,7 @@ class moduint(object): cls = self.__class__ if isinstance(y, moduint): cls = self.maxcast(y) - return cls(self.arg - (y * (self / y))) + return cls(self.arg - y * (self // y)) def __mul__(self, y): if isinstance(y, moduint): @@ -100,9 +118,12 @@ class moduint(object): def __rdiv__(self, y): if isinstance(y, moduint): cls = self.maxcast(y) - return cls(y.arg / self.arg) + return cls(y.arg // self.arg) else: - return self.__class__(y / self.arg) + return self.__class__(y // self.arg) + + def __rfloordiv__(self, y): + return self.__rdiv__(y) def __rlshift__(self, y): if isinstance(y, moduint): @@ -181,11 +202,13 @@ class modint(moduint): if isinstance(arg, moduint): arg = arg.arg a = arg % self.__class__.limit - if a >= self.__class__.limit / 2: + if a >= self.__class__.limit // 2: a -= self.__class__.limit self.arg = a - assert(self.arg >= -self.__class__.limit / - 2 and self.arg < self.__class__.limit) + assert( + self.arg >= -self.__class__.limit // 2 and + self.arg < self.__class__.limit + ) def is_modint(a): @@ -225,7 +248,7 @@ def define_uint(size): def define_common_int(): "Define common int" - common_int = xrange(1, 257) + common_int = range(1, 257) for i in common_int: define_int(i) diff --git a/miasm2/expression/simplifications.py b/miasm2/expression/simplifications.py index 483331a6..331018ae 100644 --- a/miasm2/expression/simplifications.py +++ b/miasm2/expression/simplifications.py @@ -4,6 +4,8 @@ import logging +from future.utils import viewitems + from miasm2.expression import simplifications_common from miasm2.expression import simplifications_cond from miasm2.expression import simplifications_explicit @@ -126,7 +128,7 @@ class ExpressionSimplifier(object): # Clear cache of simplifiied expressions when adding a new pass self.simplified_exprs.clear() - for k, v in passes.items(): + for k, v in viewitems(passes): self.expr_simp_cb[k] = fast_unify(self.expr_simp_cb.get(k, []) + v) def apply_simp(self, expression): diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py index a4b7c61e..ddcfc668 100644 --- a/miasm2/expression/simplifications_common.py +++ b/miasm2/expression/simplifications_common.py @@ -2,6 +2,7 @@ # Common simplifications passes # # ----------------------------- # +from future.utils import viewitems from miasm2.expression.modint import mod_size2int, mod_size2uint from miasm2.expression.expression import ExprInt, ExprSlice, ExprMem, \ @@ -70,14 +71,14 @@ def simp_cst_propagation(e_s, expr): shifter = int2.arg % int2.size out = (int1.arg << shifter) | (int1.arg >> (int2.size - shifter)) elif op_name == '/': - out = int1.arg / int2.arg + out = int1.arg // int2.arg elif op_name == '%': out = int1.arg % int2.arg elif op_name == 'sdiv': assert int2.arg.arg tmp1 = mod_size2int[int1.arg.size](int1.arg) tmp2 = mod_size2int[int2.arg.size](int2.arg) - out = mod_size2uint[int1.arg.size](tmp1 / tmp2) + out = mod_size2uint[int1.arg.size](tmp1 // tmp2) elif op_name == 'smod': assert int2.arg.arg tmp1 = mod_size2int[int1.arg.size](int1.arg) @@ -92,7 +93,7 @@ def simp_cst_propagation(e_s, expr): assert int2.arg.arg tmp1 = mod_size2uint[int1.arg.size](int1.arg) tmp2 = mod_size2uint[int2.arg.size](int2.arg) - out = mod_size2uint[int1.arg.size](tmp1 / tmp2) + out = mod_size2uint[int1.arg.size](tmp1 // tmp2) @@ -151,7 +152,8 @@ def simp_cst_propagation(e_s, expr): if len(args) > 2: raise ValueError( 'sanity check fail on expr -: should have one or 2 args ' + - '%r %s' % (expr, expr)) + '%r %s' % (expr, expr) + ) return ExprOp('+', args[0], -args[1]) # A op 0 => 0 @@ -445,7 +447,7 @@ def simp_cond_factor(e_s, expr): # Rebuild the new expression c_out = not_conds - for cond, vals in conds.items(): + for cond, vals in viewitems(conds): new_src1 = [x.src1 for x in vals] new_src2 = [x.src2 for x in vals] src1 = e_s.expr_simp_wrapper(ExprOp(expr.op, *new_src1)) @@ -583,7 +585,7 @@ def simp_compose(e_s, expr): nxt = args[i + 1] if arg.is_mem() and nxt.is_mem(): gap = e_s(nxt.ptr - arg.ptr) - if gap.is_int() and arg.size % 8 == 0 and int(gap) == arg.size / 8: + if gap.is_int() and arg.size % 8 == 0 and int(gap) == arg.size // 8: args = args[:i] + [ExprMem(arg.ptr, arg.size + nxt.size)] + args[i + 2:] return ExprCompose(*args) @@ -1520,7 +1522,7 @@ def simp_add_multiple(_, expr): modified = True while modified: modified = False - for arg, count in operands.iteritems(): + for arg, count in list(viewitems(operands)): if not arg.is_op('+'): continue components = arg.args @@ -1536,7 +1538,7 @@ def simp_add_multiple(_, expr): modified = True break - for arg, count in operands.iteritems(): + for arg, count in viewitems(operands): if count == 0: continue if count == 1: diff --git a/miasm2/ir/ir.py b/miasm2/ir/ir.py index dc1d203b..82b12dcd 100644 --- a/miasm2/ir/ir.py +++ b/miasm2/ir/ir.py @@ -17,14 +17,17 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # +from builtins import zip import warnings from itertools import chain +from future.utils import viewvalues, viewitems import miasm2.expression.expression as m2_expr from miasm2.expression.expression_helper import get_missing_interval from miasm2.core.asmblock import AsmBlock, AsmConstraint from miasm2.core.graph import DiGraph +from functools import reduce def _expr_loc_to_symb(expr, loc_db): @@ -69,8 +72,8 @@ class AssignBlock(object): self._assigns = {} # ExprAssign.dst -> ExprAssign.src # Concurrent assignments are handled in _set - if hasattr(irs, "iteritems"): - for dst, src in irs.iteritems(): + if hasattr(irs, "items"): + for dst, src in viewitems(irs): self._set(dst, src) else: for expraff in irs: @@ -159,21 +162,21 @@ class AssignBlock(object): return key in self._assigns def iteritems(self): - for dst, src in self._assigns.iteritems(): + for dst, src in viewitems(self._assigns): yield dst, src def items(self): - return [(dst, src) for dst, src in self.iteritems()] + return [(dst, src) for dst, src in viewitems(self._assigns)] def itervalues(self): - for src in self._assigns.itervalues(): + for src in viewvalues(self._assigns): yield src def keys(self): - return self._assigns.keys() + return list(self._assigns) def values(self): - return self._assigns.values() + return list(viewvalues(self._assigns)) def __iter__(self): for dst in self._assigns: @@ -188,10 +191,10 @@ class AssignBlock(object): def __eq__(self, other): if set(self.keys()) != set(other.keys()): return False - return all(other[dst] == src for dst, src in self.iteritems()) + return all(other[dst] == src for dst, src in viewitems(self)) def __ne__(self, other): - return not self.__eq__(other) + return not self == other def __len__(self): return len(self._assigns) @@ -226,7 +229,7 @@ class AssignBlock(object): @cst_read: (optional) cst_read argument of `get_r` """ out = {} - for dst, src in self.iteritems(): + for dst, src in viewitems(self): src_read = src.get_r(mem_read=mem_read, cst_read=cst_read) if isinstance(dst, m2_expr.ExprMem) and mem_read: # Read on destination happens only with ExprMem @@ -241,12 +244,19 @@ class AssignBlock(object): @cst_read: (optional) cst_read argument of `get_r` """ return set( - chain.from_iterable(self.get_rw(mem_read=mem_read, - cst_read=cst_read).itervalues())) + chain.from_iterable( + viewvalues( + self.get_rw( + mem_read=mem_read, + cst_read=cst_read + ) + ) + ) + ) def __str__(self): out = [] - for dst, src in sorted(self._assigns.iteritems()): + for dst, src in sorted(viewitems(self._assigns)): out.append("%s = %s" % (dst, src)) return "\n".join(out) @@ -262,7 +272,7 @@ class AssignBlock(object): @simplifier: ExpressionSimplifier instance """ new_assignblk = {} - for dst, src in self.iteritems(): + for dst, src in viewitems(self): if dst == src: continue new_src = simplifier(src) @@ -272,7 +282,7 @@ class AssignBlock(object): def to_string(self, loc_db=None): out = [] - for dst, src in self.iteritems(): + for dst, src in viewitems(self): new_src = src.visit(lambda expr:_expr_loc_to_symb(expr, loc_db)) new_dst = dst.visit(lambda expr:_expr_loc_to_symb(expr, loc_db)) line = "%s = %s" % (new_dst, new_src) @@ -315,7 +325,7 @@ class IRBlock(object): return True def __ne__(self, other): - return not self.__eq__(other) + return not self == other def get_label(self): warnings.warn('DEPRECATION WARNING: use ".loc_key" instead of ".label"') @@ -352,7 +362,7 @@ class IRBlock(object): final_dst = None final_linenb = None for linenb, assignblk in enumerate(self): - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): if dst.is_id("IRDst"): if final_dst is not None: raise ValueError('Multiple destinations!') @@ -375,7 +385,7 @@ class IRBlock(object): dst_found = False for assignblk in self: new_assignblk = {} - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): if dst.is_id("IRDst"): assert dst_found is False dst_found = True @@ -396,7 +406,7 @@ class IRBlock(object): out = [] out.append(str(self.loc_key)) for assignblk in self: - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): out.append('\t%s = %s' % (dst, src)) out.append("") return "\n".join(out) @@ -418,7 +428,7 @@ class IRBlock(object): assignblks = [] for assignblk in self: new_assignblk = {} - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): new_assignblk[mod_dst(dst)] = mod_src(src) assignblks.append(AssignBlock(new_assignblk, assignblk.instr)) return IRBlock(self.loc_key, assignblks) @@ -509,11 +519,7 @@ class IRCFG(DiGraph): if self.loc_db is None: node_name = str(node) else: - names = self.loc_db.get_location_names(node) - if not names: - node_name = self.loc_db.pretty_str(node) - else: - node_name = "".join("%s:\n" % name for name in names) + node_name = self.loc_db.pretty_str(node) yield self.DotCellDescription( text="%s" % node_name, attr={ @@ -524,9 +530,9 @@ class IRCFG(DiGraph): ) if node not in self._blocks: yield [self.DotCellDescription(text="NOT PRESENT", attr={})] - raise StopIteration + return for i, assignblk in enumerate(self._blocks[node]): - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): new_src = src.visit(lambda expr:_expr_loc_to_symb(expr, self.loc_db)) new_dst = dst.visit(lambda expr:_expr_loc_to_symb(expr, self.loc_db)) @@ -602,14 +608,18 @@ class IRCFG(DiGraph): return self.blocks.get(loc_key, None) def getby_offset(self, offset): + """ + Return the set of loc_keys of irblocks containing @offset + @offset: address + """ out = set() - for irb in self.blocks.values(): + for irb in viewvalues(self.blocks): for assignblk in irb: instr = assignblk.instr if instr is None: continue if instr.offset <= offset < instr.offset + instr.l: - out.add(irb) + out.add(irb.loc_key) return out @@ -619,7 +629,7 @@ class IRCFG(DiGraph): @simplifier: ExpressionSimplifier instance """ modified = False - for loc_key, block in self.blocks.iteritems(): + for loc_key, block in list(viewitems(self.blocks)): assignblks = [] for assignblk in block: new_assignblk = assignblk.simplify(simplifier) @@ -629,12 +639,6 @@ class IRCFG(DiGraph): self.blocks[loc_key] = IRBlock(loc_key, assignblks) return modified - def replace_expr_in_ir(self, block, replaced): - for assignblk in block: - for dst, src in assignblk.items(): - del assignblk[dst] - assignblk[dst.replace_expr(replaced)] = src.replace_expr(replaced) - def get_rw(self, regs_ids=None): """ Calls get_rw(irb) for each bloc @@ -642,7 +646,7 @@ class IRCFG(DiGraph): """ if regs_ids is None: regs_ids = [] - for irblock in self.blocks.values(): + for irblock in viewvalues(self.blocks): irblock.get_rw(regs_ids) def _extract_dst(self, todo, done): @@ -873,7 +877,7 @@ class IntermediateRepresentation(object): def is_pc_written(self, block): """Return the first Assignblk of the @blockin which PC is written @block: IRBlock instance""" - all_pc = self.arch.pc.values() + all_pc = viewvalues(self.arch.pc) for assignblk in block: if assignblk.dst in all_pc: return assignblk diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py index f54ee2a5..b945e85c 100644 --- a/miasm2/ir/symbexec.py +++ b/miasm2/ir/symbexec.py @@ -1,6 +1,10 @@ +from __future__ import print_function +from builtins import range import logging from collections import MutableMapping +from future.utils import viewitems + from miasm2.expression.expression import ExprOp, ExprId, ExprLoc, ExprInt, \ ExprMem, ExprCompose, ExprSlice, ExprCond from miasm2.expression.simplifications import expr_simp_explicit @@ -40,7 +44,7 @@ class SymbolicState(StateEngine): """Stores a SymbolicExecutionEngine state""" def __init__(self, dct): - self._symbols = frozenset(dct.items()) + self._symbols = frozenset(viewitems(dct)) def __hash__(self): return hash((self.__class__, self._symbols)) @@ -53,7 +57,7 @@ class SymbolicState(StateEngine): return self.symbols == other.symbols def __ne__(self, other): - return not self.__eq__(other) + return not self == other def __iter__(self): for dst, src in self._symbols: @@ -71,7 +75,7 @@ class SymbolicState(StateEngine): symb_a = self.symbols symb_b = other.symbols - intersection = set(symb_a.keys()).intersection(symb_b.keys()) + intersection = set(symb_a).intersection(set(symb_b)) out = {} for dst in intersection: if symb_a[dst] == symb_b[dst]: @@ -168,7 +172,7 @@ class MemArray(MutableMapping): return self._offset_to_expr.__delitem__(offset) def __iter__(self): - for offset, _ in self._offset_to_expr.iteritems(): + for offset, _ in viewitems(self._offset_to_expr): yield offset def __len__(self): @@ -177,7 +181,7 @@ class MemArray(MutableMapping): def __repr__(self): out = [] out.append("Base: %s" % self.base) - for offset, (index, value) in sorted(self._offset_to_expr.iteritems()): + for offset, (index, value) in sorted(viewitems(self._offset_to_expr)): out.append("%16X %d %s" % (offset, index, value)) return '\n'.join(out) @@ -220,7 +224,7 @@ class MemArray(MutableMapping): assert size % 8 == 0 # Parts is (Expr's offset, size, Expr) parts = [] - for index in xrange(size / 8): + for index in range(size // 8): # Wrap read: # @32[EAX+0xFFFFFFFF] is ok and will read at 0xFFFFFFFF, 0, 1, 2 request_offset = (offset + index) & self._mask @@ -264,8 +268,8 @@ class MemArray(MutableMapping): index += 1 continue if (ptr_offset_a + off_a + size_a) & self._mask == (ptr_offset_b + off_b) & self._mask: - assert size_a <= data_a.size / 8 - off_a - assert size_b <= data_b.size / 8 - off_b + assert size_a <= data_a.size // 8 - off_a + assert size_b <= data_b.size // 8 - off_b # Successive comparable symbolic pointers # [(0, 8, @8[ptr]), (0, 8, @8[ptr+1])] => (0, 16, @16[ptr]) ptr = self.offset_to_ptr(ptr_base_a, (ptr_offset_a + off_a) & self._mask) @@ -280,7 +284,7 @@ class MemArray(MutableMapping): # Slice datas read_mem = [] for off, bytesize, data in parts: - if data.size / 8 != bytesize: + if data.size // 8 != bytesize: data = data[off * 8: (off + bytesize) * 8] read_mem.append(data) @@ -294,7 +298,7 @@ class MemArray(MutableMapping): """ assert expr.size % 8 == 0 assert offset <= self._mask - for index in xrange(expr.size / 8): + for index in range(expr.size // 8): # Wrap write: # @32[EAX+0xFFFFFFFF] is ok and will write at 0xFFFFFFFF, 0, 1, 2 request_offset = (offset + index) & self._mask @@ -305,7 +309,9 @@ class MemArray(MutableMapping): # Special case: Simplify slice of pointer (simplification is ok # here, as we won't store the simplified expression) if tmp.is_slice() and tmp.arg.is_mem() and tmp.start % 8 == 0: - new_ptr = self.expr_simp(tmp.arg.ptr + ExprInt(tmp.start / 8, tmp.arg.ptr.size)) + new_ptr = self.expr_simp( + tmp.arg.ptr + ExprInt(tmp.start // 8, tmp.arg.ptr.size) + ) tmp = ExprMem(new_ptr, tmp.stop - tmp.start) # Test if write to original value if tmp.is_mem(): @@ -332,12 +338,12 @@ class MemArray(MutableMapping): assert value.size % 8 == 0 if forward: - start, end, step = value_byte_index + 1, value.size / 8, 1 + start, end, step = value_byte_index + 1, value.size // 8, 1 else: start, end, step = value_byte_index - 1, -1, -1 partnum = 1 - for value_offset in xrange(start, end, step): + for value_offset in range(start, end, step): offset += step # Check if next part is in known_offsets next_index = index + step * partnum @@ -398,9 +404,8 @@ class MemArray(MutableMapping): """ if not self._offset_to_expr: - raise StopIteration - known_offsets = self._offset_to_expr.keys() - known_offsets.sort() + return + known_offsets = sorted(self._offset_to_expr) index = 0 # Test if the first element is the continuation of the last byte. If # yes, merge and output it first. @@ -444,7 +449,7 @@ class MemArray(MutableMapping): def dump(self): """Display MemArray content""" for mem, value in self.memory(): - print "%s = %s" % (mem, value) + print("%s = %s" % (mem, value)) class MemSparse(object): @@ -484,7 +489,7 @@ class MemSparse(object): memarray = self.base_to_memarray.get(base, None) if memarray is None: return False - for i in xrange(expr.size / 8): + for i in range(expr.size // 8): if offset + i not in memarray: return False return True @@ -500,7 +505,7 @@ class MemSparse(object): memarray = self.base_to_memarray.get(base, None) if memarray is None: return False - for i in xrange(expr.size / 8): + for i in range(expr.size // 8): if offset + i in memarray: return True return False @@ -512,7 +517,7 @@ class MemSparse(object): def copy(self): """Copy the current object instance""" base_to_memarray = {} - for base, memarray in self.base_to_memarray.iteritems(): + for base, memarray in viewitems(self.base_to_memarray): base_to_memarray[base] = memarray.copy() obj = MemSparse(self.addrsize, self.expr_simp) obj.base_to_memarray = base_to_memarray @@ -529,10 +534,10 @@ class MemSparse(object): if memarray is None: raise KeyError # Check if whole entity is in the MemArray before deleting it - for i in xrange(expr.size / 8): + for i in range(expr.size // 8): if (offset + i) & memarray.mask not in memarray: raise KeyError - for i in xrange(expr.size / 8): + for i in range(expr.size // 8): del memarray[(offset + i) & memarray.mask] def delete_partial(self, expr): @@ -546,7 +551,7 @@ class MemSparse(object): if memarray is None: raise KeyError # Check if whole entity is in the MemArray before deleting it - for i in xrange(expr.size / 8): + for i in range(expr.size // 8): real_offset = (offset + i) & memarray.mask if real_offset in memarray: del memarray[real_offset] @@ -583,7 +588,7 @@ class MemSparse(object): def iteritems(self): """Iterate on stored memory variables and their values.""" - for _, memarray in sorted(self.base_to_memarray.iteritems()): + for _, memarray in viewitems(self.base_to_memarray): for mem, value in memarray.memory(): yield mem, value @@ -593,12 +598,12 @@ class MemSparse(object): def dump(self): """Display MemSparse content""" - for mem, value in self.iteritems(): - print "%s = %s" % (mem, value) + for mem, value in viewitems(self): + print("%s = %s" % (mem, value)) def __repr__(self): out = [] - for _, memarray in sorted(self.base_to_memarray.iteritems()): + for _, memarray in sorted(viewitems(self.base_to_memarray)): out.append(repr(memarray)) return '\n'.join(out) @@ -615,7 +620,7 @@ class SymbolMngr(object): self.symbols_id = {} self.symbols_mem = MemSparse(addrsize, expr_simp) self.mask = (1 << addrsize) - 1 - for expr, value in init.iteritems(): + for expr, value in viewitems(init): self.write(expr, value) def __contains__(self, expr): @@ -687,14 +692,14 @@ class SymbolMngr(object): """Display memory content""" if ids: for variable, value in self.ids(): - print '%s = %s' % (variable, value) + print('%s = %s' % (variable, value)) if mems: for mem, value in self.memory(): - print '%s = %s' % (mem, value) + print('%s = %s' % (mem, value)) def __repr__(self): out = [] - for variable, value in self.iteritems(): + for variable, value in viewitems(self): out.append('%s = %s' % (variable, value)) return "\n".join(out) @@ -715,12 +720,12 @@ class SymbolMngr(object): def ids(self): """Iterate on variables and their values.""" - for expr, value in self.symbols_id.iteritems(): + for expr, value in viewitems(self.symbols_id): yield expr, value def memory(self): """Iterate on memory variables and their values.""" - for mem, value in self.symbols_mem.iteritems(): + for mem, value in viewitems(self.symbols_mem): yield mem, value def keys(self): @@ -817,7 +822,7 @@ class SymbolicExecutionEngine(object): self.symbols = SymbolMngr(addrsize=ir_arch.addrsize, expr_simp=sb_expr_simp) - for dst, src in state.iteritems(): + for dst, src in viewitems(state): self.symbols.write(dst, src) self.ir_arch = ir_arch @@ -833,7 +838,7 @@ class SymbolicExecutionEngine(object): @state: StateEngine instance """ self.symbols = SymbolMngr(addrsize=self.ir_arch.addrsize, expr_simp=self.expr_simp) - for dst, src in dict(state).iteritems(): + for dst, src in viewitems(dict(state)): self.symbols[dst] = src state = property(get_state, set_state) @@ -950,7 +955,7 @@ class SymbolicExecutionEngine(object): if init_state is None: init_state = {} if ids: - for variable, value in self.symbols.symbols_id.iteritems(): + for variable, value in viewitems(self.symbols.symbols_id): if variable in init_state and init_state[variable] == value: continue yield variable, value @@ -968,7 +973,7 @@ class SymbolicExecutionEngine(object): """ for variable, value in self.modified(None, ids, mems): - print "%-18s" % variable, "=", "%s" % value + print("%-18s" % variable, "=", "%s" % value) def eval_assignblk(self, assignblk): """ @@ -980,7 +985,7 @@ class SymbolicExecutionEngine(object): """ pool_out = {} eval_cache = {} - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): src = self.eval_expr(src, eval_cache) if dst.is_mem(): ptr = self.eval_expr(dst.ptr, eval_cache) @@ -1012,7 +1017,7 @@ class SymbolicExecutionEngine(object): """ mem_dst = [] dst_src = self.eval_assignblk(assignblk) - for dst, src in dst_src.iteritems(): + for dst, src in viewitems(dst_src): self.apply_change(dst, src) if dst.is_mem(): mem_dst.append(dst) @@ -1026,15 +1031,15 @@ class SymbolicExecutionEngine(object): """ for assignblk in irb: if step: - print 'Instr', assignblk.instr - print 'Assignblk:' - print assignblk - print '_' * 80 + print('Instr', assignblk.instr) + print('Assignblk:') + print(assignblk) + print('_' * 80) self.eval_updt_assignblk(assignblk) if step: self.dump(mems=False) self.dump(ids=False) - print '_' * 80 + print('_' * 80) dst = self.eval_expr(self.ir_arch.IRDst) return dst diff --git a/miasm2/ir/symbexec_top.py b/miasm2/ir/symbexec_top.py index be48c065..a1a255f8 100644 --- a/miasm2/ir/symbexec_top.py +++ b/miasm2/ir/symbexec_top.py @@ -1,3 +1,5 @@ +from future.utils import viewitems + from miasm2.ir.symbexec import SymbolicExecutionEngine, StateEngine from miasm2.expression.simplifications import expr_simp from miasm2.expression.expression import ExprId, ExprInt, ExprSlice,\ @@ -16,7 +18,7 @@ def exprid_top(expr): class SymbolicStateTop(StateEngine): def __init__(self, dct, regstop): - self._symbols = frozenset(dct.items()) + self._symbols = frozenset(viewitems(dct)) self._regstop = frozenset(regstop) def __hash__(self): @@ -52,8 +54,8 @@ class SymbolicStateTop(StateEngine): """ symb_a = self.symbols symb_b = other.symbols - intersection = set(symb_a.keys()).intersection(symb_b.keys()) - diff = set(symb_a.keys()).union(symb_b.keys()).difference(intersection) + intersection = set(symb_a).intersection(symb_b) + diff = set(symb_a).union(symb_b).difference(intersection) symbols = {} regstop = set() for dst in diff: diff --git a/miasm2/ir/symbexec_types.py b/miasm2/ir/symbexec_types.py index e4f37e3f..57b7580a 100644 --- a/miasm2/ir/symbexec_types.py +++ b/miasm2/ir/symbexec_types.py @@ -1,3 +1,7 @@ +from __future__ import print_function + +from future.utils import viewitems + from miasm2.ir.symbexec import SymbolicExecutionEngine, StateEngine from miasm2.expression.simplifications import expr_simp from miasm2.expression.expression import ExprId, ExprMem @@ -8,9 +12,9 @@ class SymbolicStateCTypes(StateEngine): def __init__(self, symbols): tmp = {} - for expr, types in symbols.iteritems(): + for expr, types in viewitems(symbols): tmp[expr] = frozenset(types) - self._symbols = frozenset(tmp.iteritems()) + self._symbols = frozenset(viewitems(tmp)) def __hash__(self): return hash((self.__class__, self._symbols)) @@ -84,7 +88,7 @@ class SymbExecCType(SymbolicExecutionEngine): @assignblk: AssignBlock instance """ pool_out = {} - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): objcs = self.chandler.expr_to_types(src, self.symbols) if isinstance(dst, ExprMem): continue @@ -112,16 +116,16 @@ class SymbExecCType(SymbolicExecutionEngine): """ Dump modififed registers symbols only """ - for expr, expr_types in sorted(self.symbols.iteritems()): + for expr, expr_types in sorted(viewitems(self.symbols)): if not expr.is_mem(): - print expr + print(expr) for expr_type in expr_types: - print '\t', expr_type + print('\t', expr_type) def dump_mem(self): """ Dump modififed memory symbols """ - for expr, value in sorted(self.symbols.iteritems()): + for expr, value in sorted(viewitems(self.symbols)): if expr.is_mem(): - print expr, value + print(expr, value) diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py index 5a55237f..e44e859f 100644 --- a/miasm2/ir/translators/C.py +++ b/miasm2/ir/translators/C.py @@ -11,8 +11,8 @@ def int_size_to_bn(value, size): size_nibble = 8 else: # size must be multiple of 4 - size = ((size + 31) / 32) * 32 - size_nibble = size / 4 + size = ((size + 31) // 32) * 32 + size_nibble = size // 4 fmt_str = "%%.%dx" % size_nibble int_str = fmt_str % value assert len(int_str) == size_nibble diff --git a/miasm2/ir/translators/miasm.py b/miasm2/ir/translators/miasm.py index 356ec3fd..e93e9499 100644 --- a/miasm2/ir/translators/miasm.py +++ b/miasm2/ir/translators/miasm.py @@ -1,3 +1,4 @@ +from builtins import map from miasm2.ir.translators.translator import Translator @@ -23,8 +24,10 @@ class TranslatorMiasm(Translator): expr.stop) def from_ExprOp(self, expr): - return "ExprOp(%s, %s)" % (repr(expr.op), - ", ".join(map(self.from_expr, expr.args))) + return "ExprOp(%s, %s)" % ( + repr(expr.op), + ", ".join(map(self.from_expr, expr.args)) + ) def from_ExprCompose(self, expr): args = ["%s" % self.from_expr(arg) for arg in expr.args] diff --git a/miasm2/ir/translators/python.py b/miasm2/ir/translators/python.py index f32e4585..4b1b4b52 100644 --- a/miasm2/ir/translators/python.py +++ b/miasm2/ir/translators/python.py @@ -1,3 +1,4 @@ +from builtins import map from miasm2.expression.expression import ExprInt from miasm2.ir.translators.translator import Translator @@ -24,8 +25,10 @@ class TranslatorPython(Translator): return str(expr) def from_ExprMem(self, expr): - return "memory(%s, 0x%x)" % (self.from_expr(expr.ptr), - expr.size / 8) + return "memory(%s, 0x%x)" % ( + self.from_expr(expr.ptr), + expr.size // 8 + ) def from_ExprSlice(self, expr): out = self.from_expr(expr.arg) @@ -36,26 +39,36 @@ class TranslatorPython(Translator): def from_ExprCompose(self, expr): out = [] for index, arg in expr.iter_args(): - out.append("((%s & 0x%x) << %d)" % (self.from_expr(arg), - (1 << arg.size) - 1, - index)) + out.append( + "((%s & 0x%x) << %d)" % ( + self.from_expr(arg), + (1 << arg.size) - 1, + index + ) + ) return "(%s)" % ' | '.join(out) def from_ExprCond(self, expr): - return "(%s if (%s) else %s)" % (self.from_expr(expr.src1), - self.from_expr(expr.cond), - self.from_expr(expr.src2)) + return "(%s if (%s) else %s)" % ( + self.from_expr(expr.src1), + self.from_expr(expr.cond), + self.from_expr(expr.src2) + ) def from_ExprOp(self, expr): if expr.op in self.op_no_translate: - args = map(self.from_expr, expr.args) + args = list(map(self.from_expr, expr.args)) if len(expr.args) == 1: - return "((%s %s) & 0x%x)" % (expr.op, - args[0], - (1 << expr.size) - 1) + return "((%s %s) & 0x%x)" % ( + expr.op, + args[0], + (1 << expr.size) - 1 + ) else: - return "((%s) & 0x%x)" % ((" %s " % expr.op).join(args), - (1 << expr.size) - 1) + return "((%s) & 0x%x)" % ( + (" %s " % expr.op).join(args), + (1 << expr.size) - 1 + ) elif expr.op == "parity": return "(%s & 0x1)" % self.from_expr(expr.args[0]) @@ -75,7 +88,10 @@ class TranslatorPython(Translator): raise NotImplementedError("Unknown operator: %s" % expr.op) def from_ExprAssign(self, expr): - return "%s = %s" % tuple(map(self.from_expr, (expr.dst, expr.src))) + return "%s = %s" % ( + self.from_expr(expr.dst), + self.from_expr(expr.src) + ) # Register the class diff --git a/miasm2/ir/translators/smt2.py b/miasm2/ir/translators/smt2.py index 81d86798..7b619457 100644 --- a/miasm2/ir/translators/smt2.py +++ b/miasm2/ir/translators/smt2.py @@ -1,3 +1,5 @@ +from builtins import map +from builtins import range import logging from miasm2.ir.translators.translator import Translator @@ -76,14 +78,14 @@ class SMT2Mem(object): original_size = size if original_size % 8 != 0: # Size not aligned on 8bits -> read more than size and extract after - size = ((original_size / 8) + 1) * 8 + size = ((original_size // 8) + 1) * 8 res = self[addr] if self.is_little_endian(): - for i in xrange(1, size/8): + for i in range(1, size // 8): index = bvadd(addr, bit_vec_val(i, addr_size)) res = bv_concat(self[index], res) else: - for i in xrange(1, size/8): + for i in range(1, size // 8): res = bv_concat(res, self[index]) if size == original_size: return res @@ -185,7 +187,7 @@ class TranslatorSMT2(Translator): return smt2_ite(distinct_and, src1, src2) def from_ExprOp(self, expr): - args = map(self.from_expr, expr.args) + args = list(map(self.from_expr, expr.args)) res = args[0] if len(args) > 1: @@ -229,7 +231,7 @@ class TranslatorSMT2(Translator): elif expr.op == 'parity': arg = bv_extract(7, 0, res) res = bit_vec_val(1, 1) - for i in xrange(8): + for i in range(8): res = bvxor(res, bv_extract(i, i, arg)) elif expr.op == '-': res = bvneg(res) @@ -245,7 +247,7 @@ class TranslatorSMT2(Translator): cond = smt2_distinct(op, zero_smt2) # ite(cond, size - 1, src) res = smt2_ite(cond, bvsub(size_smt2, one_smt2), src) - for i in xrange(size - 2, -1, -1): + for i in range(size - 2, -1, -1): # smt2 expression of i i_smt2 = bit_vec_val(i, size) # src & (1 << i) @@ -263,7 +265,7 @@ class TranslatorSMT2(Translator): cond = smt2_distinct(bvand(src, one_smt2), zero_smt2) # ite(cond, 0, src) res= smt2_ite(cond, zero_smt2, src) - for i in xrange(size - 1, 0, -1): + for i in range(size - 1, 0, -1): index = - i % size index_smt2 = bit_vec_val(index, size) # src & (1 << index) diff --git a/miasm2/ir/translators/translator.py b/miasm2/ir/translators/translator.py index a56c6a62..65875072 100644 --- a/miasm2/ir/translators/translator.py +++ b/miasm2/ir/translators/translator.py @@ -1,3 +1,5 @@ +from future.utils import viewitems + import miasm2.expression.expression as m2_expr from miasm2.core.utils import BoundedDict @@ -104,17 +106,18 @@ class Translator(object): return self._cache[expr] # Handle Expr type - handlers = {m2_expr.ExprInt: self.from_ExprInt, - m2_expr.ExprId: self.from_ExprId, - m2_expr.ExprLoc: self.from_ExprLoc, - m2_expr.ExprCompose: self.from_ExprCompose, - m2_expr.ExprSlice: self.from_ExprSlice, - m2_expr.ExprOp: self.from_ExprOp, - m2_expr.ExprMem: self.from_ExprMem, - m2_expr.ExprAssign: self.from_ExprAssign, - m2_expr.ExprCond: self.from_ExprCond - } - for target, handler in handlers.iteritems(): + handlers = { + m2_expr.ExprInt: self.from_ExprInt, + m2_expr.ExprId: self.from_ExprId, + m2_expr.ExprLoc: self.from_ExprLoc, + m2_expr.ExprCompose: self.from_ExprCompose, + m2_expr.ExprSlice: self.from_ExprSlice, + m2_expr.ExprOp: self.from_ExprOp, + m2_expr.ExprMem: self.from_ExprMem, + m2_expr.ExprAssign: self.from_ExprAssign, + m2_expr.ExprCond: self.from_ExprCond + } + for target, handler in viewitems(handlers): if isinstance(expr, target): ## Compute value and update the internal cache ret = handler(expr) diff --git a/miasm2/ir/translators/z3_ir.py b/miasm2/ir/translators/z3_ir.py index 204ee976..902e72bd 100644 --- a/miasm2/ir/translators/z3_ir.py +++ b/miasm2/ir/translators/z3_ir.py @@ -1,3 +1,5 @@ +from builtins import map +from builtins import range import imp import logging @@ -76,13 +78,13 @@ class Z3Mem(object): original_size = size if original_size % 8 != 0: # Size not aligned on 8bits -> read more than size and extract after - size = ((original_size / 8) + 1) * 8 + size = ((original_size // 8) + 1) * 8 res = self[addr] if self.is_little_endian(): - for i in xrange(1, size/8): + for i in range(1, size // 8): res = z3.Concat(self[addr+i], res) else: - for i in xrange(1, size/8): + for i in range(1, size //8): res = z3.Concat(res, self[addr+i]) if size == original_size: return res @@ -182,7 +184,7 @@ class TranslatorZ3(Translator): return z3.UDiv(self._abs(num), self._abs(den)) * result_sign def from_ExprOp(self, expr): - args = map(self.from_expr, expr.args) + args = list(map(self.from_expr, expr.args)) res = args[0] if len(args) > 1: @@ -240,7 +242,7 @@ class TranslatorZ3(Translator): elif expr.op == 'parity': arg = z3.Extract(7, 0, res) res = z3.BitVecVal(1, 1) - for i in xrange(8): + for i in range(8): res = res ^ z3.Extract(i, i, arg) elif expr.op == '-': res = -res @@ -248,13 +250,13 @@ class TranslatorZ3(Translator): size = expr.size src = res res = z3.If(src == 0, size, src) - for i in xrange(size - 1, -1, -1): + for i in range(size - 1, -1, -1): res = z3.If((src & (1 << i)) != 0, i, res) elif expr.op == "cntleadzeros": size = expr.size src = res res = z3.If(src == 0, size, src) - for i in xrange(size, 0, -1): + for i in range(size, 0, -1): index = - i % size out = size - (index + 1) res = z3.If((src & (1 << index)) != 0, out, res) diff --git a/miasm2/jitter/JitCore.c b/miasm2/jitter/JitCore.c index a2873d03..ae5af293 100644 --- a/miasm2/jitter/JitCore.c +++ b/miasm2/jitter/JitCore.c @@ -2,6 +2,7 @@ #include "structmember.h" #include <stdint.h> #include <inttypes.h> +#include "compat_py23.h" #include "queue.h" #include "vm_mngr.h" #include "vm_mngr_py.h" @@ -11,7 +12,7 @@ void JitCpu_dealloc(JitCpu* self) { - self->ob_type->tp_free((PyObject*)self); + Py_TYPE(self)->tp_free((PyObject*)self); } @@ -250,7 +251,7 @@ PyObject* vm_get_mem(JitCpu *self, PyObject* args) return NULL; } - obj_out = PyString_FromStringAndSize(buf_out, size); + obj_out = PyBytes_FromStringAndSize(buf_out, size); free(buf_out); return obj_out; } diff --git a/miasm2/jitter/JitCore.h b/miasm2/jitter/JitCore.h index d85b71d9..15efc7d2 100644 --- a/miasm2/jitter/JitCore.h +++ b/miasm2/jitter/JitCore.h @@ -11,31 +11,73 @@ #define RAISE_ret0(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return 0;} -#define PyGetInt(item, value) \ - if (PyInt_Check(item)){ \ - value = (uint64_t)PyInt_AsLong(item); \ - } \ - else if (PyLong_Check(item)){ \ - value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ - } \ - else{ \ - RAISE(PyExc_TypeError,"arg must be int"); \ - } \ - - -#define PyGetInt_retneg(item, value) \ - if (PyInt_Check(item)){ \ - value = (uint64_t)PyInt_AsLong(item); \ - } \ - else if (PyLong_Check(item)){ \ - value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ - } \ - else{ \ - PyErr_SetString(PyExc_TypeError, "Arg must be int"); \ - return -1; \ +#if PY_MAJOR_VERSION >= 3 +#define getset_reg_bn(regname, size) \ + static PyObject *JitCpu_get_ ## regname (JitCpu *self, void *closure) \ + { \ + bn_t bn; \ + int j; \ + PyObject* py_long; \ + PyObject* py_long_new; \ + PyObject* py_tmp; \ + PyObject* cst_32; \ + uint64_t tmp; \ + py_long = PyLong_FromLong(0); \ + cst_32 = PyLong_FromLong(32); \ + bn = ((vm_cpu_t*)(self->cpu))-> regname; \ + bn = bignum_mask(bn, (size)); \ + for (j = BN_BYTE_SIZE - 4; j >= 0 ; j -= 4) { \ + tmp = bignum_to_uint64(bignum_mask(bignum_rshift(bn, 8 * j), 32)); \ + py_tmp = PyLong_FromUnsignedLong(tmp); \ + py_long_new = PyObject_CallMethod(py_long, "__lshift__", "O", cst_32); \ + Py_DECREF(py_long); \ + py_long = PyObject_CallMethod(py_long_new, "__add__", "O", py_tmp); \ + Py_DECREF(py_long_new); \ + Py_DECREF(py_tmp); \ + } \ + Py_DECREF(cst_32); \ + return py_long; \ } \ + \ + static int JitCpu_set_ ## regname (JitCpu *self, PyObject *value, void *closure) \ + { \ + bn_t bn; \ + int j; \ + PyObject* py_long = value; \ + PyObject* py_long_new; \ + PyObject* py_tmp; \ + PyObject* cst_32; \ + PyObject* cst_ffffffff; \ + uint64_t tmp; \ + if (PyLong_Check(py_long)){ \ + Py_INCREF(py_long); \ + } else { \ + RAISE(PyExc_TypeError,"arg must be int"); \ + } \ + \ + cst_ffffffff = PyLong_FromLong(0xffffffff); \ + cst_32 = PyLong_FromLong(32); \ + bn = bignum_from_int(0); \ + \ + for (j = 0; j < BN_BYTE_SIZE; j += 4) { \ + py_tmp = PyObject_CallMethod(py_long, "__and__", "O", cst_ffffffff); \ + py_long_new = PyObject_CallMethod(py_long, "__rshift__", "O", cst_32); \ + Py_DECREF(py_long); \ + py_long = py_long_new; \ + tmp = PyLong_AsUnsignedLongMask(py_tmp); \ + Py_DECREF(py_tmp); \ + bn = bignum_or(bn, bignum_lshift(bignum_from_uint64(tmp), 8 * j)); \ + } \ + \ + ((vm_cpu_t*)(self->cpu))-> regname = bignum_mask(bn, (size)); \ + Py_DECREF(py_long); \ + Py_DECREF(cst_32); \ + Py_DECREF(cst_ffffffff); \ + return 0; \ + } +#else #define getset_reg_bn(regname, size) \ static PyObject *JitCpu_get_ ## regname (JitCpu *self, void *closure) \ { \ @@ -74,18 +116,14 @@ PyObject* cst_ffffffff; \ uint64_t tmp; \ \ - /* Ensure py_long is a PyLong */ \ - if (PyInt_Check(py_long)) { \ + if (PyInt_Check(py_long)){ \ tmp = (uint64_t)PyInt_AsLong(py_long); \ - py_long = PyLong_FromLong(tmp); \ + py_long = PyLong_FromLong((long)tmp); \ } else if (PyLong_Check(py_long)){ \ - /* Already PyLong */ \ - /* Increment ref as we will decement it next */ \ Py_INCREF(py_long); \ } \ - else { \ - PyErr_SetString(PyExc_TypeError, "Arg must be int"); \ - return -1; \ + else{ \ + RAISE(PyExc_TypeError,"arg must be int"); \ } \ \ cst_ffffffff = PyLong_FromLong(0xffffffff); \ @@ -108,6 +146,17 @@ Py_DECREF(cst_ffffffff); \ return 0; \ } +#endif + + + + + + + + + + #define getset_reg_u64(regname) \ static PyObject *JitCpu_get_ ## regname (JitCpu *self, void *closure) \ diff --git a/miasm2/jitter/Jitgcc.c b/miasm2/jitter/Jitgcc.c index 329b7db4..0a39c998 100644 --- a/miasm2/jitter/Jitgcc.c +++ b/miasm2/jitter/Jitgcc.c @@ -1,6 +1,7 @@ #include <Python.h> #include <inttypes.h> #include <stdint.h> +#include "compat_py23.h" typedef struct { uint8_t is_local; @@ -90,17 +91,16 @@ static PyMethodDef GccMethods[] = { {NULL, NULL, 0, NULL} /* Sentinel */ }; -PyMODINIT_FUNC -initJitgcc(void) + + +MOD_INIT(Jitgcc) { - PyObject *m; + PyObject *module; - m = Py_InitModule("Jitgcc", GccMethods); - if (m == NULL) - return; + MOD_DEF(module, "Jitgcc", "gcc module", GccMethods); - GccError = PyErr_NewException("gcc.error", NULL, NULL); - Py_INCREF(GccError); - PyModule_AddObject(m, "error", GccError); -} + if (module == NULL) + return NULL; + return module; +} diff --git a/miasm2/jitter/Jitllvm.c b/miasm2/jitter/Jitllvm.c index bb500d2e..efe5250f 100644 --- a/miasm2/jitter/Jitllvm.c +++ b/miasm2/jitter/Jitllvm.c @@ -3,6 +3,7 @@ #include <inttypes.h> #include <stdint.h> +#include "compat_py23.h" #include "queue.h" #include "vm_mngr.h" #include "vm_mngr_py.h" @@ -82,13 +83,17 @@ static PyMethodDef LLVMMethods[] = { {NULL, NULL, 0, NULL} /* Sentinel */ }; -PyMODINIT_FUNC -initJitllvm(void) + + + +MOD_INIT(Jitllvm) { - PyObject *m; + PyObject *module; - m = Py_InitModule("Jitllvm", LLVMMethods); - if (m == NULL) - return; + MOD_DEF(module, "Jitllvm", "llvm module", LLVMMethods); + + if (module == NULL) + return NULL; + return module; } diff --git a/miasm2/jitter/arch/JitCore_aarch64.c b/miasm2/jitter/arch/JitCore_aarch64.c index d8b6d0f9..9e1a870e 100644 --- a/miasm2/jitter/arch/JitCore_aarch64.c +++ b/miasm2/jitter/arch/JitCore_aarch64.c @@ -2,6 +2,7 @@ #include "structmember.h" #include <stdint.h> #include <inttypes.h> +#include "../compat_py23.h" #include "../queue.h" #include "../vm_mngr.h" #include "../vm_mngr_py.h" @@ -117,6 +118,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) PyObject* dict; PyObject *d_key, *d_value = NULL; Py_ssize_t pos = 0; + char* d_key_name; uint64_t val; unsigned int i, found; @@ -125,14 +127,12 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) if(!PyDict_Check(dict)) RAISE(PyExc_TypeError, "arg must be dict"); while(PyDict_Next(dict, &pos, &d_key, &d_value)){ - if(!PyString_Check(d_key)) - RAISE(PyExc_TypeError, "key must be str"); - + PyGetStr(d_key_name, d_key); PyGetInt(d_value, val); found = 0; for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ - if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name)) + if (strcmp(d_key_name, gpreg_dict[i].name)) continue; *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val; found = 1; @@ -141,7 +141,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) if (found) continue; - fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key)); + fprintf(stderr, "unknown key: %s\n", d_key_name); RAISE(PyExc_ValueError, "unknown reg"); } Py_INCREF(Py_None); @@ -276,11 +276,11 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args) PyGetInt(py_addr, addr); - if(!PyString_Check(py_buffer)) - RAISE(PyExc_TypeError,"arg must be str"); + if(!PyBytes_Check(py_buffer)) + RAISE(PyExc_TypeError,"arg must be bytes"); - size = PyString_Size(py_buffer); - PyString_AsStringAndSize(py_buffer, &buffer, &py_length); + size = PyBytes_Size(py_buffer); + PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length); ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size); if (ret < 0) @@ -491,9 +491,8 @@ static PyGetSetDef JitCpu_getseters[] = { static PyTypeObject JitCpuType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "JitCore_aarch64.JitCpu", /*tp_name*/ + PyVarObject_HEAD_INIT(NULL, 0) + "JitCore_aarch64.JitCpu", /*tp_name*/ sizeof(JitCpu), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)JitCpu_dealloc,/*tp_dealloc*/ @@ -540,26 +539,24 @@ static PyMethodDef JitCore_aarch64_Methods[] = { }; -static PyObject *JitCore_aarch64_Error; -PyMODINIT_FUNC -initJitCore_aarch64(void) + +MOD_INIT(JitCore_aarch64) { - PyObject *m; + PyObject *module; - if (PyType_Ready(&JitCpuType) < 0) - return; + MOD_DEF(module, "JitCore_aarch64", "JitCore_aarch64 module", JitCore_aarch64_Methods); - m = Py_InitModule("JitCore_aarch64", JitCore_aarch64_Methods); - if (m == NULL) - return; + if (module == NULL) + return NULL; - JitCore_aarch64_Error = PyErr_NewException("JitCore_aarch64.error", NULL, NULL); - Py_INCREF(JitCore_aarch64_Error); - PyModule_AddObject(m, "error", JitCore_aarch64_Error); + if (PyType_Ready(&JitCpuType) < 0) + return NULL; - Py_INCREF(&JitCpuType); - PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType); + Py_INCREF(&JitCpuType); + if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0) + return NULL; + return module; } diff --git a/miasm2/jitter/arch/JitCore_arm.c b/miasm2/jitter/arch/JitCore_arm.c index dca341d3..64f30cf4 100644 --- a/miasm2/jitter/arch/JitCore_arm.c +++ b/miasm2/jitter/arch/JitCore_arm.c @@ -2,6 +2,7 @@ #include "structmember.h" #include <stdint.h> #include <inttypes.h> +#include "../compat_py23.h" #include "../queue.h" #include "../vm_mngr.h" #include "../vm_mngr_py.h" @@ -91,6 +92,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) PyObject* dict; PyObject *d_key, *d_value = NULL; Py_ssize_t pos = 0; + char* d_key_name; uint64_t val; unsigned int i, found; @@ -99,14 +101,12 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) if(!PyDict_Check(dict)) RAISE(PyExc_TypeError, "arg must be dict"); while(PyDict_Next(dict, &pos, &d_key, &d_value)){ - if(!PyString_Check(d_key)) - RAISE(PyExc_TypeError, "key must be str"); - + PyGetStr(d_key_name, d_key); PyGetInt(d_value, val); found = 0; for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ - if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name)) + if (strcmp(d_key_name, gpreg_dict[i].name)) continue; *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val; found = 1; @@ -115,7 +115,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) if (found) continue; - fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key)); + fprintf(stderr, "unknown key: %s\n", d_key); RAISE(PyExc_ValueError, "unknown reg"); } Py_INCREF(Py_None); @@ -239,11 +239,11 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args) PyGetInt(py_addr, addr); - if(!PyString_Check(py_buffer)) - RAISE(PyExc_TypeError,"arg must be str"); + if(!PyBytes_Check(py_buffer)) + RAISE(PyExc_TypeError,"arg must be bytes"); - size = PyString_Size(py_buffer); - PyString_AsStringAndSize(py_buffer, &buffer, &py_length); + size = PyBytes_Size(py_buffer); + PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length); ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size); if (ret < 0) @@ -432,8 +432,7 @@ static PyGetSetDef JitCpu_getseters[] = { static PyTypeObject JitCpuType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ + PyVarObject_HEAD_INIT(NULL, 0) "JitCore_arm.JitCpu", /*tp_name*/ sizeof(JitCpu), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -485,26 +484,24 @@ static PyMethodDef JitCore_arm_Methods[] = { }; -static PyObject *JitCore_arm_Error; -PyMODINIT_FUNC -initJitCore_arm(void) + +MOD_INIT(JitCore_arm) { - PyObject *m; + PyObject *module; - if (PyType_Ready(&JitCpuType) < 0) - return; + MOD_DEF(module, "JitCore_arm", "JitCore_arm module", JitCore_arm_Methods); - m = Py_InitModule("JitCore_arm", JitCore_arm_Methods); - if (m == NULL) - return; + if (module == NULL) + return NULL; - JitCore_arm_Error = PyErr_NewException("JitCore_arm.error", NULL, NULL); - Py_INCREF(JitCore_arm_Error); - PyModule_AddObject(m, "error", JitCore_arm_Error); + if (PyType_Ready(&JitCpuType) < 0) + return NULL; - Py_INCREF(&JitCpuType); - PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType); + Py_INCREF(&JitCpuType); + if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0) + return NULL; + return module; } diff --git a/miasm2/jitter/arch/JitCore_mep.c b/miasm2/jitter/arch/JitCore_mep.c index a089e84f..6e7f1767 100644 --- a/miasm2/jitter/arch/JitCore_mep.c +++ b/miasm2/jitter/arch/JitCore_mep.c @@ -5,6 +5,7 @@ #include <stdint.h> #include <inttypes.h> +#include "../compat_py23.h" #include "../queue.h" #include "../vm_mngr.h" #include "../vm_mngr_py.h" @@ -148,32 +149,31 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) PyObject* dict; PyObject *d_key, *d_value = NULL; Py_ssize_t pos = 0; + char* d_key_name; uint64_t val; unsigned int i, found; if (!PyArg_ParseTuple(args, "O", &dict)) - return NULL; + return NULL; if(!PyDict_Check(dict)) - RAISE(PyExc_TypeError, "arg must be dict"); + RAISE(PyExc_TypeError, "arg must be dict"); while(PyDict_Next(dict, &pos, &d_key, &d_value)){ - if(!PyString_Check(d_key)) - RAISE(PyExc_TypeError, "key must be str"); - - PyGetInt(d_value, val); - - found = 0; - for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ - if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name)) - continue; - *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val; - found = 1; - break; - } - - if (found) - continue; - fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key)); - RAISE(PyExc_ValueError, "unknown reg"); + PyGetStr(d_key_name, d_key); + PyGetInt(d_value, val); + + found = 0; + for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ + if (strcmp(d_key_name, gpreg_dict[i].name)) + continue; + *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val; + found = 1; + break; + } + + if (found) + continue; + fprintf(stderr, "unknown key: %s\n", d_key_name); + RAISE(PyExc_ValueError, "unknown reg"); } Py_INCREF(Py_None); return Py_None; @@ -193,23 +193,23 @@ PyObject * cpu_init_regs(JitCpu* self) void dump_gpregs(vm_cpu_t* vmcpu) { - printf("R0 %.4"PRIX32" ", vmcpu->R0); - printf("R1 %.4"PRIX32" ", vmcpu->R1); - printf("R2 %.4"PRIX32" ", vmcpu->R2); - printf("R3 %.4"PRIX32" ", vmcpu->R3); - printf("R4 %.4"PRIX32" ", vmcpu->R4); - printf("R5 %.4"PRIX32" ", vmcpu->R5); - printf("R6 %.4"PRIX32" ", vmcpu->R6); - printf("R7 %.4"PRIX32" ", vmcpu->R7); - printf("R8 %.4"PRIX32" ", vmcpu->R8); - printf("R9 %.4"PRIX32" ", vmcpu->R9); - printf("R10 %.4"PRIX32" ", vmcpu->R10); - printf("R11 %.4"PRIX32" ", vmcpu->R11); - printf("R12 %.4"PRIX32" ", vmcpu->R12); - printf("TP %.4"PRIX32" ", vmcpu->TP); - printf("GP %.4"PRIX32" ", vmcpu->GP); - printf("SP %.4"PRIX32" ", vmcpu->SP); - printf("\n"); + printf("R0 %.4"PRIX32" ", vmcpu->R0); + printf("R1 %.4"PRIX32" ", vmcpu->R1); + printf("R2 %.4"PRIX32" ", vmcpu->R2); + printf("R3 %.4"PRIX32" ", vmcpu->R3); + printf("R4 %.4"PRIX32" ", vmcpu->R4); + printf("R5 %.4"PRIX32" ", vmcpu->R5); + printf("R6 %.4"PRIX32" ", vmcpu->R6); + printf("R7 %.4"PRIX32" ", vmcpu->R7); + printf("R8 %.4"PRIX32" ", vmcpu->R8); + printf("R9 %.4"PRIX32" ", vmcpu->R9); + printf("R10 %.4"PRIX32" ", vmcpu->R10); + printf("R11 %.4"PRIX32" ", vmcpu->R11); + printf("R12 %.4"PRIX32" ", vmcpu->R12); + printf("TP %.4"PRIX32" ", vmcpu->TP); + printf("GP %.4"PRIX32" ", vmcpu->GP); + printf("SP %.4"PRIX32" ", vmcpu->SP); + printf("\n"); } @@ -234,7 +234,7 @@ PyObject* cpu_set_exception(JitCpu* self, PyObject* args) uint64_t i; if (!PyArg_ParseTuple(args, "O", &item1)) - return NULL; + return NULL; PyGetInt(item1, i); @@ -253,7 +253,7 @@ void check_automod(JitCpu* jitcpu, uint64_t addr, uint64_t size) PyObject *result; if (!(((VmMngr*)jitcpu->pyvm)->vm_mngr.exception_flags & EXCEPT_CODE_AUTOMOD)) - return; + return; result = PyObject_CallMethod(jitcpu->jitter, "automod_cb", "LL", addr, size); Py_DECREF(result); @@ -296,19 +296,19 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args) int ret = 0x1337; if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_buffer)) - return NULL; + return NULL; PyGetInt(py_addr, addr); - if(!PyString_Check(py_buffer)) - RAISE(PyExc_TypeError,"arg must be str"); + if(!PyBytes_Check(py_buffer)) + RAISE(PyExc_TypeError,"arg must be bytes"); - size = PyString_Size(py_buffer); - PyString_AsStringAndSize(py_buffer, &buffer, &py_length); + size = PyBytes_Size(py_buffer); + PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length); ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size); if (ret < 0) - RAISE(PyExc_TypeError,"arg must be str"); + RAISE(PyExc_TypeError,"arg must be str"); check_automod(self, addr, size*8); Py_INCREF(Py_None); @@ -337,8 +337,8 @@ JitCpu_init(JitCpu *self, PyObject *args, PyObject *kwds) { self->cpu = malloc(sizeof(vm_cpu_t)); if (self->cpu == NULL) { - fprintf(stderr, "cannot alloc vm_cpu_t\n"); - exit(0); + fprintf(stderr, "cannot alloc vm_cpu_t\n"); + exit(0); } return 0; } @@ -543,8 +543,7 @@ static PyGetSetDef JitCpu_getseters[] = { static PyTypeObject JitCpuType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ + PyVarObject_HEAD_INIT(NULL, 0) "JitCore_mep.JitCpu", /*tp_name*/ sizeof(JitCpu), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -596,25 +595,23 @@ static PyMethodDef JitCore_mep_Methods[] = { }; -static PyObject *JitCore_mep_Error; -PyMODINIT_FUNC -initJitCore_mep(void) + +MOD_INIT(JitCore_mep) { - PyObject *m; + PyObject *module; - if (PyType_Ready(&JitCpuType) < 0) - return; + MOD_DEF(module, "JitCore_mep", "JitCore_mep module", JitCore_mep_Methods); - m = Py_InitModule("JitCore_mep", JitCore_mep_Methods); - if (m == NULL) - return; + if (module == NULL) + return NULL; - JitCore_mep_Error = PyErr_NewException("JitCore_mep.error", NULL, NULL); - Py_INCREF(JitCore_mep_Error); - PyModule_AddObject(m, "error", JitCore_mep_Error); + if (PyType_Ready(&JitCpuType) < 0) + return NULL; - Py_INCREF(&JitCpuType); - PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType); + Py_INCREF(&JitCpuType); + if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0) + return NULL; + return module; } diff --git a/miasm2/jitter/arch/JitCore_mips32.c b/miasm2/jitter/arch/JitCore_mips32.c index 1c2854aa..1455fec9 100644 --- a/miasm2/jitter/arch/JitCore_mips32.c +++ b/miasm2/jitter/arch/JitCore_mips32.c @@ -2,6 +2,7 @@ #include "structmember.h" #include <stdint.h> #include <inttypes.h> +#include "../compat_py23.h" #include "../queue.h" #include "../vm_mngr.h" #include "../vm_mngr_py.h" @@ -107,6 +108,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) PyObject* dict; PyObject *d_key, *d_value = NULL; Py_ssize_t pos = 0; + char* d_key_name; uint64_t val; unsigned int i, found; @@ -115,14 +117,12 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) if(!PyDict_Check(dict)) RAISE(PyExc_TypeError, "arg must be dict"); while(PyDict_Next(dict, &pos, &d_key, &d_value)){ - if(!PyString_Check(d_key)) - RAISE(PyExc_TypeError, "key must be str"); - + PyGetStr(d_key_name, d_key); PyGetInt(d_value, val); found = 0; for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ - if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name)) + if (strcmp(d_key_name, gpreg_dict[i].name)) continue; *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val; found = 1; @@ -131,7 +131,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) if (found) continue; - fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key)); + fprintf(stderr, "unknown key: %s\n", d_key_name); RAISE(PyExc_ValueError, "unknown reg"); } Py_INCREF(Py_None); @@ -264,11 +264,11 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args) PyGetInt(py_addr, addr); - if(!PyString_Check(py_buffer)) - RAISE(PyExc_TypeError,"arg must be str"); + if(!PyBytes_Check(py_buffer)) + RAISE(PyExc_TypeError,"arg must be bytes"); - size = PyString_Size(py_buffer); - PyString_AsStringAndSize(py_buffer, &buffer, &py_length); + size = PyBytes_Size(py_buffer); + PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length); ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size); if (ret < 0) @@ -455,8 +455,7 @@ static PyGetSetDef JitCpu_getseters[] = { static PyTypeObject JitCpuType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ + PyVarObject_HEAD_INIT(NULL, 0) "JitCore_mips32.JitCpu", /*tp_name*/ sizeof(JitCpu), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -508,26 +507,25 @@ static PyMethodDef JitCore_mips32_Methods[] = { }; -static PyObject *JitCore_mips32_Error; -PyMODINIT_FUNC -initJitCore_mips32(void) + + + +MOD_INIT(JitCore_mips32) { - PyObject *m; + PyObject *module; - if (PyType_Ready(&JitCpuType) < 0) - return; + MOD_DEF(module, "JitCore_mips32", "JitCore_mips32 module", JitCore_mips32_Methods); - m = Py_InitModule("JitCore_mips32", JitCore_mips32_Methods); - if (m == NULL) - return; + if (module == NULL) + return NULL; - JitCore_mips32_Error = PyErr_NewException("JitCore_mips32.error", NULL, NULL); - Py_INCREF(JitCore_mips32_Error); - PyModule_AddObject(m, "error", JitCore_mips32_Error); + if (PyType_Ready(&JitCpuType) < 0) + return NULL; - Py_INCREF(&JitCpuType); - PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType); + Py_INCREF(&JitCpuType); + if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0) + return NULL; + return module; } - diff --git a/miasm2/jitter/arch/JitCore_msp430.c b/miasm2/jitter/arch/JitCore_msp430.c index 69f179a4..c21296c7 100644 --- a/miasm2/jitter/arch/JitCore_msp430.c +++ b/miasm2/jitter/arch/JitCore_msp430.c @@ -2,6 +2,7 @@ #include "structmember.h" #include <stdint.h> #include <inttypes.h> +#include "../compat_py23.h" #include "../queue.h" #include "../vm_mngr.h" #include "../vm_mngr_py.h" @@ -89,6 +90,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) PyObject* dict; PyObject *d_key, *d_value = NULL; Py_ssize_t pos = 0; + char* d_key_name; uint64_t val; unsigned int i, found; @@ -97,14 +99,11 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) if(!PyDict_Check(dict)) RAISE(PyExc_TypeError, "arg must be dict"); while(PyDict_Next(dict, &pos, &d_key, &d_value)){ - if(!PyString_Check(d_key)) - RAISE(PyExc_TypeError, "key must be str"); - + PyGetStr(d_key_name, d_key); PyGetInt(d_value, val); - found = 0; for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ - if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name)) + if (strcmp(d_key_name, gpreg_dict[i].name)) continue; *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val; found = 1; @@ -113,7 +112,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) if (found) continue; - fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key)); + fprintf(stderr, "unknown key: %s\n", d_key_name); RAISE(PyExc_ValueError, "unknown reg"); } Py_INCREF(Py_None); @@ -240,11 +239,11 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args) PyGetInt(py_addr, addr); - if(!PyString_Check(py_buffer)) - RAISE(PyExc_TypeError,"arg must be str"); + if(!PyBytes_Check(py_buffer)) + RAISE(PyExc_TypeError,"arg must be bytes"); - size = PyString_Size(py_buffer); - PyString_AsStringAndSize(py_buffer, &buffer, &py_length); + size = PyBytes_Size(py_buffer); + PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length); ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size); if (ret < 0) @@ -403,8 +402,7 @@ static PyGetSetDef JitCpu_getseters[] = { static PyTypeObject JitCpuType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ + PyVarObject_HEAD_INIT(NULL, 0) "JitCore_msp430.JitCpu", /*tp_name*/ sizeof(JitCpu), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -456,26 +454,24 @@ static PyMethodDef JitCore_msp430_Methods[] = { }; -static PyObject *JitCore_msp430_Error; -PyMODINIT_FUNC -initJitCore_msp430(void) + + +MOD_INIT(JitCore_msp430) { - PyObject *m; + PyObject *module; - if (PyType_Ready(&JitCpuType) < 0) - return; + MOD_DEF(module, "JitCore_msp430", "JitCore_msp430 module", JitCore_msp430_Methods); - m = Py_InitModule("JitCore_msp430", JitCore_msp430_Methods); - if (m == NULL) - return; + if (module == NULL) + return NULL; - JitCore_msp430_Error = PyErr_NewException("JitCore_msp430.error", NULL, NULL); - Py_INCREF(JitCore_msp430_Error); - PyModule_AddObject(m, "error", JitCore_msp430_Error); + if (PyType_Ready(&JitCpuType) < 0) + return NULL; - Py_INCREF(&JitCpuType); - PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType); + Py_INCREF(&JitCpuType); + if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0) + return NULL; + return module; } - diff --git a/miasm2/jitter/arch/JitCore_ppc32.c b/miasm2/jitter/arch/JitCore_ppc32.c index e1a3fcd5..8a1bb79e 100644 --- a/miasm2/jitter/arch/JitCore_ppc32.c +++ b/miasm2/jitter/arch/JitCore_ppc32.c @@ -2,6 +2,7 @@ #include "structmember.h" #include <stdint.h> #include <inttypes.h> +#include "../compat_py23.h" #include "../queue.h" #include "../vm_mngr.h" #include "../vm_mngr_py.h" @@ -36,6 +37,7 @@ cpu_set_gpreg(JitCpu *self, PyObject *args) { PyObject *dict; PyObject *d_key, *d_value = NULL; Py_ssize_t pos = 0; + char* d_key_name; uint64_t val; unsigned int i; @@ -46,14 +48,11 @@ cpu_set_gpreg(JitCpu *self, PyObject *args) { while(PyDict_Next(dict, &pos, &d_key, &d_value)) { int found = 0; - - if(!PyString_Check(d_key)) - RAISE(PyExc_TypeError, "key must be str"); - + PyGetStr(d_key_name, d_key); PyGetInt(d_value, val); for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ - if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name)) + if (strcmp(d_key_name, gpreg_dict[i].name)) continue; *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val; found = 1; @@ -62,7 +61,7 @@ cpu_set_gpreg(JitCpu *self, PyObject *args) { if (found) continue; - fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key)); + fprintf(stderr, "unknown key: %s\n", d_key_name); RAISE(PyExc_ValueError, "unknown reg"); } @@ -192,11 +191,11 @@ vm_set_mem(JitCpu *self, PyObject *args) { PyGetInt(py_addr, addr); - if(!PyString_Check(py_buffer)) - RAISE(PyExc_TypeError,"arg must be str"); + if(!PyBytes_Check(py_buffer)) + RAISE(PyExc_TypeError,"arg must be bytes"); - size = PyString_Size(py_buffer); - PyString_AsStringAndSize(py_buffer, &buffer, &py_length); + size = PyBytes_Size(py_buffer); + PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length); ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size); if (ret < 0) @@ -276,8 +275,7 @@ static PyGetSetDef JitCpu_getseters[] = { static PyTypeObject JitCpuType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ + PyVarObject_HEAD_INIT(NULL, 0) "JitCore_ppc.JitCpu", /*tp_name*/ sizeof(JitCpu), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -319,31 +317,28 @@ static PyTypeObject JitCpuType = { -static PyMethodDef JitCore_ppc_Methods[] = { +static PyMethodDef JitCore_ppc32_Methods[] = { {"get_gpreg_offset_all", (PyCFunction)get_gpreg_offset_all, METH_NOARGS}, {NULL, NULL, 0, NULL} /* Sentinel */ }; -static PyObject *JitCore_ppc32_Error; -PyMODINIT_FUNC -initJitCore_ppc32(void) + +MOD_INIT(JitCore_ppc32) { - PyObject *m; + PyObject *module; - if (PyType_Ready(&JitCpuType) < 0) - return; + MOD_DEF(module, "JitCore_ppc32", "JitCore_ppc32 module", JitCore_ppc32_Methods); - m = Py_InitModule("JitCore_ppc32", JitCore_ppc_Methods); - if (m == NULL) - return; + if (module == NULL) + return NULL; - JitCore_ppc32_Error = PyErr_NewException("JitCore_ppc32.error", NULL, NULL); - Py_INCREF(JitCore_ppc32_Error); - PyModule_AddObject(m, "error", JitCore_ppc32_Error); + if (PyType_Ready(&JitCpuType) < 0) + return NULL; - Py_INCREF(&JitCpuType); - PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType); + Py_INCREF(&JitCpuType); + if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0) + return NULL; + return module; } - diff --git a/miasm2/jitter/arch/JitCore_x86.c b/miasm2/jitter/arch/JitCore_x86.c index a13b6881..50ce6bd5 100644 --- a/miasm2/jitter/arch/JitCore_x86.c +++ b/miasm2/jitter/arch/JitCore_x86.c @@ -2,6 +2,7 @@ #include "structmember.h" #include <stdint.h> #include <inttypes.h> +#include "../compat_py23.h" #include "../queue.h" #include "../vm_mngr.h" #include "../vm_mngr_py.h" @@ -10,6 +11,7 @@ #include "../op_semantics.h" #include "JitCore_x86.h" + vm_cpu_t ref_arch_regs; reg_dict gpreg_dict[] = { @@ -161,13 +163,11 @@ PyObject* cpu_get_gpreg(JitCpu* self) } - - - PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) { PyObject* dict; PyObject *d_key, *d_value = NULL; + char* d_key_name; Py_ssize_t pos = 0; uint64_t val; unsigned int i, found; @@ -177,12 +177,10 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) if(!PyDict_Check(dict)) RAISE(PyExc_TypeError, "arg must be dict"); while(PyDict_Next(dict, &pos, &d_key, &d_value)){ - if(!PyString_Check(d_key)) - RAISE(PyExc_TypeError, "key must be str"); - + PyGetStr(d_key_name, d_key); found = 0; for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ - if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name)) + if (strcmp(d_key_name, gpreg_dict[i].name)) continue; found = 1; switch (gpreg_dict[i].size) { @@ -213,7 +211,16 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) PyObject* cst_ffffffff; uint64_t tmp; - /* Ensure py_long is a PyLong */ + +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(py_long)){ + /* Already PyLong */ + /* Increment ref as we will decement it next */ + Py_INCREF(py_long); + } else { + RAISE(PyExc_TypeError,"arg must be int"); + } +#else if (PyInt_Check(py_long)){ tmp = (uint64_t)PyInt_AsLong(py_long); py_long = PyLong_FromLong((long)tmp); @@ -225,6 +232,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) else{ RAISE(PyExc_TypeError,"arg must be int"); } +#endif cst_ffffffff = PyLong_FromLong(0xffffffff); @@ -254,7 +262,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) if (found) continue; - fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key)); + fprintf(stderr, "unknown key: %s\n", d_key_name); RAISE(PyExc_ValueError, "unknown reg"); } Py_INCREF(Py_None); @@ -437,7 +445,7 @@ PyObject* cpu_get_segm_base(JitCpu* self, PyObject* args) if (!PyArg_ParseTuple(args, "O", &item1)) RAISE(PyExc_TypeError,"Cannot parse arguments"); PyGetInt(item1, segm_num); - v = PyInt_FromLong((long)(((vm_cpu_t*)self->cpu)->segm_base[segm_num])); + v = PyLong_FromLong((long)(((vm_cpu_t*)self->cpu)->segm_base[segm_num])); return v; } @@ -484,11 +492,11 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args) PyGetInt(py_addr, addr); - if(!PyString_Check(py_buffer)) - RAISE(PyExc_TypeError,"arg must be str"); + if(!PyBytes_Check(py_buffer)) + RAISE(PyExc_TypeError,"arg must be bytes"); - size = PyString_Size(py_buffer); - PyString_AsStringAndSize(py_buffer, &buffer, &py_length); + size = PyBytes_Size(py_buffer); + PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length); ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size); if (ret < 0) @@ -865,9 +873,8 @@ static PyGetSetDef JitCpu_getseters[] = { static PyTypeObject JitCpuType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "JitCore_x86.JitCpu", /*tp_name*/ + PyVarObject_HEAD_INIT(NULL, 0) + "JitCore_x86.JitCpu", /*tp_name*/ sizeof(JitCpu), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)JitCpu_dealloc,/*tp_dealloc*/ @@ -918,47 +925,22 @@ static PyMethodDef JitCore_x86_Methods[] = { }; -static PyObject *JitCore_x86_Error; -PyMODINIT_FUNC -initJitCore_x86(void) +MOD_INIT(JitCore_x86) { - PyObject *m; + PyObject *module; - if (PyType_Ready(&JitCpuType) < 0) - return; + MOD_DEF(module, "JitCore_x86", "JitCore_x86 module", JitCore_x86_Methods); - m = Py_InitModule("JitCore_x86", JitCore_x86_Methods); - if (m == NULL) - return; + if (module == NULL) + return NULL; - JitCore_x86_Error = PyErr_NewException("JitCore_x86.error", NULL, NULL); - Py_INCREF(JitCore_x86_Error); - PyModule_AddObject(m, "error", JitCore_x86_Error); + if (PyType_Ready(&JitCpuType) < 0) + return NULL; - Py_INCREF(&JitCpuType); - PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType); + Py_INCREF(&JitCpuType); + if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0) + return NULL; + return module; } - - - - - - - - - - - - - - - - - - - - - - diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py index 65df0c03..bdd9e570 100644 --- a/miasm2/jitter/codegen.py +++ b/miasm2/jitter/codegen.py @@ -2,6 +2,10 @@ Module to generate C code for a given native @block """ +from builtins import zip + +from future.utils import viewitems, viewvalues + from miasm2.expression.expression import Expr, ExprId, ExprLoc, ExprInt, \ ExprMem, ExprCond, LocKey from miasm2.ir.ir import IRBlock, AssignBlock @@ -238,18 +242,18 @@ class CGen(object): prefetchers = self.get_mem_prefetch(assignblk) - for expr, prefetcher in sorted(prefetchers.iteritems()): + for expr, prefetcher in viewitems(prefetchers): str_src = self.id_to_c(expr) str_dst = self.id_to_c(prefetcher) c_prefetch.append('%s = %s;' % (str_dst, str_src)) - for var in prefetchers.itervalues(): + for var in viewvalues(prefetchers): if var.size <= self.translator.NATIVE_INT_MAX_SIZE: c_var.append("uint%d_t %s;" % (var.size, var)) else: c_var.append("bn_t %s; // %d" % (var, var.size)) - for dst, src in sorted(assignblk.iteritems()): + for dst, src in viewitems(assignblk): src = src.replace_expr(prefetchers) if dst == self.ir_arch.IRDst: pass @@ -294,7 +298,7 @@ class CGen(object): else: raise ValueError("Unknown dst") - for dst, new_dst in dst_var.iteritems(): + for dst, new_dst in viewitems(dst_var): if dst == self.ir_arch.IRDst: continue @@ -450,7 +454,7 @@ class CGen(object): out.append('switch(DST_case) {') stopcase = False - for dst, index in sorted(dst2index.iteritems(), key=lambda lblindex: lblindex[1]): + for dst, index in sorted(viewitems(dst2index), key=lambda lblindex: lblindex[1]): if index == -1: # Handle '-1' case only once if not stopcase: diff --git a/miasm2/jitter/compat_py23.h b/miasm2/jitter/compat_py23.h new file mode 100644 index 00000000..bc66d80b --- /dev/null +++ b/miasm2/jitter/compat_py23.h @@ -0,0 +1,87 @@ +#ifndef __COMPAT_PY23_H__ +#define __COMPAT_PY23_H__ + + + +#if PY_MAJOR_VERSION >= 3 +#define PyGetInt(item, value) \ + if (PyLong_Check(item)){ \ + value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ + } \ + else{ \ + RAISE(PyExc_TypeError,"arg must be int"); \ + } + + +#define PyGetInt_retneg(item, value) \ + if (PyLong_Check(item)){ \ + value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ + } \ + else{ \ + PyErr_SetString(PyExc_TypeError, "Arg must be int"); \ + return -1; \ + } + +#define PyGetStr(dest, name) \ + if (!PyUnicode_Check((name))) \ + RAISE(PyExc_TypeError,"Page name must be bytes"); \ + (dest) = PyUnicode_AsUTF8((name)) + + + +#else +#define PyGetInt(item, value) \ + if (PyInt_Check(item)){ \ + value = (uint64_t)PyInt_AsLong(item); \ + } \ + else if (PyLong_Check(item)){ \ + value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ + } \ + else{ \ + RAISE(PyExc_TypeError,"arg must be int"); \ + } + + +#define PyGetInt_retneg(item, value) \ + if (PyInt_Check(item)){ \ + value = (uint64_t)PyLong_AsLong(item); \ + } \ + else if (PyLong_Check(item)){ \ + value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ + } \ + else{ \ + PyErr_SetString(PyExc_TypeError, "Arg must be int"); \ + return -1; \ + } \ + + +#define PyGetStr(dest, name) \ + if (!PyString_Check((name))) \ + RAISE(PyExc_TypeError,"Page name must be bytes"); \ + (dest) = PyString_AsString((name)) + +#endif + + + +#if PY_MAJOR_VERSION >= 3 + +#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void) + +#define MOD_DEF(ob, name, doc, methods) \ + static struct PyModuleDef moduledef = { \ + PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \ + ob = PyModule_Create(&moduledef); +#else + +#define MOD_INIT(name) PyMODINIT_FUNC init##name(void) + +#define MOD_DEF(ob, name, doc, methods) \ + ob = Py_InitModule3(name, methods, doc); +#endif + + + + + +#endif diff --git a/miasm2/jitter/emulatedsymbexec.py b/miasm2/jitter/emulatedsymbexec.py index 78c02fb1..3ccce522 100644 --- a/miasm2/jitter/emulatedsymbexec.py +++ b/miasm2/jitter/emulatedsymbexec.py @@ -1,3 +1,4 @@ +from miasm2.core.utils import decode_hex, encode_hex import miasm2.expression.expression as m2_expr from miasm2.ir.symbexec import SymbolicExecutionEngine @@ -43,14 +44,16 @@ class EmulatedSymbExec(SymbolicExecutionEngine): if not addr.is_int(): return super(EmulatedSymbExec, self).mem_read(expr_mem) addr = int(addr) - size = expr_mem.size / 8 + size = expr_mem.size // 8 value = self.cpu.get_mem(addr, size) if self.vm.is_little_endian(): value = value[::-1] self.vm.add_mem_read(addr, size) - return m2_expr.ExprInt(int(value.encode("hex"), 16), - expr_mem.size) + return m2_expr.ExprInt( + int(encode_hex(value), 16), + expr_mem.size + ) def mem_write(self, dest, data): """Memory read wrapper for symbolic execution @@ -65,10 +68,10 @@ class EmulatedSymbExec(SymbolicExecutionEngine): # Format information addr = dest.ptr.arg.arg - size = data.size / 8 + size = data.size // 8 content = hex(to_write).replace("0x", "").replace("L", "") content = "0" * (size * 2 - len(content)) + content - content = content.decode("hex") + content = decode_hex(content) if self.vm.is_little_endian(): content = content[::-1] diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py index 78e27244..33efdfd9 100644 --- a/miasm2/jitter/jitcore.py +++ b/miasm2/jitter/jitcore.py @@ -1,3 +1,4 @@ +from __future__ import print_function # # Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> # @@ -18,6 +19,8 @@ from hashlib import md5 import warnings +from future.utils import viewvalues + from miasm2.core.asmblock import disasmEngine, AsmBlockBad from miasm2.core.interval import interval from miasm2.core.utils import BoundedDict @@ -141,7 +144,7 @@ class JitCore(object): return cur_block # Logging if self.log_newbloc: - print cur_block.to_string(self.mdis.loc_db) + print(cur_block.to_string(self.mdis.loc_db)) # Update label -> block self.loc_key_to_block[cur_block.loc_key] = cur_block @@ -222,7 +225,7 @@ class JitCore(object): # Find concerned blocks modified_blocks = set() - for block in self.loc_key_to_block.values(): + for block in viewvalues(self.loc_key_to_block): if not block.lines: continue if block.ad_max <= ad1 or block.ad_min >= ad2: @@ -282,13 +285,17 @@ class JitCore(object): Build a hash of the block @block @block: asmblock """ - block_raw = "".join(line.b for line in block.lines) + block_raw = b"".join(line.b for line in block.lines) offset = self.ir_arch.loc_db.get_location_offset(block.loc_key) - block_hash = md5("%X_%s_%s_%s_%s" % (offset, - self.arch_name, - self.log_mn, - self.log_regs, - block_raw)).hexdigest() + block_hash = md5( + b"%X_%s_%s_%s_%s" % ( + offset, + self.arch_name.encode(), + b'\x01' if self.log_mn else b'\x00', + b'\x01' if self.log_regs else b'\x00', + block_raw + ) + ).hexdigest() return block_hash @property diff --git a/miasm2/jitter/jitcore_cc_base.py b/miasm2/jitter/jitcore_cc_base.py index 7853816a..997d6330 100644 --- a/miasm2/jitter/jitcore_cc_base.py +++ b/miasm2/jitter/jitcore_cc_base.py @@ -3,6 +3,7 @@ import os import tempfile import platform +import sysconfig from distutils.sysconfig import get_python_inc from miasm2.jitter.jitcore import JitCore @@ -28,7 +29,7 @@ def gen_core(arch, attrib): return txt -class myresolver: +class myresolver(object): def __init__(self, offset): self.offset = offset @@ -37,7 +38,7 @@ class myresolver: return "return PyLong_FromUnsignedLongLong(0x%X);" % self.offset -class resolver: +class resolver(object): def __init__(self): self.resolvers = keydefaultdict(myresolver) @@ -57,7 +58,7 @@ class JitCore_Cc_Base(JitCore): self.states = {} self.tempdir = os.path.join(tempfile.gettempdir(), "miasm_cache") try: - os.mkdir(self.tempdir, 0755) + os.mkdir(self.tempdir, 0o755) except OSError: pass if not os.access(self.tempdir, os.R_OK | os.W_OK): @@ -72,12 +73,23 @@ class JitCore_Cc_Base(JitCore): def load(self): lib_dir = os.path.dirname(os.path.realpath(__file__)) - ext = ".so" if not is_win else ".lib" - libs = [os.path.join(lib_dir, "VmMngr" + ext), - os.path.join(lib_dir, "arch", "JitCore_%s%s" % (self.ir_arch.arch.name, ext))] - - include_files = [os.path.dirname(__file__), - get_python_inc()] + ext = sysconfig.get_config_var('EXT_SUFFIX') + if ext is None: + ext = ".so" if not is_win else ".lib" + + libs = [ + os.path.join(lib_dir, "VmMngr" + ext), + os.path.join( + lib_dir, + "arch", + "JitCore_%s%s" % (self.ir_arch.arch.name, ext) + ) + ] + + include_files = [ + os.path.dirname(__file__), + get_python_inc() + ] self.include_files = include_files self.libs = libs @@ -94,7 +106,11 @@ class JitCore_Cc_Base(JitCore): @irblocks: list of irblocks """ f_declaration = '_MIASM_EXPORT int %s(block_id * BlockDst, JitCpu* jitcpu)' % self.FUNCNAME - out = self.codegen.gen_c(block, log_mn=self.log_mn, log_regs=self.log_regs) + out = self.codegen.gen_c( + block, + log_mn=self.log_mn, + log_regs=self.log_regs + ) out = [f_declaration + '{'] + out + ['}\n'] c_code = out diff --git a/miasm2/jitter/jitcore_gcc.py b/miasm2/jitter/jitcore_gcc.py index 238f2239..5fd54c3d 100644 --- a/miasm2/jitter/jitcore_gcc.py +++ b/miasm2/jitter/jitcore_gcc.py @@ -5,9 +5,9 @@ import tempfile import ctypes import _ctypes import platform +import sysconfig from subprocess import check_call from distutils.sysconfig import get_python_inc - from miasm2.jitter import Jitgcc from miasm2.jitter.jitcore_cc_base import JitCore_Cc_Base, gen_core @@ -45,7 +45,9 @@ class JitCore_Gcc(JitCore_Cc_Base): @block: block to jit """ block_hash = self.hash_block(block) - ext = ".so" if not is_win else ".pyd" + ext = sysconfig.get_config_var('EXT_SUFFIX') + if ext is None: + ext = ".so" if not is_win else ".pyd" fname_out = os.path.join(self.tempdir, "%s%s" % (block_hash, ext)) if not os.access(fname_out, os.R_OK | os.X_OK): @@ -53,7 +55,7 @@ class JitCore_Gcc(JitCore_Cc_Base): # Create unique C file fdesc, fname_in = tempfile.mkstemp(suffix=".c") - os.write(fdesc, func_code) + os.write(fdesc, func_code.encode()) os.close(fdesc) # Create unique SO file @@ -63,7 +65,14 @@ class JitCore_Gcc(JitCore_Cc_Base): inc_dir = ["-I%s" % inc for inc in self.include_files] libs = ["%s" % lib for lib in self.libs] if is_win: - libs.append(os.path.join(get_python_inc(), "..", "libs", "python27.lib")) + libs.append( + os.path.join( + get_python_inc(), + "..", + "libs", + "python27.lib" + ) + ) cl = [ "cl", "/nologo", "/W3", "/MP", "/Od", "/DNDEBUG", "/D_WINDOWS", "/Gm-", "/EHsc", @@ -76,26 +85,44 @@ class JitCore_Gcc(JitCore_Cc_Base): basename_out, _ = os.path.splitext(fname_tmp) basename_in, _ = os.path.splitext(os.path.basename(fname_in)) for ext in ('.obj', '.exp', '.lib'): - artifact_out_path = os.path.join(out_dir, basename_out + ext) + artifact_out_path = os.path.join( + out_dir, + basename_out + ext + ) if os.path.isfile(artifact_out_path): os.remove(artifact_out_path) - artifact_in_path = os.path.join(out_dir, basename_in + ext) + artifact_in_path = os.path.join( + out_dir, + basename_in + ext + ) if os.path.isfile(artifact_in_path): os.remove(artifact_in_path) else: - args = ["cc", "-O3", "-shared", "-fPIC", fname_in, "-o", fname_tmp] + inc_dir + libs + args = [ + "cc", + "-O3", + "-shared", + "-fPIC", + fname_in, + "-o", + fname_tmp + ] + inc_dir + libs check_call(args) # Move temporary file to final file try: os.rename(fname_tmp, fname_out) - except WindowsError, e: - # On Windows, os.rename works slightly differently than on Linux; quoting the documentation: - # "On Unix, if dst exists and is a file, it will be replaced silently if the user has permission. - # The operation may fail on some Unix flavors if src and dst are on different filesystems. - # If successful, the renaming will be an atomic operation (this is a POSIX requirement). - # On Windows, if dst already exists, OSError will be raised even if it is a file; there may be no way - # to implement an atomic rename when dst names an existing file." + except WindowsError as e: + # On Windows, os.rename works slightly differently than on + # Linux; quoting the documentation: + # "On Unix, if dst exists and is a file, it will be replaced + # silently if the user has permission. The operation may fail + # on some Unix flavors if src and dst are on different + # filesystems. If successful, the renaming will be an atomic + # operation (this is a POSIX requirement). On Windows, if dst + # already exists, OSError will be raised even if it is a file; + # there may be no way to implement an atomic rename when dst + # names an existing file." # [Error 183] Cannot create a file when that file already exists if e.winerror != 183: raise diff --git a/miasm2/jitter/jitcore_llvm.py b/miasm2/jitter/jitcore_llvm.py index 463e476a..d017e122 100644 --- a/miasm2/jitter/jitcore_llvm.py +++ b/miasm2/jitter/jitcore_llvm.py @@ -1,32 +1,40 @@ +from __future__ import print_function import os import importlib import tempfile +import sysconfig from miasm2.jitter.llvmconvert import * import miasm2.jitter.jitcore as jitcore -import Jitllvm +from miasm2.jitter import Jitllvm import platform +is_win = platform.system() == "Windows" + class JitCore_LLVM(jitcore.JitCore): "JiT management, using LLVM as backend" # Architecture dependent libraries - arch_dependent_libs = {"x86": "JitCore_x86", - "arm": "JitCore_arm", - "msp430": "JitCore_msp430", - "mips32": "JitCore_mips32", - "aarch64": "JitCore_aarch64", - "ppc32": "JitCore_ppc32", + arch_dependent_libs = { + "x86": "JitCore_x86", + "arm": "JitCore_arm", + "msp430": "JitCore_msp430", + "mips32": "JitCore_mips32", + "aarch64": "JitCore_aarch64", + "ppc32": "JitCore_ppc32", } def __init__(self, ir_arch, bin_stream): super(JitCore_LLVM, self).__init__(ir_arch, bin_stream) - self.options.update({"safe_mode": True, # Verify each function - "optimise": True, # Optimise functions - "log_func": False, # Print LLVM functions - "log_assembly": False, # Print assembly executed - }) + self.options.update( + { + "safe_mode": True, # Verify each function + "optimise": True, # Optimise functions + "log_func": False, # Print LLVM functions + "log_assembly": False, # Print assembly executed + } + ) self.exec_wrapper = Jitllvm.llvm_exec_block self.ir_arch = ir_arch @@ -34,7 +42,7 @@ class JitCore_LLVM(jitcore.JitCore): # Cache temporary dir self.tempdir = os.path.join(tempfile.gettempdir(), "miasm_cache") try: - os.mkdir(self.tempdir, 0755) + os.mkdir(self.tempdir, 0o755) except OSError: pass if not os.access(self.tempdir, os.R_OK | os.W_OK): @@ -49,10 +57,13 @@ class JitCore_LLVM(jitcore.JitCore): # Get architecture dependent Jitcore library (if any) lib_dir = os.path.dirname(os.path.realpath(__file__)) lib_dir = os.path.join(lib_dir, 'arch') - ext = '.so' if platform.system() != 'Windows' else '.pyd' + ext = sysconfig.get_config_var('EXT_SUFFIX') + if ext is None: + ext = ".so" if not is_win else ".pyd" try: jit_lib = os.path.join( - lib_dir, self.arch_dependent_libs[self.ir_arch.arch.name] + ext) + lib_dir, self.arch_dependent_libs[self.ir_arch.arch.name] + ext + ) libs_to_load.append(jit_lib) except KeyError: pass @@ -103,9 +114,9 @@ class JitCore_LLVM(jitcore.JitCore): # Log if self.options["log_func"] is True: - print func + print(func) if self.options["log_assembly"] is True: - print func.get_assembly() + print(func.get_assembly()) # Use propagate the cache filename self.context.set_cache_filename(func, fname_out) diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py index fdd5c2ae..4262c334 100644 --- a/miasm2/jitter/jitcore_python.py +++ b/miasm2/jitter/jitcore_python.py @@ -1,3 +1,5 @@ +from __future__ import print_function +from builtins import zip import miasm2.jitter.jitcore as jitcore from miasm2.expression.expression import ExprInt, ExprLoc import miasm2.jitter.csts as csts @@ -111,10 +113,10 @@ class JitCore_Python(jitcore.JitCore): if index == 0: # Pre code if instr_attrib.log_mn: - print "%.8X %s" % ( + print("%.8X %s" % ( instr_attrib.instr.offset, instr_attrib.instr.to_string(loc_db) - ) + )) # Exec IRBlock instr = instr_attrib.instr diff --git a/miasm2/jitter/jitload.py b/miasm2/jitter/jitload.py index 59c7ac97..3f3cf10f 100644 --- a/miasm2/jitter/jitload.py +++ b/miasm2/jitter/jitload.py @@ -1,9 +1,10 @@ - import logging import warnings from functools import wraps from collections import Sequence, namedtuple +from future.utils import viewitems + from miasm2.jitter.csts import * from miasm2.core.utils import * from miasm2.core.bin_stream import bin_stream_vm @@ -42,12 +43,15 @@ def named_arguments(func): ret_ad, arg_vals = func(self, len(args)) arg_vals = namedtuple("args", args)(*arg_vals) # func_name(arguments) return address - log_func.info('%s(%s) ret addr: %s', - get_caller_name(1), - ', '.join("%s=0x%x" % (field, value) - for field, value in arg_vals._asdict( - ).iteritems()), - hex(ret_ad)) + log_func.info( + '%s(%s) ret addr: %s', + get_caller_name(1), + ', '.join( + "%s=0x%x" % (field, value) + for field, value in viewitems(arg_vals._asdict()) + ), + hex(ret_ad) + ) return ret_ad, namedtuple("args", args)(*arg_vals) else: ret_ad, arg_vals = func(self, args) @@ -86,7 +90,7 @@ class CallbackHandler(object): Return the list of empty keys (removed)""" to_check = set() - for key, cb_list in self.callbacks.items(): + for key, cb_list in viewitems(self.callbacks): try: cb_list.remove(callback) to_check.add(key) @@ -145,7 +149,7 @@ class CallbackHandlerBitflag(CallbackHandler): yield res -class ExceptionHandle(): +class ExceptionHandle(object): "Return type for exception handler" @@ -326,7 +330,7 @@ class Jitter(object): return self.jit.run_at( self.cpu, pc, - set(self.breakpoints_handler.callbacks.keys()) + set(self.breakpoints_handler.callbacks) ) def runiter_once(self, pc): @@ -398,7 +402,7 @@ class Jitter(object): while self.run: try: - return self.run_iterator.next() + return next(self.run_iterator) except StopIteration: pass @@ -411,7 +415,9 @@ class Jitter(object): def init_stack(self): self.vm.add_memory_page( - self.stack_base, PAGE_READ | PAGE_WRITE, "\x00" * self.stack_size, + self.stack_base, + PAGE_READ | PAGE_WRITE, + b"\x00" * self.stack_size, "Stack") sp = self.arch.getsp(self.attrib) setattr(self.cpu, sp.name, self.stack_base + self.stack_size) @@ -430,7 +436,7 @@ class Jitter(object): l = 0 tmp = addr while ((max_char is None or l < max_char) and - self.vm.get_mem(tmp, 1) != "\x00"): + self.vm.get_mem(tmp, 1) != b"\x00"): tmp += 1 l += 1 return self.vm.get_mem(addr, l) @@ -442,21 +448,21 @@ class Jitter(object): l = 0 tmp = addr while ((max_char is None or l < max_char) and - self.vm.get_mem(tmp, 2) != "\x00\x00"): + self.vm.get_mem(tmp, 2) != b"\x00\x00"): tmp += 2 l += 2 s = self.vm.get_mem(addr, l) - s = s[::2] # TODO: real unicode decoding + s = s.decode("utf-16le") return s def set_str_ansi(self, addr, s): """Set an ansi string in memory""" - s = s + "\x00" + s = s + b"\x00" self.vm.set_mem(addr, s) def set_str_unic(self, addr, s): """Set an unicode string in memory""" - s = "\x00".join(list(s)) + '\x00' * 3 + s = b"\x00".join(list(s)) + b'\x00' * 3 self.vm.set_mem(addr, s) @staticmethod @@ -492,7 +498,11 @@ class Jitter(object): user_globals = {} self.libs = libs - self.user_globals = user_globals + out = {} + for name, func in viewitems(user_globals): + name = force_bytes(name) + out[name] = func + self.user_globals = out for f_addr in libs.fad2cname: self.handle_function(f_addr) diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py index fd32001c..bea8cd36 100644 --- a/miasm2/jitter/llvmconvert.py +++ b/miasm2/jitter/llvmconvert.py @@ -11,9 +11,15 @@ # # +from builtins import zip +from builtins import range import os from llvmlite import binding as llvm from llvmlite import ir as llvm_ir +from builtins import int as int_types + +from future.utils import viewitems, viewvalues + from miasm2.expression.expression import ExprId, ExprInt, ExprMem, ExprSlice, \ ExprCond, ExprLoc, ExprOp, ExprCompose, LocKey, Expr, \ TOK_EQUAL, \ @@ -67,7 +73,7 @@ class LLVMType(llvm_ir.Type): return precision -class LLVMContext(): +class LLVMContext(object): "Context for llvm binding. Stand for a LLVM Module" @@ -139,7 +145,7 @@ class LLVMContext(): def add_fc(self, fc, readonly=False): "Add function into known_fc" - for name, detail in fc.iteritems(): + for name, detail in viewitems(fc): fnty = llvm_ir.FunctionType(detail["ret"], detail["args"]) fn = llvm_ir.Function(self.mod, fnty, name=name) if readonly: @@ -444,8 +450,10 @@ class LLVMContext_JIT(LLVMContext): self.add_shared_library(lib_fname) # Activate cache - self.exec_engine.set_object_cache(self.cache_notify, - self.cache_getbuffer) + self.exec_engine.set_object_cache( + self.cache_notify, + self.cache_getbuffer + ) def set_cache_filename(self, func, fname_out): "Set the filename @fname_out to use for cache for @func" @@ -473,16 +481,20 @@ class LLVMContext_IRCompilation(LLVMContext): """Perform a memory lookup at @addr of size @size (in bit)""" builder = func.builder int_size = LLVMType.IntType(size) - ptr_casted = builder.inttoptr(addr, - llvm_ir.PointerType(int_size)) + ptr_casted = builder.inttoptr( + addr, + llvm_ir.PointerType(int_size) + ) return builder.load(ptr_casted) def memory_write(self, func, addr, size, value): """Perform a memory write at @addr of size @size (in bit) with LLVM IR @value""" builder = func.builder int_size = LLVMType.IntType(size) - ptr_casted = builder.inttoptr(addr, - llvm_ir.PointerType(int_size)) + ptr_casted = builder.inttoptr( + addr, + llvm_ir.PointerType(int_size) + ) return builder.store(value, ptr_casted) @@ -504,8 +516,9 @@ class LLVMFunction(object): ## Add the size as first argument op_translate_with_size = {} ## Add the size as suffix - op_translate_with_suffix_size = {'bcdadd': 'bcdadd', - 'bcdadd_cf': 'bcdadd_cf', + op_translate_with_suffix_size = { + 'bcdadd': 'bcdadd', + 'bcdadd_cf': 'bcdadd_cf', } def __init__(self, llvm_context, name="fc", new_module=True): @@ -582,12 +595,20 @@ class LLVMFunction(object): offset = self.llvm_context.vmcpu[name] # Pointer cast - ptr = builder.gep(self.local_vars["vmcpu"], - [llvm_ir.Constant(LLVMType.IntType(), - offset)]) + ptr = builder.gep( + self.local_vars["vmcpu"], + [ + llvm_ir.Constant( + LLVMType.IntType(), + offset + ) + ] + ) pointee_type = LLVMType.IntType(expr.size) - ptr_casted = builder.bitcast(ptr, - llvm_ir.PointerType(pointee_type)) + ptr_casted = builder.bitcast( + ptr, + llvm_ir.PointerType(pointee_type) + ) # Store in cache self.local_vars_pointers[name] = ptr_casted @@ -612,7 +633,10 @@ class LLVMFunction(object): def get_basic_block_by_loc_key(self, loc_key): "Return the bbl corresponding to label, None otherwise" - return self.name2bbl.get(self.llvm_context.canonize_label_name(loc_key), None) + return self.name2bbl.get( + self.llvm_context.canonize_label_name(loc_key), + None + ) def global_constant(self, name, value): """ @@ -658,10 +682,15 @@ class LLVMFunction(object): count = 0 while "%s_%d" % (base_name, count) in self.mod.globals: count += 1 - global_fmt = self.global_constant("%s_%d" % (base_name, count), - fmt_bytes) - fnty = llvm_ir.FunctionType(llvm_ir.IntType(32), [cstring], - var_arg=True) + global_fmt = self.global_constant( + "%s_%d" % (base_name, count), + fmt_bytes + ) + fnty = llvm_ir.FunctionType( + llvm_ir.IntType(32), + [cstring], + var_arg=True + ) # Insert printf() fn = mod.globals.get('printf', None) if fn is None: @@ -692,7 +721,10 @@ class LLVMFunction(object): "Init the function" # Build type for fc signature - fc_type = llvm_ir.FunctionType(self.ret_type, [k[1] for k in self.my_args]) + fc_type = llvm_ir.FunctionType( + self.ret_type, + [k[1] for k in self.my_args] + ) # Add fc in module try: @@ -741,7 +773,9 @@ class LLVMFunction(object): return ret if expr.is_loc(): - offset = self.llvm_context.ir_arch.loc_db.get_location_offset(expr.loc_key) + offset = self.llvm_context.ir_arch.loc_db.get_location_offset( + expr.loc_key + ) ret = llvm_ir.Constant(LLVMType.IntType(expr.size), offset) self.update_cache(expr, ret) return ret @@ -785,7 +819,12 @@ class LLVMFunction(object): casted_args = [] for i, arg in enumerate(args): if arg.type.width < fc_ptr.args[i].type.width: - casted_args.append(builder.zext(arg, fc_ptr.args[i].type)) + casted_args.append( + builder.zext( + arg, + fc_ptr.args[i].type + ) + ) else: casted_args.append(arg) ret = builder.call(fc_ptr, casted_args) @@ -810,8 +849,10 @@ class LLVMFunction(object): assert len(expr.args) == 1 arg = self.add_ir(expr.args[0]) truncated = builder.trunc(arg, LLVMType.IntType(8)) - bitcount = builder.call(self.mod.get_global("llvm.ctpop.i8"), - [truncated]) + bitcount = builder.call( + self.mod.get_global("llvm.ctpop.i8"), + [truncated] + ) ret = builder.not_(builder.trunc(bitcount, LLVMType.IntType(1))) self.update_cache(expr, ret) return ret @@ -824,16 +865,20 @@ class LLVMFunction(object): "cnttrailzeros": "cttz", }[op] func_llvm_name = "llvm.%s.i%d" % (func_name, expr.size) - func_sig = {func_llvm_name: { - "ret": LLVMType.IntType(expr.size), - "args": [LLVMType.IntType(expr.args[0].size)] - }} + func_sig = { + func_llvm_name: { + "ret": LLVMType.IntType(expr.size), + "args": [LLVMType.IntType(expr.args[0].size)] + } + } try: self.mod.get_global(func_llvm_name) except KeyError: self.llvm_context.add_fc(func_sig, readonly=True) - ret = builder.call(self.mod.get_global(func_llvm_name), - [arg]) + ret = builder.call( + self.mod.get_global(func_llvm_name), + [arg] + ) self.update_cache(expr, ret) return ret @@ -867,12 +912,19 @@ class LLVMFunction(object): casted_args = [] for i, arg in enumerate(args, 1): if arg.type.width < fc_ptr.args[i].type.width: - casted_args.append(builder.zext(arg, fc_ptr.args[i].type)) + casted_args.append( + builder.zext( + arg, + fc_ptr.args[i].type + ) + ) else: casted_args.append(arg) - ret = builder.call(fc_ptr, - [self.local_vars["jitcpu"]] + casted_args) + ret = builder.call( + fc_ptr, + [self.local_vars["jitcpu"]] + casted_args + ) if ret.type.width > expr.size: ret = builder.trunc(ret, LLVMType.IntType(expr.size)) self.update_cache(expr, ret) @@ -905,11 +957,14 @@ class LLVMFunction(object): if op in unsigned_cmps: op = unsigned_cmps[op] args = [self.add_ir(arg) for arg in expr.args] - ret = builder.select(builder.icmp_unsigned(op, - args[0], - args[1]), - llvm_ir.IntType(expr.size)(1), - llvm_ir.IntType(expr.size)(0)) + ret = builder.select( + builder.icmp_unsigned(op, + args[0], + args[1] + ), + llvm_ir.IntType(expr.size)(1), + llvm_ir.IntType(expr.size)(0) + ) self.update_cache(expr, ret) return ret @@ -919,8 +974,11 @@ class LLVMFunction(object): count = self.add_ir(expr.args[1]) value = self.add_ir(expr.args[0]) itype = LLVMType.IntType(expr.size) - cond_ok = self.builder.icmp_unsigned("<", count, - itype(expr.size)) + cond_ok = self.builder.icmp_unsigned( + "<", + count, + itype(expr.size) + ) zero = itype(0) if op == ">>": callback = builder.lshr @@ -932,8 +990,11 @@ class LLVMFunction(object): cond_neg = self.builder.icmp_signed("<", value, zero) zero = self.builder.select(cond_neg, itype(-1), zero) - ret = self.builder.select(cond_ok, callback(value, count), - zero) + ret = self.builder.select( + cond_ok, + callback(value, count), + zero + ) self.update_cache(expr, ret) return ret @@ -948,8 +1009,10 @@ class LLVMFunction(object): # As shift of expr_size is undefined, we urem the shifters shift = builder.urem(count, expr_size) - shift_inv = builder.urem(builder.sub(expr_size, shift), - expr_size) + shift_inv = builder.urem( + builder.sub(expr_size, shift), + expr_size + ) if op == '<<<': part_a = builder.shl(value, shift) @@ -1045,12 +1108,16 @@ class LLVMFunction(object): # Apply the correct func if expr.size == 32: arg = builder.bitcast(arg, llvm_ir.FloatType()) - ret = builder.call(self.mod.get_global("llvm.%s.f32" % op), - [arg]) + ret = builder.call( + self.mod.get_global("llvm.%s.f32" % op), + [arg] + ) elif expr.size == 64: arg = builder.bitcast(arg, llvm_ir.DoubleType()) - ret = builder.call(self.mod.get_global("llvm.%s.f64" % op), - [arg]) + ret = builder.call( + self.mod.get_global("llvm.%s.f64" % op), + [arg] + ) else: raise RuntimeError("Unsupported precision: %x", expr.size) @@ -1164,22 +1231,27 @@ class LLVMFunction(object): # Remove trailing bits if expr.start != 0: - to_shr = llvm_ir.Constant(LLVMType.IntType(expr.arg.size), - expr.start) - shred = builder.lshr(src, - to_shr) + to_shr = llvm_ir.Constant( + LLVMType.IntType(expr.arg.size), + expr.start + ) + shred = builder.lshr(src, to_shr) else: shred = src # Remove leading bits - to_and = llvm_ir.Constant(LLVMType.IntType(expr.arg.size), - (1 << (expr.stop - expr.start)) - 1) + to_and = llvm_ir.Constant( + LLVMType.IntType(expr.arg.size), + (1 << (expr.stop - expr.start)) - 1 + ) anded = builder.and_(shred, to_and) # Cast into e.size - ret = builder.trunc(anded, - LLVMType.IntType(expr.size)) + ret = builder.trunc( + anded, + LLVMType.IntType(expr.size) + ) self.update_cache(expr, ret) return ret @@ -1192,17 +1264,23 @@ class LLVMFunction(object): for start, src in expr.iter_args(): # src & size src = self.add_ir(src) - src_casted = builder.zext(src, - LLVMType.IntType(expr.size)) - to_and = llvm_ir.Constant(LLVMType.IntType(expr.size), - (1 << src.type.width) - 1) + src_casted = builder.zext( + src, + LLVMType.IntType(expr.size) + ) + to_and = llvm_ir.Constant( + LLVMType.IntType(expr.size), + (1 << src.type.width) - 1 + ) anded = builder.and_(src_casted, to_and) if (start != 0): # result << start - to_shl = llvm_ir.Constant(LLVMType.IntType(expr.size), - start) + to_shl = llvm_ir.Constant( + LLVMType.IntType(expr.size), + start + ) shled = builder.shl(anded, to_shl) final = shled else: @@ -1213,7 +1291,7 @@ class LLVMFunction(object): # result = part1 | part2 | ... last = args[0] - for i in xrange(1, len(expr.args)): + for i in range(1, len(expr.args)): last = builder.or_(last, args[i]) self.update_cache(expr, last) @@ -1246,9 +1324,11 @@ class LLVMFunction(object): # Compute cond zero_casted = llvm_ir.Constant(t_size, 0) - condition_bool = builder.icmp_unsigned("!=", - exceptionflag, - zero_casted) + condition_bool = builder.icmp_unsigned( + "!=", + exceptionflag, + zero_casted + ) # Create bbls branch_id = self.new_branch_name() @@ -1264,7 +1344,7 @@ class LLVMFunction(object): # Then Bloc builder.position_at_end(then_block) PC = self.llvm_context.PC - if isinstance(offset, (int, long)): + if isinstance(offset, int_types): offset = self.add_ir(ExprInt(offset, PC.size)) self.assign(offset, PC) self.assign(self.add_ir(ExprInt(1, 8)), ExprId("status", 32)) @@ -1289,13 +1369,18 @@ class LLVMFunction(object): # Compute cond if restricted_exception is True: flag = m2_csts.EXCEPT_NUM_UPDT_EIP - condition_bool = builder.icmp_unsigned(">", exceptionflag, - llvm_ir.Constant(t_size, flag)) + condition_bool = builder.icmp_unsigned( + ">", + exceptionflag, + llvm_ir.Constant(t_size, flag) + ) else: zero_casted = llvm_ir.Constant(t_size, 0) - condition_bool = builder.icmp_unsigned("!=", - exceptionflag, - zero_casted) + condition_bool = builder.icmp_unsigned( + "!=", + exceptionflag, + zero_casted + ) # Create bbls branch_id = self.new_branch_name() @@ -1311,7 +1396,7 @@ class LLVMFunction(object): # Then Bloc builder.position_at_end(then_block) PC = self.llvm_context.PC - if isinstance(offset, (int, long)): + if isinstance(offset, int_types): offset = self.add_ir(ExprInt(offset, PC.size)) self.assign(offset, PC) self.assign(self.add_ir(ExprInt(1, 8)), ExprId("status", 32)) @@ -1324,8 +1409,12 @@ class LLVMFunction(object): def gen_pre_code(self, instr_attrib): if instr_attrib.log_mn: loc_db = self.llvm_context.ir_arch.loc_db - self.printf("%.8X %s\n" % (instr_attrib.instr.offset, - instr_attrib.instr.to_string(loc_db))) + self.printf( + "%.8X %s\n" % ( + instr_attrib.instr.offset, + instr_attrib.instr.to_string(loc_db) + ) + ) def gen_post_code(self, attributes, pc_value): if attributes.log_regs: @@ -1464,7 +1553,7 @@ class LLVMFunction(object): # Evaluate expressions values = {} - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): if dst == self.llvm_context.ir_arch.IRDst: case2dst, case_value = self.expr2cases(src) else: @@ -1472,40 +1561,51 @@ class LLVMFunction(object): # Check memory access exception if attributes[index].mem_read: - self.check_memory_exception(instr.offset, - restricted_exception=True) + self.check_memory_exception( + instr.offset, + restricted_exception=True + ) # Update the memory - for dst, src in values.iteritems(): + for dst, src in viewitems(values): if isinstance(dst, ExprMem): self.assign(src, dst) # Check memory write exception if attributes[index].mem_write: - self.check_memory_exception(instr.offset, - restricted_exception=True) + self.check_memory_exception( + instr.offset, + restricted_exception=True + ) # Update registers values - for dst, src in values.iteritems(): + for dst, src in viewitems(values): if not isinstance(dst, ExprMem): self.assign(src, dst) # Check post assignblk exception flags if attributes[index].set_exception: - self.check_cpu_exception(instr.offset, restricted_exception=True) + self.check_cpu_exception( + instr.offset, + restricted_exception=True + ) # Destination assert case2dst is not None if len(case2dst) == 1: # Avoid switch in this common case - self.gen_jump2dst(instr_attrib, instr_offsets, case2dst.values()[0]) + self.gen_jump2dst( + instr_attrib, + instr_offsets, + next(iter(viewvalues(case2dst))) + ) else: current_bbl = self.builder.basic_block # Gen the out cases branch_id = self.new_branch_name() case2bbl = {} - for case, dst in case2dst.iteritems(): + for case, dst in list(viewitems(case2dst)): name = "switch_%s_%d" % (branch_id, case) bbl = self.append_basic_block(name) case2bbl[case] = bbl @@ -1515,7 +1615,7 @@ class LLVMFunction(object): # Jump on the correct output self.builder.position_at_end(current_bbl) switch = self.builder.switch(case_value, case2bbl[0]) - for i, bbl in case2bbl.iteritems(): + for i, bbl in viewitems(case2bbl): if i == 0: # Default case is case 0, arbitrary continue @@ -1528,17 +1628,23 @@ class LLVMFunction(object): builder = self.builder m2_exception_flag = self.llvm_context.ir_arch.arch.regs.exception_flags t_size = LLVMType.IntType(m2_exception_flag.size) - self.assign(self.add_ir(ExprInt(1, 8)), - ExprId("status", 32)) - self.assign(t_size(m2_csts.EXCEPT_UNK_MNEMO), - m2_exception_flag) - offset = self.llvm_context.ir_arch.loc_db.get_location_offset(asmblock.loc_key) + self.assign( + self.add_ir(ExprInt(1, 8)), + ExprId("status", 32) + ) + self.assign( + t_size(m2_csts.EXCEPT_UNK_MNEMO), + m2_exception_flag + ) + offset = self.llvm_context.ir_arch.loc_db.get_location_offset( + asmblock.loc_key + ) self.set_ret(LLVMType.IntType(64)(offset)) def gen_finalize(self, asmblock, codegen): """ - In case of delayslot, generate a dummy BBL which return on the computed IRDst - or on next_label + In case of delayslot, generate a dummy BBL which return on the computed + IRDst or on next_label """ if self.llvm_context.has_delayslot: next_label = codegen.get_block_post_label(asmblock) @@ -1552,9 +1658,11 @@ class LLVMFunction(object): # Check if IRDst has been set zero_casted = LLVMType.IntType(codegen.delay_slot_set.size)(0) - condition_bool = builder.icmp_unsigned("!=", - self.add_ir(codegen.delay_slot_set), - zero_casted) + condition_bool = builder.icmp_unsigned( + "!=", + self.add_ir(codegen.delay_slot_set), + zero_casted + ) # Create bbls branch_id = self.new_branch_name() @@ -1627,8 +1735,10 @@ class LLVMFunction(object): if self.llvm_context.has_delayslot: for element in (codegen.delay_slot_dst, codegen.delay_slot_set): eltype = LLVMType.IntType(element.size) - ptr = self.CreateEntryBlockAlloca(eltype, - default_value=eltype(0)) + ptr = self.CreateEntryBlockAlloca( + eltype, + default_value=eltype(0) + ) self.local_vars_pointers[element.name] = ptr loc_key = codegen.get_block_post_label(asmblock) offset = self.llvm_context.ir_arch.loc_db.get_location_offset(loc_key) @@ -1640,9 +1750,12 @@ class LLVMFunction(object): for instr, irblocks in zip(asmblock.lines, irblocks_list): - instr_attrib, irblocks_attributes = codegen.get_attributes(instr, irblocks, - self.log_mn, - self.log_regs) + instr_attrib, irblocks_attributes = codegen.get_attributes( + instr, + irblocks, + self.log_mn, + self.log_regs + ) # Pre-create basic blocks for irblock in irblocks: @@ -1783,7 +1896,7 @@ class LLVMFunction_IRCompilation(LLVMFunction): def gen_irblock(self, irblock): instr_attrib = Attributes() - attributes = [Attributes() for _ in xrange(len(irblock.assignblks))] + attributes = [Attributes() for _ in range(len(irblock.assignblks))] instr_offsets = None return super(LLVMFunction_IRCompilation, self).gen_irblock( instr_attrib, attributes, instr_offsets, irblock @@ -1791,11 +1904,11 @@ class LLVMFunction_IRCompilation(LLVMFunction): def from_ircfg(self, ircfg, append_ret=True): # Create basic blocks - for loc_key, irblock in ircfg.blocks.iteritems(): + for loc_key, irblock in viewitems(ircfg.blocks): self.append_basic_block(loc_key) # Add IRBlocks - for label, irblock in ircfg.blocks.iteritems(): + for label, irblock in viewitems(ircfg.blocks): self.builder.position_at_end(self.get_basic_block_by_loc_key(label)) self.gen_irblock(irblock) diff --git a/miasm2/jitter/loader/elf.py b/miasm2/jitter/loader/elf.py index 17041372..1044fe73 100644 --- a/miasm2/jitter/loader/elf.py +++ b/miasm2/jitter/loader/elf.py @@ -1,6 +1,8 @@ import struct from collections import defaultdict +from future.utils import viewitems + from elfesteem import cstruct from elfesteem import * import elfesteem.elf as elf_csts @@ -23,7 +25,7 @@ def get_import_address_elf(e): for sh in e.sh: if not hasattr(sh, 'rel'): continue - for k, v in sh.rel.items(): + for k, v in viewitems(sh.rel): import2addr[('xxx', k)].add(v.offset) return import2addr @@ -32,7 +34,7 @@ def preload_elf(vm, e, runtime_lib, patch_vm_imp=True, loc_db=None): # XXX quick hack fa = get_import_address_elf(e) dyn_funcs = {} - for (libname, libfunc), ads in fa.items(): + for (libname, libfunc), ads in viewitems(fa): # Quick hack - if a symbol is already known, do not stub it if loc_db and loc_db.get_name_location(libfunc) is not None: continue @@ -66,7 +68,7 @@ def fill_loc_db_with_symbols(elf, loc_db, base_addr=0): symbol_sections = [] for section_header in elf.sh: if hasattr(section_header, 'symbols'): - for name, sym in section_header.symbols.iteritems(): + for name, sym in viewitems(section_header.symbols): if not name or sym.value == 0: continue name = loc_db.find_free_name(name) @@ -275,10 +277,14 @@ def vm_load_elf(vm, fdata, name="", base_addr=0, loc_db=None, apply_reloc=False, # -2: Trick to avoid merging 2 consecutive pages i += [(a_addr, b_addr - 2)] for a, b in i.intervals: - vm.add_memory_page(a, PAGE_READ | PAGE_WRITE, "\x00" * (b + 2 - a), - repr(name)) - - for r_vaddr, data in all_data.items(): + vm.add_memory_page( + a, + PAGE_READ | PAGE_WRITE, + b"\x00" * (b + 2 - a), + repr(name) + ) + + for r_vaddr, data in viewitems(all_data): vm.set_mem(r_vaddr, data) if loc_db is not None: diff --git a/miasm2/jitter/loader/pe.py b/miasm2/jitter/loader/pe.py index 176e0065..a8e6ec0d 100644 --- a/miasm2/jitter/loader/pe.py +++ b/miasm2/jitter/loader/pe.py @@ -1,8 +1,11 @@ +from builtins import map import os import struct import logging from collections import defaultdict +from future.utils import viewitems, viewvalues + from elfesteem import pe from elfesteem import cstruct from elfesteem import * @@ -45,7 +48,8 @@ def get_import_address_pe(e): funcname = imp # l = " %2d %-16s" % (ii, repr(funcname)) import2addr[(libname, funcname)].add( - e.rva2virt(s.firstthunk + e._wsize * ii / 8)) + e.rva2virt(s.firstthunk + (e._wsize * ii) // 8) + ) return import2addr @@ -53,7 +57,7 @@ def preload_pe(vm, e, runtime_lib, patch_vm_imp=True): fa = get_import_address_pe(e) dyn_funcs = {} # log.debug('imported funcs: %s' % fa) - for (libname, libfunc), ads in fa.items(): + for (libname, libfunc), ads in viewitems(fa): for ad in ads: ad_base_lib = runtime_lib.lib_get_add_base(libname) ad_libfunc = runtime_lib.lib_get_add_func(ad_base_lib, libfunc, ad) @@ -81,7 +85,7 @@ def is_redirected_export(pe_obj, addr): addr_rva = pe_obj.virt2rva(addr) if not (export_dir.rva <= addr_rva < export_dir.rva + export_dir.size): return False - addr_end = pe_obj.virt.find('\x00', addr) + addr_end = pe_obj.virt.find(b'\x00', addr) data = pe_obj.virt.get(addr, addr_end) dllname, func_info = data.split('.', 1) @@ -150,10 +154,16 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs): min_len = min(pe.SHList[0].addr, 0x1000) # Get and pad the pe_hdr - pe_hdr = pe.content[:hdr_len] + max( - 0, (min_len - hdr_len)) * "\x00" - vm.add_memory_page(pe.NThdr.ImageBase, PAGE_READ | PAGE_WRITE, - pe_hdr, "%r: PE Header" % name) + pe_hdr = ( + pe.content[:hdr_len] + + max(0, (min_len - hdr_len)) * b"\x00" + ) + vm.add_memory_page( + pe.NThdr.ImageBase, + PAGE_READ | PAGE_WRITE, + pe_hdr, + "%r: PE Header" % name + ) # Align sections size if align_s: @@ -173,13 +183,17 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs): # Pad sections with null bytes and map them for section in pe.SHList: - data = str(section.data) - data += "\x00" * (section.size - len(data)) + data = bytes(section.data) + data += b"\x00" * (section.size - len(data)) attrib = PAGE_READ if section.flags & 0x80000000: attrib |= PAGE_WRITE - vm.add_memory_page(pe.rva2virt(section.addr), attrib, data, - "%r: %r" % (name, section.name)) + vm.add_memory_page( + pe.rva2virt(section.addr), + attrib, + data, + "%r: %r" % (name, section.name) + ) return pe @@ -209,15 +223,17 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs): (max_addr - min_addr)) # Create only one big section containing the whole PE - vm.add_memory_page(min_addr, - PAGE_READ | PAGE_WRITE, - (max_addr - min_addr) * "\x00") + vm.add_memory_page( + min_addr, + PAGE_READ | PAGE_WRITE, + (max_addr - min_addr) * b"\x00" + ) # Copy each sections content in memory for section in pe.SHList: log.debug('Map 0x%x bytes to 0x%x', len(section.data), pe.rva2virt(section.addr)) - vm.set_mem(pe.rva2virt(section.addr), str(section.data)) + vm.set_mem(pe.rva2virt(section.addr), bytes(section.data)) return pe @@ -256,7 +272,7 @@ def vm_load_pe_libs(vm, libs_name, libs, lib_path_base, **kargs): def vm_fix_imports_pe_libs(lib_imgs, libs, lib_path_base, patch_vm_imp=True, **kargs): - for e in lib_imgs.values(): + for e in viewvalues(lib_imgs): preload_pe(e, libs, patch_vm_imp) @@ -281,7 +297,7 @@ def vm2pe(myjit, fname, libs=None, e_orig=None, mye.NThdr.ImageBase = img_base all_mem = myjit.vm.get_all_memory() - addrs = all_mem.keys() + addrs = list(all_mem) addrs.sort() mye.Opthdr.AddressOfEntryPoint = mye.virt2rva(myjit.pc) first = True @@ -303,8 +319,6 @@ def vm2pe(myjit, fname, libs=None, e_orig=None, first = False if libs: if added_funcs is not None: - # name_inv = dict([(x[1], x[0]) for x in libs.name2off.items()]) - for addr, funcaddr in added_funcs: libbase, dllname = libs.fad2info[funcaddr] libs.lib_get_add_func(libbase, dllname, addr) @@ -323,7 +337,7 @@ def vm2pe(myjit, fname, libs=None, e_orig=None, log.debug('%r', mye.SHList) if e_orig: # resource - xx = str(mye) + xx = bytes(mye) mye.content = xx ad = e_orig.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].rva size = e_orig.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].size @@ -333,10 +347,13 @@ def vm2pe(myjit, fname, libs=None, e_orig=None, mye.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].size = size mye.DirRes = pe.DirRes.unpack(mye.img_rva, ad, mye) log.debug('%r', mye.DirRes) - s_res = mye.SHList.add_section(name="myres", rawsize=len(mye.DirRes)) + s_res = mye.SHList.add_section( + name="myres", + rawsize=len(mye.DirRes) + ) mye.DirRes.set_rva(s_res.addr) # generation - open(fname, 'wb').write(str(mye)) + open(fname, 'wb').write(bytes(mye)) return mye @@ -408,7 +425,9 @@ class libimp_pe(libimp): ad = self.lib_imp2ad[libad_tmp][exp_fname] self.lib_imp2ad[libad][imp_ord_or_name] = ad - name_inv = dict([(x[1], x[0]) for x in self.name2off.items()]) + name_inv = dict( + (value, key) for key, value in viewitems(self.name2off) + ) c_name = canon_libname_libfunc( name_inv[libad], imp_ord_or_name) self.fad2cname[ad] = c_name @@ -423,34 +442,36 @@ class libimp_pe(libimp): """ new_lib = [] - for lib_name, ad in self.name2off.items(): + for lib_name, ad in viewitems(self.name2off): # Build an IMAGE_IMPORT_DESCRIPTOR # Get fixed addresses out_ads = dict() # addr -> func_name - for func_name, dst_addresses in self.lib_imp2dstad[ad].items(): + for func_name, dst_addresses in viewitems(self.lib_imp2dstad[ad]): out_ads.update({addr: func_name for addr in dst_addresses}) # Filter available addresses according to @filter_import all_ads = [ - addr for addr in out_ads.keys() if filter_import(target_pe, addr)] + addr for addr in list(out_ads) if filter_import(target_pe, addr) + ] + if not all_ads: continue # Keep non-NULL elements - all_ads.sort() + all_ads.sort(key=str) for i, x in enumerate(all_ads): if x not in [0, None]: break all_ads = all_ads[i:] - log.debug('ads: %s', map(hex, all_ads)) + log.debug('ads: %s', list(map(hex, all_ads))) while all_ads: # Find libname's Import Address Table othunk = all_ads[0] i = 0 while (i + 1 < len(all_ads) and - all_ads[i] + target_pe._wsize / 8 == all_ads[i + 1]): + all_ads[i] + target_pe._wsize // 8 == all_ads[i + 1]): i += 1 # 'i + 1' is IAT's length @@ -515,7 +536,7 @@ def vm_load_pe_and_dependencies(vm, fname, name2module, runtime_lib, todo += [(name, os.path.join(lib_path_base, name), weight - 1) for name in new_dependencies] - ordered_modules = sorted(weight2name.items()) + ordered_modules = sorted(viewitems(weight2name)) for _, modules in ordered_modules: for name in modules: pe_obj = name2module[name] @@ -525,7 +546,7 @@ def vm_load_pe_and_dependencies(vm, fname, name2module, runtime_lib, if pe_obj.DirExport: runtime_lib.add_export_lib(pe_obj, name) - for pe_obj in name2module.itervalues(): + for pe_obj in viewvalues(name2module): if pe_obj is None: continue preload_pe(vm, pe_obj, runtime_lib, patch_vm_imp=True) diff --git a/miasm2/jitter/loader/utils.py b/miasm2/jitter/loader/utils.py index a3a0ecd1..80e19310 100644 --- a/miasm2/jitter/loader/utils.py +++ b/miasm2/jitter/loader/utils.py @@ -1,5 +1,10 @@ +from builtins import int as int_types import logging +from future.utils import viewitems, viewvalues + +from miasm2.core.utils import force_bytes + log = logging.getLogger('loader_common') hnd = logging.StreamHandler() hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s")) @@ -8,11 +13,13 @@ log.setLevel(logging.INFO) def canon_libname_libfunc(libname, libfunc): - dn = libname.split('.')[0] - if type(libfunc) == str: - return "%s_%s" % (dn, libfunc) - else: + libname = force_bytes(libname) + dn = libname.split(b'.')[0] + if isinstance(libfunc, int_types): return str(dn), libfunc + else: + libfunc = force_bytes(libfunc) + return b"%s_%s" % (dn, libfunc) class libimp(object): @@ -30,10 +37,11 @@ class libimp(object): self.fake_libs = set() def lib_get_add_base(self, name): - name = name.lower().strip(' ') - if not "." in name: + name = force_bytes(name) + name = name.lower().strip(b' ') + if not b"." in name: log.debug('warning adding .dll to modulename') - name += '.dll' + name += b'.dll' log.debug(name) if name in self.name2off: @@ -50,7 +58,7 @@ class libimp(object): return ad def lib_get_add_func(self, libad, imp_ord_or_name, dst_ad=None): - if not libad in self.name2off.values(): + if not libad in viewvalues(self.name2off): raise ValueError('unknown lib base!', hex(libad)) # test if not ordinatl @@ -70,7 +78,9 @@ class libimp(object): self.libbase2lastad[libad] += 0x10 # arbitrary self.lib_imp2ad[libad][imp_ord_or_name] = ad - name_inv = dict([(x[1], x[0]) for x in self.name2off.items()]) + name_inv = dict( + (value, key) for key, value in viewitems(self.name2off) + ) c_name = canon_libname_libfunc(name_inv[libad], imp_ord_or_name) self.fad2cname[ad] = c_name self.cname2addr[c_name] = ad @@ -79,8 +89,7 @@ class libimp(object): def check_dst_ad(self): for ad in self.lib_imp2dstad: - all_ads = self.lib_imp2dstad[ad].values() - all_ads.sort() + all_ads = sorted(viewvalues(self.lib_imp2dstad[ad])) for i, x in enumerate(all_ads[:-1]): if x is None or all_ads[i + 1] is None: return False diff --git a/miasm2/jitter/vm_mngr_py.c b/miasm2/jitter/vm_mngr_py.c index 93de9bb4..1173146b 100644 --- a/miasm2/jitter/vm_mngr_py.c +++ b/miasm2/jitter/vm_mngr_py.c @@ -20,6 +20,7 @@ #include <stdint.h> #include <inttypes.h> #include <signal.h> +#include "compat_py23.h" #include "queue.h" #include "vm_mngr.h" #include "vm_mngr_py.h" @@ -54,18 +55,6 @@ PyObject* _vm_get_exception(unsigned int xcpt) return p; } - -#define PyGetInt(item, value) \ - if (PyInt_Check(item)){ \ - value = (uint64_t)PyInt_AsLong(item); \ - } \ - else if (PyLong_Check(item)){ \ - value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ - } \ - else{ \ - RAISE(PyExc_TypeError,"arg must be int"); \ - } \ - static void sig_alarm(int signo) { global_vmmngr->vm_mngr.exception_flags |= BREAK_SIGALARM; @@ -104,18 +93,16 @@ PyObject* vm_add_memory_page(VmMngr* self, PyObject* args) PyGetInt(addr, page_addr); PyGetInt(access, page_access); - if(!PyString_Check(item_str)) - RAISE(PyExc_TypeError,"arg must be str"); + if(!PyBytes_Check(item_str)) + RAISE(PyExc_TypeError,"arg must be bytes"); - buf_size = PyString_Size(item_str); - PyString_AsStringAndSize(item_str, &buf_data, &length); + buf_size = PyBytes_Size(item_str); + PyBytes_AsStringAndSize(item_str, &buf_data, &length); if (name == NULL) { name_ptr = (char*)""; } else { - if (!PyString_Check(name)) - RAISE(PyExc_TypeError,"name must be str"); - name_ptr = PyString_AsString(name); + PyGetStr(name_ptr, name); } mpn = create_memory_page_node(page_addr, (unsigned int)buf_size, (unsigned int)page_access, name_ptr); if (mpn == NULL) @@ -177,11 +164,11 @@ PyObject* vm_set_mem(VmMngr* self, PyObject* args) PyGetInt(py_addr, addr); - if (!PyString_Check(py_buffer)) - RAISE(PyExc_TypeError,"arg must be str"); + if (!PyBytes_Check(py_buffer)) + RAISE(PyExc_TypeError,"arg must be bytes"); - size = PyString_Size(py_buffer); - PyString_AsStringAndSize(py_buffer, &buffer, &py_length); + size = PyBytes_Size(py_buffer); + PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length); ret = vm_write_mem(&self->vm_mngr, addr, buffer, size); if (ret < 0) @@ -238,7 +225,7 @@ PyObject* vm_get_mem(VmMngr* self, PyObject* args) RAISE(PyExc_RuntimeError,"Cannot find address"); } - obj_out = PyString_FromStringAndSize(buf_out, size); + obj_out = PyBytes_FromStringAndSize(buf_out, size); free(buf_out); return obj_out; } @@ -648,7 +635,7 @@ PyObject *vm_dump(PyObject* self) PyObject* ret_obj; buf_final = dump(&((VmMngr* )self)->vm_mngr); - ret_obj = PyString_FromString(buf_final); + ret_obj = PyUnicode_FromString(buf_final); free(buf_final); return ret_obj; } @@ -677,15 +664,15 @@ PyObject* vm_get_all_memory(VmMngr* self, PyObject* args) dict2 = PyDict_New(); - o = PyString_FromStringAndSize(mpn->ad_hp, mpn->size); + o = PyBytes_FromStringAndSize(mpn->ad_hp, mpn->size); PyDict_SetItemString(dict2, "data", o); Py_DECREF(o); - o = PyInt_FromLong((long)mpn->size); + o = PyLong_FromLong((long)mpn->size); PyDict_SetItemString(dict2, "size", o); Py_DECREF(o); - o = PyInt_FromLong((long)mpn->access); + o = PyLong_FromLong((long)mpn->access); PyDict_SetItemString(dict2, "access", o); Py_DECREF(o); @@ -818,7 +805,7 @@ VmMngr_dealloc(VmMngr* self) vm_reset_memory_page_pool(self, NULL); vm_reset_code_bloc_pool(self, NULL); vm_reset_memory_breakpoint(self, NULL); - self->ob_type->tp_free((PyObject*)self); + Py_TYPE(self)->tp_free((PyObject*)self); } @@ -957,8 +944,7 @@ static PyGetSetDef VmMngr_getseters[] = { }; static PyTypeObject VmMngrType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ + PyVarObject_HEAD_INIT(NULL, 0) "VmMngr", /*tp_name*/ sizeof(VmMngr), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -998,30 +984,30 @@ static PyTypeObject VmMngrType = { VmMngr_new, /* tp_new */ }; - static PyMethodDef VmMngr_Methods[] = { {NULL, NULL, 0, NULL} /* Sentinel */ }; -static PyObject *Vm_Mngr_Error; +char vm_mngr_mod_docs[] = "vm_mngr module."; +char vm_mngr_mod_name[] = "VmMngr"; -PyMODINIT_FUNC -initVmMngr(void) + +MOD_INIT(VmMngr) { - PyObject *m; + PyObject *module; - if (PyType_Ready(&VmMngrType) < 0) - return; + MOD_DEF(module, "VmMngr", "vm_mngr module", VmMngr_Methods); + + if (module == NULL) + return NULL; - m = Py_InitModule("VmMngr", VmMngr_Methods); - if (m == NULL) - return; + if (PyType_Ready(&VmMngrType) < 0) + return NULL; - Vm_Mngr_Error = PyErr_NewException("VmMngr.error", NULL, NULL); - Py_INCREF(Vm_Mngr_Error); - PyModule_AddObject(m, "error", Vm_Mngr_Error); + Py_INCREF(&VmMngrType); + if (PyModule_AddObject(module, "Vm", (PyObject *)&VmMngrType) < 0) + return NULL; - Py_INCREF(&VmMngrType); - PyModule_AddObject(m, "Vm", (PyObject *)&VmMngrType); + return module; } diff --git a/miasm2/os_dep/common.py b/miasm2/os_dep/common.py index 7e46b276..ed68185f 100644 --- a/miasm2/os_dep/common.py +++ b/miasm2/os_dep/common.py @@ -1,5 +1,8 @@ import os +from future.utils import viewitems + +from miasm2.core.utils import force_bytes from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE from miasm2.core.utils import get_caller_name from miasm2.core.utils import pck64, upck64 @@ -11,7 +14,7 @@ def get_str_ansi(jitter, ad_str, max_char=None): l = 0 tmp = ad_str while ((max_char is None or l < max_char) and - jitter.vm.get_mem(tmp, 1) != "\x00"): + jitter.vm.get_mem(tmp, 1) != b"\x00"): tmp += 1 l += 1 return jitter.vm.get_mem(ad_str, l) @@ -21,22 +24,25 @@ def get_str_unic(jitter, ad_str, max_char=None): l = 0 tmp = ad_str while ((max_char is None or l < max_char) and - jitter.vm.get_mem(tmp, 2) != "\x00\x00"): + jitter.vm.get_mem(tmp, 2) != b"\x00\x00"): tmp += 2 l += 2 s = jitter.vm.get_mem(ad_str, l) - # TODO: real unicode decoding - s = s[::2] + s = s.decode("utf-16le") return s -def set_str_ansi(s): - return s + "\x00" +def set_str_ansi(value): + value = force_bytes(value) + return value + b"\x00" -def set_str_unic(s): - # TODO: real unicode encoding - return "\x00".join(list(s)) + '\x00' * 3 +def set_str_unic(value): + try: + value = value.decode() + except AttributeError: + pass + return value.encode("utf-16le") + b'\x00' * 2 class heap(object): @@ -74,30 +80,34 @@ class heap(object): combination of them); default is PAGE_READ|PAGE_WRITE """ addr = self.next_addr(size) - vm.add_memory_page(addr, perm, "\x00" * (size), - "Heap alloc by %s" % get_caller_name(2)) + vm.add_memory_page( + addr, + perm, + b"\x00" * (size), + "Heap alloc by %s" % get_caller_name(2) + ) return addr def get_size(self, vm, ptr): """ @vm: a VmMngr instance @size: ptr to get the size of the associated allocation. - + `ptr` can be the base address of a previous allocation, or an address within the allocated range. The size of the whole allocation is always returned, regardless ptr is the base address or not. """ - assert vm.is_mapped(ptr, 1) - data = vm.get_all_memory() - ptr_page = data.get(ptr, None) - if ptr_page is None: - for address, page_info in data.iteritems(): - if address <= ptr < address + page_info["size"]: - ptr_page = page_info - break - else: - raise RuntimeError("Must never happen (unmapped but mark as mapped by API)") - return ptr_page["size"] + assert vm.is_mapped(ptr, 1) + data = vm.get_all_memory() + ptr_page = data.get(ptr, None) + if ptr_page is None: + for address, page_info in viewitems(data): + if address <= ptr < address + page_info["size"]: + ptr_page = page_info + break + else: + raise RuntimeError("Must never happen (unmapped but mark as mapped by API)") + return ptr_page["size"] def windows_to_sbpath(path): @@ -118,26 +128,36 @@ def unix_to_sbpath(path): return os.path.join(BASE_SB_PATH, *path) def get_fmt_args(fmt, cur_arg, get_str, get_arg_n): - output = "" idx = 0 fmt = get_str(fmt) + if isinstance(fmt, bytes): + chars_format = b'%cdfsuxX' + char_percent = b'%' + char_string = b's' + output = b"" + else: + chars_format = u'%cdfsuxX' + char_percent = u'%' + char_string = u's' + output = u"" + while True: if idx == len(fmt): break - char = fmt[idx] + char = fmt[idx:idx+1] idx += 1 - if char == '%': - token = '%' + if char == char_percent: + token = char_percent while True: - char = fmt[idx] + char = fmt[idx:idx+1] idx += 1 token += char - if char.lower() in '%cdfsux': + if char in chars_format: break - if char == '%': + if char == char_percent: output += char continue - if token.endswith('s'): + if token.endswith(char_string): addr = get_arg_n(cur_arg) arg = get_str(addr) else: diff --git a/miasm2/os_dep/linux/environment.py b/miasm2/os_dep/linux/environment.py index 7cafae43..ae9c3317 100644 --- a/miasm2/os_dep/linux/environment.py +++ b/miasm2/os_dep/linux/environment.py @@ -1,9 +1,12 @@ +from __future__ import print_function from collections import namedtuple import functools import os import struct import termios +from future.utils import viewitems + from miasm2.core.interval import interval from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE @@ -99,7 +102,7 @@ class FileDescriptorSTDOUT(FileDescriptorCharDevice): inode = 1 def write(self, data): - print "[STDOUT] %s" % data.rstrip() + print("[STDOUT] %s" % data.rstrip()) class FileDescriptorSTDERR(FileDescriptorCharDevice): @@ -107,7 +110,7 @@ class FileDescriptorSTDERR(FileDescriptorCharDevice): inode = 2 def write(self, data): - print "[STDERR] %s" % data.rstrip() + print("[STDERR] %s" % data.rstrip()) class FileDescriptorDirectory(FileDescriptor): @@ -301,7 +304,7 @@ class FileSystem(object): size = os.path.getsize(path) fdesc.size = size fdesc.blksize = self.blocksize - fdesc.blocks = (size + ((512 - (size % 512)) % 512)) / 512 + fdesc.blocks = (size + ((512 - (size % 512)) % 512)) // 512 return fd @@ -330,17 +333,17 @@ class LinuxEnvironment(object): user_euid = 1000 user_gid = 1000 user_egid = 1000 - user_name = "user" + user_name = b"user" # Memory mapping information brk_current = 0x74000000 mmap_current = 0x75000000 # System information - sys_sysname = "Linux" - sys_nodename = "user-pc" - sys_release = "4.13.0-19-generic" - sys_version = "#22-Ubuntu" + sys_sysname = b"Linux" + sys_nodename = b"user-pc" + sys_release = b"4.13.0-19-generic" + sys_version = b"#22-Ubuntu" sys_machine = None # Filesystem @@ -525,17 +528,24 @@ class LinuxEnvironment(object): self.mmap_current += (len_ + 0x1000) & ~0xfff all_mem = vmmngr.get_all_memory() - mapped = interval([(start, start + info["size"] - 1) - for start, info in all_mem.iteritems()]) + mapped = interval( + [ + (start, start + info["size"] - 1) + for start, info in viewitems(all_mem) + ] + ) MAP_FIXED = 0x10 if flags & MAP_FIXED: # Alloc missing and override missing = interval([(addr, addr + len_ - 1)]) - mapped for start, stop in missing: - vmmngr.add_memory_page(start, PAGE_READ|PAGE_WRITE, - "\x00" * (stop - start + 1), - "mmap allocated") + vmmngr.add_memory_page( + start, + PAGE_READ|PAGE_WRITE, + b"\x00" * (stop - start + 1), + "mmap allocated" + ) else: # Find first candidate segment nearby addr for start, stop in mapped: @@ -548,14 +558,18 @@ class LinuxEnvironment(object): else: assert (interval([(addr, addr + len_)]) & mapped).empty - vmmngr.add_memory_page(addr, PAGE_READ|PAGE_WRITE, "\x00" * len_, - "mmap allocated") + vmmngr.add_memory_page( + addr, + PAGE_READ|PAGE_WRITE, + b"\x00" * len_, + "mmap allocated" + ) if fd == 0xffffffff: if off != 0: raise RuntimeError("Not implemented") - data = "\x00" * len_ + data = b"\x00" * len_ else: fdesc = self.file_descriptors[fd] cur_pos = fdesc.tell() @@ -572,23 +586,30 @@ class LinuxEnvironment(object): addr = self.brk_current else: all_mem = vmmngr.get_all_memory() - mapped = interval([(start, start + info["size"] - 1) - for start, info in all_mem.iteritems()]) + mapped = interval( + [ + (start, start + info["size"] - 1) + for start, info in viewitems(all_mem) + ] + ) # Alloc missing and override missing = interval([(self.brk_current, addr)]) - mapped for start, stop in missing: - vmmngr.add_memory_page(start, PAGE_READ|PAGE_WRITE, - "\x00" * (stop - start + 1), - "BRK") + vmmngr.add_memory_page( + start, + PAGE_READ|PAGE_WRITE, + b"\x00" * (stop - start + 1), + "BRK" + ) self.brk_current = addr return addr class LinuxEnvironment_x86_64(LinuxEnvironment): - platform_arch = "x86_64" - sys_machine = "x86_64" + platform_arch = b"x86_64" + sys_machine = b"x86_64" O_ACCMODE = 0x3 O_CLOEXEC = 0x80000 @@ -599,8 +620,8 @@ class LinuxEnvironment_x86_64(LinuxEnvironment): class LinuxEnvironment_arml(LinuxEnvironment): - platform_arch = "arml" - sys_machine = "arml" + platform_arch = b"arml" + sys_machine = b"arml" O_ACCMODE = 0x3 O_CLOEXEC = 0x80000 @@ -676,7 +697,7 @@ class AuxVec(object): self.AT_PLATFORM: linux_env.platform_arch, self.AT_HWCAP: 0, self.AT_SECURE: 0, - self.AT_RANDOM: "\x00" * 0x10, + self.AT_RANDOM: b"\x00" * 0x10, # vDSO is not mandatory self.AT_SYSINFO_EHDR: None, } @@ -693,7 +714,7 @@ class AuxVec(object): def iteritems(self): """Iterator on auxiliary vector id and values""" - for AT_number, value in self.info.iteritems(): + for AT_number, value in viewitems(self.info): if AT_number in self.ptrs: value = self.ptrs[AT_number] if value is None: @@ -701,6 +722,7 @@ class AuxVec(object): continue yield (AT_number, value) + items = iteritems def prepare_loader_x86_64(jitter, argv, envp, auxv, linux_env, hlt_address=0x13371acc): @@ -735,15 +757,15 @@ def prepare_loader_x86_64(jitter, argv, envp, auxv, linux_env, # [argument vector] for AT_number, data in auxv.data_to_map(): - data += "\x00" + data += b"\x00" jitter.cpu.RSP -= len(data) ptr = jitter.cpu.RSP jitter.vm.set_mem(ptr, data) auxv.ptrs[AT_number] = ptr env_ptrs = [] - for name, value in envp.iteritems(): - env = "%s=%s\x00" % (name, value) + for name, value in viewitems(envp): + env = b"%s=%s\x00" % (name, value) jitter.cpu.RSP -= len(env) ptr = jitter.cpu.RSP jitter.vm.set_mem(ptr, env) @@ -751,7 +773,7 @@ def prepare_loader_x86_64(jitter, argv, envp, auxv, linux_env, argv_ptrs = [] for arg in argv: - arg += "\x00" + arg += b"\x00" jitter.cpu.RSP -= len(arg) ptr = jitter.cpu.RSP jitter.vm.set_mem(ptr, arg) @@ -760,7 +782,7 @@ def prepare_loader_x86_64(jitter, argv, envp, auxv, linux_env, jitter.push_uint64_t(hlt_address) jitter.push_uint64_t(0) jitter.push_uint64_t(0) - for auxid, auxval in auxv.iteritems(): + for auxid, auxval in viewitems(auxv): jitter.push_uint64_t(auxval) jitter.push_uint64_t(auxid) jitter.push_uint64_t(0) @@ -840,15 +862,15 @@ def prepare_loader_arml(jitter, argv, envp, auxv, linux_env, # [argument vector] for AT_number, data in auxv.data_to_map(): - data += "\x00" + data += b"\x00" jitter.cpu.SP -= len(data) ptr = jitter.cpu.SP jitter.vm.set_mem(ptr, data) auxv.ptrs[AT_number] = ptr env_ptrs = [] - for name, value in envp.iteritems(): - env = "%s=%s\x00" % (name, value) + for name, value in viewitems(envp): + env = b"%s=%s\x00" % (name, value) jitter.cpu.SP -= len(env) ptr = jitter.cpu.SP jitter.vm.set_mem(ptr, env) @@ -856,7 +878,7 @@ def prepare_loader_arml(jitter, argv, envp, auxv, linux_env, argv_ptrs = [] for arg in argv: - arg += "\x00" + arg += b"\x00" jitter.cpu.SP -= len(arg) ptr = jitter.cpu.SP jitter.vm.set_mem(ptr, arg) @@ -865,7 +887,7 @@ def prepare_loader_arml(jitter, argv, envp, auxv, linux_env, jitter.push_uint32_t(hlt_address) jitter.push_uint32_t(0) jitter.push_uint32_t(0) - for auxid, auxval in auxv.iteritems(): + for auxid, auxval in viewitems(auxv): jitter.push_uint32_t(auxval) jitter.push_uint32_t(auxid) jitter.push_uint32_t(0) diff --git a/miasm2/os_dep/linux/syscall.py b/miasm2/os_dep/linux/syscall.py index 5bf7d64c..cd4de49f 100644 --- a/miasm2/os_dep/linux/syscall.py +++ b/miasm2/os_dep/linux/syscall.py @@ -1,3 +1,4 @@ +from builtins import range import fcntl import functools import logging @@ -74,7 +75,7 @@ def sys_x86_64_rt_sigaction(jitter, linux_env): # Stub if oact != 0: # Return an empty old action - jitter.vm.set_mem(oact, "\x00" * sigsetsize) + jitter.vm.set_mem(oact, b"\x00" * sigsetsize) jitter.syscall_ret_systemv(0) @@ -110,10 +111,10 @@ def sys_x86_64_newuname(jitter, linux_env): linux_env.sys_machine ] # TODO: Elements start at 0x41 multiples on my tests... - output = "" + output = b"" for elem in info: output += elem - output += "\x00" * (0x41 - len(elem)) + output += b"\x00" * (0x41 - len(elem)) jitter.vm.set_mem(nameptr, output) jitter.syscall_ret_systemv(0) @@ -141,10 +142,10 @@ def sys_arml_newuname(jitter, linux_env): linux_env.sys_machine ] # TODO: Elements start at 0x41 multiples on my tests... - output = "" + output = b"" for elem in info: output += elem - output += "\x00" * (0x41 - len(elem)) + output += b"\x00" * (0x41 - len(elem)) jitter.vm.set_mem(nameptr, output) jitter.syscall_ret_systemv(0) @@ -220,7 +221,7 @@ def sys_x86_64_writev(jitter, linux_env): # Stub fdesc = linux_env.file_descriptors[fd] - for iovec_num in xrange(vlen): + for iovec_num in range(vlen): # struct iovec { # void *iov_base; /* Starting address */ # size_t iov_len; /* Number of bytes to transfer */ @@ -239,7 +240,7 @@ def sys_arml_writev(jitter, linux_env): # Stub fdesc = linux_env.file_descriptors[fd] - for iovec_num in xrange(vlen): + for iovec_num in range(vlen): # struct iovec { # void *iov_base; /* Starting address */ # size_t iov_len; /* Number of bytes to transfer */ @@ -511,7 +512,7 @@ def sys_x86_64_getdents(jitter, linux_env): d_reclen = 8 * 2 + 2 + 1 + len(name) + 1 d_off = cur_len + d_reclen entry = struct.pack("QqH", d_ino, d_off, d_reclen) + \ - name + "\x00" + struct.pack("B", d_type) + name + b"\x00" + struct.pack("B", d_type) assert len(entry) == d_reclen return entry @@ -539,7 +540,7 @@ def sys_arml_getdents64(jitter, linux_env): d_reclen = 8 * 2 + 2 + 1 + len(name) + 1 d_off = cur_len + d_reclen entry = struct.pack("QqHB", d_ino, d_off, d_reclen, d_type) + \ - name + "\x00" + name + b"\x00" assert len(entry) == d_reclen return entry @@ -595,7 +596,7 @@ def sys_x86_64_lgetxattr(jitter, linux_env): log.debug("sys_lgetxattr(%r, %r, %x, %x)", rpathname, rname, value, size) # Stub - jitter.vm.set_mem(value, "\x00" * size) + jitter.vm.set_mem(value, b"\x00" * size) jitter.cpu.RAX = 0 @@ -610,7 +611,7 @@ def sys_x86_64_getxattr(jitter, linux_env): log.debug("sys_getxattr(%r, %r, %x, %x)", rpathname, rname, value, size) # Stub - jitter.vm.set_mem(value, "\x00" * size) + jitter.vm.set_mem(value, b"\x00" * size) jitter.cpu.RAX = 0 @@ -690,7 +691,7 @@ def sys_x86_64_readlink(jitter, linux_env): # Not a link jitter.cpu.RAX = -1 else: - data = link[:bufsize - 1] + "\x00" + data = link[:bufsize - 1] + b"\x00" jitter.vm.set_mem(buf, data) jitter.cpu.RAX = len(data) - 1 diff --git a/miasm2/os_dep/linux_stdlib.py b/miasm2/os_dep/linux_stdlib.py index 9e1cc9db..f12284ee 100644 --- a/miasm2/os_dep/linux_stdlib.py +++ b/miasm2/os_dep/linux_stdlib.py @@ -1,9 +1,16 @@ #-*- coding:utf-8 -*- +from __future__ import print_function import struct from sys import stdout -from string import printable +try: + # Python3 binary stdout + stdout = stdout.buffer +except AttributeError: + pass + +from miasm2.core.utils import int_to_byte, cmp_elts from miasm2.os_dep.common import heap from miasm2.os_dep.common import get_fmt_args as _get_fmt_args @@ -67,7 +74,7 @@ def xxx___libc_start_main(jitter): main = args.main # done by __libc_init_first - size = jitter.ir_arch.pc.size / 8 + size = jitter.ir_arch.pc.size // 8 argc = args.argc argv = args.ubp_av envp = argv + (args.argc + 1) * size @@ -88,7 +95,7 @@ def xxx_isprint(jitter): checks for any printable character including space. ''' ret_addr, args = jitter.func_args_systemv(['c']) - ret = 1 if chr(args.c & 0xFF) in printable else 0 + ret = 1 if 0x20 <= args.c & 0xFF < 0x7f else 0 return jitter.func_ret_systemv(ret_addr, ret) @@ -113,7 +120,7 @@ def xxx_memset(jitter): byte c.''' ret_addr, args = jitter.func_args_systemv(['dest', 'c', 'n']) - jitter.vm.set_mem(args.dest, chr(args.c & 0xFF) * args.n) + jitter.vm.set_mem(args.dest, int_to_byte(args.c & 0xFF) * args.n) return jitter.func_ret_systemv(ret_addr, args.dest) @@ -127,11 +134,11 @@ def xxx_puts(jitter): ret_addr, args = jitter.func_args_systemv(['s']) index = args.s char = jitter.vm.get_mem(index, 1) - while char != '\x00': + while char != b'\x00': stdout.write(char) index += 1 char = jitter.vm.get_mem(index, 1) - stdout.write('\n') + stdout.write(b'\n') return jitter.func_ret_systemv(ret_addr, 1) @@ -146,7 +153,7 @@ def xxx_snprintf(jitter): output = get_fmt_args(jitter, fmt, cur_arg) output = output[:size - 1] ret = len(output) - jitter.vm.set_mem(args.string, output + '\x00') + jitter.vm.set_mem(args.string, output + b'\x00') return jitter.func_ret_systemv(ret_addr, ret) @@ -155,7 +162,7 @@ def xxx_sprintf(jitter): cur_arg, fmt = 2, args.fmt output = get_fmt_args(jitter, fmt, cur_arg) ret = len(output) - jitter.vm.set_mem(args.string, output + '\x00') + jitter.vm.set_mem(args.string, output + b'\x00') return jitter.func_ret_systemv(ret_addr, ret) @@ -164,13 +171,13 @@ def xxx_printf(jitter): cur_arg, fmt = 1, args.fmt output = get_fmt_args(jitter, fmt, cur_arg) ret = len(output) - print output, + stdout.write(output) return jitter.func_ret_systemv(ret_addr, ret) def xxx_strcpy(jitter): ret_ad, args = jitter.func_args_systemv(["dst", "src"]) - str_src = jitter.get_str_ansi(args.src) + '\x00' + str_src = jitter.get_str_ansi(args.src) + b'\x00' jitter.vm.set_mem(args.dst, str_src) jitter.func_ret_systemv(ret_ad, args.dst) @@ -196,11 +203,11 @@ def xxx_strcmp(jitter): ret_ad, args = jitter.func_args_systemv(["ptr_str1", "ptr_str2"]) s1 = jitter.get_str_ansi(args.ptr_str1) s2 = jitter.get_str_ansi(args.ptr_str2) - jitter.func_ret_systemv(ret_ad, cmp(s1, s2)) + jitter.func_ret_systemv(ret_ad, cmp_elts(s1, s2)) def xxx_strncmp(jitter): ret_ad, args = jitter.func_args_systemv(["ptr_str1", "ptr_str2", "size"]) s1 = jitter.get_str_ansi(args.ptr_str1, args.size) s2 = jitter.get_str_ansi(args.ptr_str2, args.size) - jitter.func_ret_systemv(ret_ad, cmp(s1, s2)) + jitter.func_ret_systemv(ret_ad, cmp_elts(s1, s2)) diff --git a/miasm2/os_dep/win_api_x86_32.py b/miasm2/os_dep/win_api_x86_32.py index df679074..e6ef3601 100644 --- a/miasm2/os_dep/win_api_x86_32.py +++ b/miasm2/os_dep/win_api_x86_32.py @@ -1,3 +1,4 @@ +from __future__ import print_function # # Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> # @@ -15,6 +16,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # +from past.builtins import cmp import struct import os import stat @@ -22,14 +24,16 @@ import time import string import logging from zlib import crc32 -from StringIO import StringIO +from io import StringIO import time import datetime +from future.utils import PY3, viewitems + try: from Crypto.Hash import MD5, SHA except ImportError: - print "cannot find crypto, skipping" + print("cannot find crypto, skipping") from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, PAGE_EXEC from miasm2.core.utils import pck16, pck32, hexdump, whoami @@ -77,10 +81,10 @@ ACCESS_DICT = {0x0: 0, 0x100: 0 } -ACCESS_DICT_INV = dict((x[1], x[0]) for x in ACCESS_DICT.iteritems()) +ACCESS_DICT_INV = dict((x[1], x[0]) for x in viewitems(ACCESS_DICT)) -class whandle(): +class whandle(object): def __init__(self, name, info): self.name = name @@ -90,7 +94,7 @@ class whandle(): return '<%r %r %r>' % (self.__class__.__name__, self.name, self.info) -class handle_generator(): +class handle_generator(object): def __init__(self): self.offset = 600 @@ -106,7 +110,7 @@ class handle_generator(): def __repr__(self): out = '<%r\n' % self.__class__.__name__ - ks = self.all_handles.keys() + ks = list(self.all_handles) ks.sort() for k in ks: @@ -124,7 +128,7 @@ class handle_generator(): self.all_handles.__delitem__(item) -class c_winobjs: +class c_winobjs(object): def __init__(self): self.alloc_ad = 0x20000000 @@ -140,8 +144,8 @@ class c_winobjs: self.dw_pid_dummy2 = 0x333 self.dw_pid_cur = 0x444 self.module_fname_nux = None - self.module_name = "test.exe" - self.module_path = "c:\\mydir\\" + self.module_name + self.module_name = b"test.exe" + self.module_path = b"c:\\mydir\\" + self.module_name self.hcurmodule = None self.module_filesize = None self.getversion = 0x0A280105 @@ -161,8 +165,11 @@ class c_winobjs: self.tls_values = {} self.handle_pool = handle_generator() self.handle_mapped = {} - self.hkey_handles = {0x80000001: "hkey_current_user", 0x80000002: "hkey_local_machine"} - self.cur_dir = "c:\\tmp" + self.hkey_handles = { + 0x80000001: b"hkey_current_user", + 0x80000002: b"hkey_local_machine" + } + self.cur_dir = b"c:\\tmp" self.nt_mdl = {} self.nt_mdl_ad = None @@ -176,9 +183,11 @@ class c_winobjs: self.events_pool = {} self.find_data = None - self.current_datetime = datetime.datetime(year=2017, month=8, day=21, - hour=13, minute=37, - second=11, microsecond=123456) + self.current_datetime = datetime.datetime( + year=2017, month=8, day=21, + hour=13, minute=37, + second=11, microsecond=123456 + ) winobjs = c_winobjs() @@ -194,7 +203,7 @@ process_list = [ winobjs.dw_pid_explorer, # DWORD th32ParentProcessID; 0xbeef, # LONG pcPriClassBase; 0x0, # DWORD dwFlags; - "dummy1.exe" # TCHAR szExeFile[MAX_PATH]; + b"dummy1.exe" # TCHAR szExeFile[MAX_PATH]; ], [ 0x40, # DWORD dwSize; @@ -206,7 +215,7 @@ process_list = [ 4, # DWORD th32ParentProcessID; 0xbeef, # LONG pcPriClassBase; 0x0, # DWORD dwFlags; - "explorer.exe" # TCHAR szExeFile[MAX_PATH]; + b"explorer.exe" # TCHAR szExeFile[MAX_PATH]; ], [ @@ -219,7 +228,7 @@ process_list = [ winobjs.dw_pid_explorer, # DWORD th32ParentProcessID; 0xbeef, # LONG pcPriClassBase; 0x0, # DWORD dwFlags; - "dummy2.exe" # TCHAR szExeFile[MAX_PATH]; + b"dummy2.exe" # TCHAR szExeFile[MAX_PATH]; ], [ @@ -239,19 +248,24 @@ process_list = [ ] -class hobj: +class hobj(object): pass -class mdl: +class mdl(object): def __init__(self, ad, l): self.ad = ad self.l = l - def __str__(self): + def __bytes__(self): return struct.pack('LL', self.ad, self.l) + def __str__(self): + if PY3: + return repr(self) + return self.__bytes__() + def kernel32_HeapAlloc(jitter): ret_ad, args = jitter.func_args_stdcall(["heap", "flags", "size"]) @@ -322,7 +336,8 @@ def kernel32_Process32First(jitter): ret_ad, args = jitter.func_args_stdcall(["s_handle", "ad_pentry"]) pentry = struct.pack( - 'IIIIIIIII', *process_list[0][:-1]) + process_list[0][-1] + 'IIIIIIIII', *process_list[0][:-1] + ) + process_list[0][-1] jitter.vm.set_mem(args.ad_pentry, pentry) winobjs.toolhelpsnapshot_info[args.s_handle] = 0 @@ -360,19 +375,20 @@ def kernel32_GetVersionEx(jitter, str_size, set_str): size = jitter.vm.get_u32(args.ptr_struct) if size in [0x14+str_size, 0x1c+str_size]: - tmp = struct.pack("IIIII%dsHHHBB" % str_size, - 0x114, # struct size - 0x5, # maj vers - 0x2, # min vers - 0xa28, # build nbr - 0x2, # platform id - set_str("Service pack 4"), - 3, # wServicePackMajor - 0, # wServicePackMinor - 0x100, # wSuiteMask - 1, # wProductType - 0 # wReserved - ) + tmp = struct.pack( + "IIIII%dsHHHBB" % str_size, + 0x114, # struct size + 0x5, # maj vers + 0x2, # min vers + 0xa28, # build nbr + 0x2, # platform id + set_str("Service pack 4"), + 3, # wServicePackMajor + 0, # wServicePackMinor + 0x100, # wSuiteMask + 1, # wProductType + 0 # wReserved + ) tmp = tmp[:size] jitter.vm.set_mem(args.ptr_struct, tmp) ret = 1 @@ -691,10 +707,10 @@ def kernel32_GetFileSize(jitter): ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"]) if args.hwnd == winobjs.module_cur_hwnd: - ret = len(open(winobjs.module_fname_nux).read()) + ret = len(open(winobjs.module_fname_nux, "rb").read()) elif args.hwnd in winobjs.handle_pool: wh = winobjs.handle_pool[args.hwnd] - ret = len(open(wh.name).read()) + ret = len(open(wh.name, "rb").read()) else: raise ValueError('unknown hwnd!') @@ -707,10 +723,10 @@ def kernel32_GetFileSizeEx(jitter): ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"]) if args.hwnd == winobjs.module_cur_hwnd: - l = len(open(winobjs.module_fname_nux).read()) + l = len(open(winobjs.module_fname_nux, "rb").read()) elif args.hwnd in winobjs.handle_pool: wh = winobjs.handle_pool[args.hwnd] - l = len(open(wh.name).read()) + l = len(open(wh.name, "rb").read()) else: raise ValueError('unknown hwnd!') @@ -797,9 +813,13 @@ def kernel32_GetModuleFileName(jitter, funcname, set_str): if args.hmodule in [0, winobjs.hcurmodule]: p = winobjs.module_path[:] elif (winobjs.runtime_dll and - args.hmodule in winobjs.runtime_dll.name2off.values()): - name_inv = dict([(x[1], x[0]) - for x in winobjs.runtime_dll.name2off.items()]) + args.hmodule in viewvalues(winobjs.runtime_dll.name2off)): + name_inv = dict( + [ + (x[1], x[0]) + for x in viewitems(winobjs.runtime_dll.name2off) + ] + ) p = name_inv[args.hmodule] else: log.warning(('Unknown module 0x%x.' + @@ -987,7 +1007,7 @@ def kernel32_VirtualLock(jitter): jitter.func_ret_stdcall(ret_ad, 1) -class systeminfo: +class systeminfo(object): oemId = 0 dwPageSize = 0x1000 lpMinimumApplicationAddress = 0x10000 @@ -1292,7 +1312,7 @@ def mdl2ad(n): def ad2mdl(ad): - return ((ad - winobjs.nt_mdl_ad) & 0xFFFFFFFFL) / 0x10 + return ((ad - winobjs.nt_mdl_ad) & 0xFFFFFFFF) // 0x10 def ntoskrnl_IoAllocateMdl(jitter): @@ -1300,7 +1320,7 @@ def ntoskrnl_IoAllocateMdl(jitter): "chargequota", "pirp"]) m = mdl(args.v_addr, args.l) winobjs.nt_mdl[winobjs.nt_mdl_cur] = m - jitter.vm.set_mem(mdl2ad(winobjs.nt_mdl_cur), str(m)) + jitter.vm.set_mem(mdl2ad(winobjs.nt_mdl_cur), bytes(m)) jitter.func_ret_stdcall(ret_ad, mdl2ad(winobjs.nt_mdl_cur)) winobjs.nt_mdl_cur += 1 @@ -1665,7 +1685,7 @@ def kernel32_WaitForSingleObject(jitter): if args.dwms and args.dwms + t_start > time.time() * 1000: ret = 0x102 break - for key, value in winobjs.events_pool.iteritems(): + for key, value in viewitems(winobjs.events_pool): if key != args.handle: continue found = True @@ -1835,19 +1855,19 @@ def ntdll_LdrGetProcedureAddress(jitter): def ntdll_memset(jitter): ret_ad, args = jitter.func_args_cdecl(['addr', 'c', 'size']) - jitter.vm.set_mem(args.addr, chr(args.c) * args.size) + jitter.vm.set_mem(args.addr, int_to_byte(args.c) * args.size) jitter.func_ret_cdecl(ret_ad, args.addr) def msvcrt_memset(jitter): ret_ad, args = jitter.func_args_cdecl(['addr', 'c', 'size']) - jitter.vm.set_mem(args.addr, chr(args.c) * args.size) + jitter.vm.set_mem(args.addr, int_to_byte(args.c) * args.size) jitter.func_ret_cdecl(ret_ad, args.addr) def msvcrt_strrchr(jitter): ret_ad, args = jitter.func_args_cdecl(['pstr','c']) s = jitter.get_str_ansi(args.pstr) - c = chr(args.c) + c = int_to_byte(args.c) ret = args.pstr + s.rfind(c) log.info("strrchr(%x '%s','%s') = %x" % (args.pstr,s,c,ret)) jitter.func_ret_cdecl(ret_ad, ret) @@ -1855,7 +1875,7 @@ def msvcrt_strrchr(jitter): def msvcrt_wcsrchr(jitter): ret_ad, args = jitter.func_args_cdecl(['pstr','c']) s = jitter.get_str_unic(args.pstr) - c = chr(args.c) + c = int_to_byte(args.c) ret = args.pstr + (s.rfind(c)*2) log.info("wcsrchr(%x '%s',%s) = %x" % (args.pstr,s,c,ret)) jitter.func_ret_cdecl(ret_ad, ret) @@ -1863,7 +1883,6 @@ def msvcrt_wcsrchr(jitter): def msvcrt_memcpy(jitter): ret_ad, args = jitter.func_args_cdecl(['dst', 'src', 'size']) s = jitter.vm.get_mem(args.src, args.size) - #log.info("memcpy buf %s" % s.encode("hex")) jitter.vm.set_mem(args.dst, s) jitter.func_ret_cdecl(ret_ad, args.dst) @@ -2011,7 +2030,7 @@ def shlwapi_StrToInt64ExW(jitter): def user32_IsCharAlpha(jitter, funcname, get_str): ret_ad, args = jitter.func_args_stdcall(["c"]) try: - c = chr(args.c) + c = int_to_byte(args.c) except: log.error('bad char %r', args.c) c = "\x00" @@ -2032,7 +2051,7 @@ def user32_IsCharAlphaW(jitter): def user32_IsCharAlphaNumericA(jitter): ret_ad, args = jitter.func_args_stdcall(["c"]) - c = chr(args.c) + c = int_to_byte(args.c) if c.isalnum(jitter): ret = 1 else: @@ -2051,7 +2070,7 @@ def msvcrt_sprintf(jitter): ret_ad, args, output = msvcrt_sprintf_str(jitter, jitter.get_str_ansi) ret = len(output) log.info("sprintf() = '%s'" % (output)) - jitter.vm.set_mem(args.string, output + '\x00') + jitter.vm.set_mem(args.string, output + b'\x00') return jitter.func_ret_cdecl(ret_ad, ret) def msvcrt_swprintf(jitter): @@ -2060,7 +2079,7 @@ def msvcrt_swprintf(jitter): output = get_fmt_args(jitter, fmt, cur_arg, jitter.get_str_unic) ret = len(output) log.info("swprintf('%s') = '%s'" % (jitter.get_str_unic(args.fmt), output)) - jitter.vm.set_mem(args.string, output.encode("utf-16le") + '\x00\x00') + jitter.vm.set_mem(args.string, output.encode("utf-16le") + b'\x00\x00') return jitter.func_ret_cdecl(ret_ad, ret) def msvcrt_fprintf(jitter): @@ -2111,7 +2130,7 @@ def kernel32_GetCurrentDirectoryA(jitter): ret_ad, args = jitter.func_args_stdcall(["size","buf"]) dir_ = winobjs.cur_dir log.debug("GetCurrentDirectory() = '%s'" % dir_) - jitter.vm.set_mem(args.buf, dir_[:args.size-1] + "\x00") + jitter.vm.set_mem(args.buf, dir_[:args.size-1] + b"\x00") ret = len(dir_) if args.size <= len(dir_): ret += 1 @@ -2346,7 +2365,7 @@ def filetime_to_unixtime(filetime): Convert filetime to unixtime # https://msdn.microsoft.com/en-us/library/ms724228 """ - return int((filetime - DATE_1601_TO_1970) / 10000000) + return int((filetime - DATE_1601_TO_1970) // 10000000) def datetime_to_systemtime(curtime): @@ -2359,7 +2378,7 @@ def datetime_to_systemtime(curtime): curtime.hour, # hour curtime.minute , # minutes curtime.second, # seconds - int(curtime.microsecond / 1000), # millisec + int(curtime.microsecond // 1000), # millisec ) return s @@ -2515,7 +2534,7 @@ def kernel32_VirtualQuery(jitter): all_mem = jitter.vm.get_all_memory() found = None - for basead, m in all_mem.iteritems(): + for basead, m in viewitems(all_mem): if basead <= args.ad < basead + m['size']: found = args.ad, m break @@ -2798,7 +2817,7 @@ def kernel32_GetTempFileNameA(jitter): jitter.func_ret_stdcall(ret_ad, 0) -class win32_find_data: +class win32_find_data(object): fileattrib = 0 creationtime = 0 lastaccesstime = 0 @@ -2811,7 +2830,7 @@ class win32_find_data: alternamefilename = "" def __init__(self, **kargs): - for k, v in kargs.items(): + for k, v in viewitems(kargs): setattr(self, k, v) def toStruct(self): @@ -2833,7 +2852,7 @@ class win32_find_data: return s -class find_data_mngr: +class find_data_mngr(object): def __init__(self): self.patterns = {} @@ -2904,7 +2923,7 @@ def raw2guid(r): return '{%.8X-%.4X-%.4X-%.4X-%.2X%.2X%.2X%.2X%.2X%.2X}' % o -digs = string.digits + string.lowercase +digs = string.digits + string.ascii_lowercase def int2base(x, base): diff --git a/miasm2/os_dep/win_api_x86_32_seh.py b/miasm2/os_dep/win_api_x86_32_seh.py index be524895..27808d83 100644 --- a/miasm2/os_dep/win_api_x86_32_seh.py +++ b/miasm2/os_dep/win_api_x86_32_seh.py @@ -21,6 +21,8 @@ import logging import os import struct +from future.utils import viewitems + from elfesteem import pe_init from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE @@ -78,7 +80,7 @@ return_from_exception = 0x6eadbeef name2module = [] main_pe = None -main_pe_name = "c:\\xxx\\toto.exe" +main_pe_name = b"c:\\xxx\\toto.exe" MAX_SEH = 5 @@ -92,18 +94,27 @@ def build_teb(jitter, teb_address): """ # Only allocate space for ExceptionList/ProcessEnvironmentBlock/Self - jitter.vm.add_memory_page(teb_address, PAGE_READ | PAGE_WRITE, - "\x00" * NT_TIB.get_offset("StackBase"), - "TEB.NtTib.ExceptionList") - jitter.vm.add_memory_page(teb_address + NT_TIB.get_offset("Self"), - PAGE_READ | PAGE_WRITE, - "\x00" * (NT_TIB.sizeof() - NT_TIB.get_offset("Self")), - "TEB.NtTib.Self") - jitter.vm.add_memory_page(teb_address + TEB.get_offset("ProcessEnvironmentBlock"), - PAGE_READ | PAGE_WRITE, - "\x00" * (TEB.get_offset("LastErrorValue") - - TEB.get_offset("ProcessEnvironmentBlock")), - "TEB.ProcessEnvironmentBlock") + jitter.vm.add_memory_page( + teb_address, + PAGE_READ | PAGE_WRITE, + b"\x00" * NT_TIB.get_offset("StackBase"), + "TEB.NtTib.ExceptionList" + ) + jitter.vm.add_memory_page( + teb_address + NT_TIB.get_offset("Self"), + PAGE_READ | PAGE_WRITE, + b"\x00" * (NT_TIB.sizeof() - NT_TIB.get_offset("Self")), + "TEB.NtTib.Self" + ) + jitter.vm.add_memory_page( + teb_address + TEB.get_offset("ProcessEnvironmentBlock"), + PAGE_READ | PAGE_WRITE, + b"\x00" * ( + TEB.get_offset("LastErrorValue") - + TEB.get_offset("ProcessEnvironmentBlock") + ), + "TEB.ProcessEnvironmentBlock" + ) Teb = TEB(jitter.vm, teb_address) Teb.NtTib.ExceptionList = DEFAULT_SEH Teb.NtTib.Self = teb_address @@ -123,9 +134,12 @@ def build_peb(jitter, peb_address): offset, length = peb_address + 0xC, 0 length += 4 - jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, - "\x00" * length, - "PEB") + jitter.vm.add_memory_page( + offset, + PAGE_READ | PAGE_WRITE, + b"\x00" * length, + "PEB" + ) Peb = PEB(jitter.vm, peb_address) if main_pe: @@ -167,9 +181,12 @@ def build_ldr_data(jitter, modules_info): size += ListEntry.sizeof() ntdll_addr_entry = modules_info.module2entry[ntdll_pe] - jitter.vm.add_memory_page(addr + offset, PAGE_READ | PAGE_WRITE, - "\x00" * size, - "Loader struct") # (ldrdata.get_size() - offset)) + jitter.vm.add_memory_page( + addr + offset, + PAGE_READ | PAGE_WRITE, + b"\x00" * size, + "Loader struct" + ) # (ldrdata.get_size() - offset)) if main_pe: ldrdata.InLoadOrderModuleList.flink = main_addr_entry @@ -213,7 +230,7 @@ class LoadedModules(object): self.module2name[module] = name def __repr__(self): - return "\n".join([str(x) for x in self.name2module.iteritems()]) + return "\n".join(str(x) for x in viewitems(self.name2module)) def create_modules_chain(jitter, name2module): @@ -230,7 +247,7 @@ def create_modules_chain(jitter, name2module): offset_path = 0x600 out = "" - for i, (fname, pe_obj) in enumerate(name2module.items(), 1): + for i, (fname, pe_obj) in enumerate(viewitems(name2module), 1): if pe_obj is None: log.warning("Unknown module: omitted from link list (%r)", fname) @@ -238,35 +255,45 @@ def create_modules_chain(jitter, name2module): addr = base_addr + i * 0x1000 bpath = fname.replace('/', '\\') bname_str = os.path.split(fname)[1].lower() - bname = "\x00".join(bname_str) + "\x00" + bname_unicode = bname_str.encode("utf-16le") log.info("Add module %x %r", pe_obj.NThdr.ImageBase, bname_str) modules_info.add(bname_str, pe_obj, addr) # Allocate a partial LdrDataEntry (0-Flags) - jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, - "\x00" * LdrDataEntry.get_offset("Flags"), - "Module info %r" % bname_str) + jitter.vm.add_memory_page( + addr, + PAGE_READ | PAGE_WRITE, + b"\x00" * LdrDataEntry.get_offset("Flags"), + "Module info %r" % bname_str + ) LdrEntry = LdrDataEntry(jitter.vm, addr) LdrEntry.DllBase = pe_obj.NThdr.ImageBase LdrEntry.EntryPoint = pe_obj.Opthdr.AddressOfEntryPoint LdrEntry.SizeOfImage = pe_obj.NThdr.sizeofimage - LdrEntry.FullDllName.length = len(bname) - LdrEntry.FullDllName.maxlength = len(bname) + 2 + LdrEntry.FullDllName.length = len(bname_unicode) + LdrEntry.FullDllName.maxlength = len(bname_unicode) + 2 LdrEntry.FullDllName.data = addr + offset_path - LdrEntry.BaseDllName.length = len(bname) - LdrEntry.BaseDllName.maxlength = len(bname) + 2 + LdrEntry.BaseDllName.length = len(bname_unicode) + LdrEntry.BaseDllName.maxlength = len(bname_unicode) + 2 LdrEntry.BaseDllName.data = addr + offset_name - jitter.vm.add_memory_page(addr + offset_name, PAGE_READ | PAGE_WRITE, - bname + "\x00" * 3, - "Module name %r" % bname_str) - - jitter.vm.add_memory_page(addr + offset_path, PAGE_READ | PAGE_WRITE, - "\x00".join(bpath) + "\x00" + "\x00" * 3, - "Module path %r" % bname_str) + jitter.vm.add_memory_page( + addr + offset_name, + PAGE_READ | PAGE_WRITE, + bname_unicode + b"\x00" * 2, + "Module name %r" % bname_str + ) + + bpath_unicode = bpath.encode('utf-16le') + jitter.vm.add_memory_page( + addr + offset_path, + PAGE_READ | PAGE_WRITE, + bpath_unicode + b"\x00" * 2, + "Module path %r" % bname_str + ) return modules_info @@ -372,14 +399,15 @@ def add_process_env(jitter): @jitter: jitter instance """ - env_str = 'ALLUSEESPROFILE=C:\\Documents and Settings\\All Users\x00' - env_str = '\x00'.join(env_str) - env_str += "\x00" * 0x10 - jitter.vm.add_memory_page(process_environment_address, - PAGE_READ | PAGE_WRITE, - env_str, - "Process environment") - jitter.vm.set_mem(process_environment_address, env_str) + env_unicode = 'ALLUSEESPROFILE=C:\\Documents and Settings\\All Users\x00'.encode('utf-16le') + env_unicode += b"\x00" * 0x10 + jitter.vm.add_memory_page( + process_environment_address, + PAGE_READ | PAGE_WRITE, + env_unicode, + "Process environment" + ) + jitter.vm.set_mem(process_environment_address, env_unicode) def add_process_parameters(jitter): @@ -388,13 +416,15 @@ def add_process_parameters(jitter): @jitter: jitter instance """ - o = "" + o = b"" o += pck32(0x1000) # size - o += "E" * (0x48 - len(o)) + o += b"E" * (0x48 - len(o)) o += pck32(process_environment_address) - jitter.vm.add_memory_page(process_parameters_address, - PAGE_READ | PAGE_WRITE, - o, "Process parameters") + jitter.vm.add_memory_page( + process_parameters_address, + PAGE_READ | PAGE_WRITE, + o, "Process parameters" + ) # http://blog.fireeye.com/research/2010/08/download_exec_notes.html @@ -431,7 +461,7 @@ def regs2ctxt(jitter, context_address): """ ctxt = ContextException(jitter.vm, context_address) - ctxt.memset("\x00") + ctxt.memset(b"\x00") # ContextFlags # XXX @@ -543,12 +573,17 @@ def fake_seh_handler(jitter, except_code, previous_seh=None): seh = seh.Next.deref seh = seh.Next.deref - log.info('seh_ptr %x { old_seh %r eh %r} ctx_addr %x', - seh.get_addr(), seh.Next, seh.Handler, context_address) + log.info( + 'seh_ptr %x { old_seh %r eh %r} ctx_addr %x', + seh.get_addr(), + seh.Next, + seh.Handler, + context_address + ) # Write exception_record except_record = EXCEPTION_RECORD(jitter.vm, exception_record_address) - except_record.memset("\x00") + except_record.memset(b"\x00") except_record.ExceptionCode = except_code except_record.ExceptionAddress = jitter.cpu.EIP diff --git a/requirements.txt b/requirements.txt index acdef10b..84530589 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ pyparsing -git+https://github.com/serpilliere/elfesteem@master#egg=elfesteem-0.1 +future +git+https://github.com/serpilliere/elfesteem@py23_lalet#egg=elfesteem-0.1 llvmlite==0.26.0 diff --git a/setup.py b/setup.py index 7b0fb86d..83e4608e 100755 --- a/setup.py +++ b/setup.py @@ -1,86 +1,122 @@ #! /usr/bin/env python2 +from __future__ import print_function from distutils.core import setup, Extension from distutils.util import get_platform -from shutil import copy2 +import io +import os import platform -import os, sys +from shutil import copy2 +import sys is_win = platform.system() == "Windows" def buil_all(): - packages=["miasm2", - "miasm2/arch", - "miasm2/arch/x86", - "miasm2/arch/arm", - "miasm2/arch/aarch64", - "miasm2/arch/msp430", - "miasm2/arch/mep", - "miasm2/arch/sh4", - "miasm2/arch/mips32", - "miasm2/arch/ppc", - "miasm2/core", - "miasm2/expression", - "miasm2/ir", - "miasm2/ir/translators", - "miasm2/analysis", - "miasm2/os_dep", - "miasm2/os_dep/linux", - "miasm2/jitter", - "miasm2/jitter/arch", - "miasm2/jitter/loader", - ] + packages=[ + "miasm2", + "miasm2/arch", + "miasm2/arch/x86", + "miasm2/arch/arm", + "miasm2/arch/aarch64", + "miasm2/arch/msp430", + "miasm2/arch/mep", + "miasm2/arch/sh4", + "miasm2/arch/mips32", + "miasm2/arch/ppc", + "miasm2/core", + "miasm2/expression", + "miasm2/ir", + "miasm2/ir/translators", + "miasm2/analysis", + "miasm2/os_dep", + "miasm2/os_dep/linux", + "miasm2/jitter", + "miasm2/jitter/arch", + "miasm2/jitter/loader", + ] ext_modules_all = [ - Extension("miasm2.jitter.VmMngr", - ["miasm2/jitter/vm_mngr.c", - "miasm2/jitter/vm_mngr_py.c", - "miasm2/jitter/bn.c", - ]), - Extension("miasm2.jitter.arch.JitCore_x86", - ["miasm2/jitter/JitCore.c", - "miasm2/jitter/vm_mngr.c", - "miasm2/jitter/op_semantics.c", - "miasm2/jitter/bn.c", - "miasm2/jitter/arch/JitCore_x86.c"]), - Extension("miasm2.jitter.arch.JitCore_arm", - ["miasm2/jitter/JitCore.c", - "miasm2/jitter/vm_mngr.c", - "miasm2/jitter/op_semantics.c", - "miasm2/jitter/bn.c", - "miasm2/jitter/arch/JitCore_arm.c"]), - Extension("miasm2.jitter.arch.JitCore_aarch64", - ["miasm2/jitter/JitCore.c", - "miasm2/jitter/vm_mngr.c", - "miasm2/jitter/op_semantics.c", - "miasm2/jitter/bn.c", - "miasm2/jitter/arch/JitCore_aarch64.c"]), - Extension("miasm2.jitter.arch.JitCore_msp430", - ["miasm2/jitter/JitCore.c", - "miasm2/jitter/vm_mngr.c", - "miasm2/jitter/op_semantics.c", - "miasm2/jitter/bn.c", - "miasm2/jitter/arch/JitCore_msp430.c"]), - Extension("miasm2.jitter.arch.JitCore_mep", - ["miasm2/jitter/JitCore.c", - "miasm2/jitter/vm_mngr.c", - "miasm2/jitter/bn.c", - "miasm2/jitter/arch/JitCore_mep.c"]), - Extension("miasm2.jitter.arch.JitCore_mips32", - ["miasm2/jitter/JitCore.c", - "miasm2/jitter/vm_mngr.c", - "miasm2/jitter/op_semantics.c", - "miasm2/jitter/bn.c", - "miasm2/jitter/arch/JitCore_mips32.c"]), - Extension("miasm2.jitter.arch.JitCore_ppc32", - ["miasm2/jitter/JitCore.c", - "miasm2/jitter/vm_mngr.c", - "miasm2/jitter/op_semantics.c", - "miasm2/jitter/bn.c", - "miasm2/jitter/arch/JitCore_ppc32.c"], - depends=["miasm2/jitter/arch/JitCore_ppc32.h", - "miasm2/jitter/arch/JitCore_ppc32_regs.h", - "miasm2/jitter/bn.h", - ]), + Extension( + "miasm2.jitter.VmMngr", + [ + "miasm2/jitter/vm_mngr.c", + "miasm2/jitter/vm_mngr_py.c", + "miasm2/jitter/bn.c", + ] + ), + Extension( + "miasm2.jitter.arch.JitCore_x86", + [ + "miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", + "miasm2/jitter/op_semantics.c", + "miasm2/jitter/bn.c", + "miasm2/jitter/arch/JitCore_x86.c" + ] + ), + Extension( + "miasm2.jitter.arch.JitCore_arm", + [ + "miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", + "miasm2/jitter/op_semantics.c", + "miasm2/jitter/bn.c", + "miasm2/jitter/arch/JitCore_arm.c" + ] + ), + Extension( + "miasm2.jitter.arch.JitCore_aarch64", + [ + "miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", + "miasm2/jitter/op_semantics.c", + "miasm2/jitter/bn.c", + "miasm2/jitter/arch/JitCore_aarch64.c" + ] + ), + Extension( + "miasm2.jitter.arch.JitCore_msp430", + [ + "miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", + "miasm2/jitter/op_semantics.c", + "miasm2/jitter/bn.c", + "miasm2/jitter/arch/JitCore_msp430.c" + ] + ), + Extension( + "miasm2.jitter.arch.JitCore_mep", + [ + "miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", + "miasm2/jitter/bn.c", + "miasm2/jitter/arch/JitCore_mep.c" + ] + ), + Extension( + "miasm2.jitter.arch.JitCore_mips32", + [ + "miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", + "miasm2/jitter/op_semantics.c", + "miasm2/jitter/bn.c", + "miasm2/jitter/arch/JitCore_mips32.c" + ] + ), + Extension( + "miasm2.jitter.arch.JitCore_ppc32", + [ + "miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", + "miasm2/jitter/op_semantics.c", + "miasm2/jitter/bn.c", + "miasm2/jitter/arch/JitCore_ppc32.c" + ], + depends=[ + "miasm2/jitter/arch/JitCore_ppc32.h", + "miasm2/jitter/arch/JitCore_ppc32_regs.h", + "miasm2/jitter/bn.h", + ] + ), Extension("miasm2.jitter.Jitllvm", ["miasm2/jitter/Jitllvm.c", "miasm2/jitter/bn.c", @@ -96,42 +132,54 @@ def buil_all(): os.environ['MSSdk'] = '1' os.environ['DISTUTILS_USE_SDK'] = '1' - print "building" + print("building") build_ok = False for name, ext_modules in [("all", ext_modules_all), ]: - print "build with", repr(name) + print("build with", repr(name)) try: s = setup( name = "Miasm", version = "2.0", packages = packages, - package_data = {"miasm2":["jitter/*.h", - "jitter/arch/*.h",]}, + package_data = { + "miasm2":[ + "jitter/*.h", + "jitter/arch/*.h", + ] + }, ext_modules = ext_modules, # Metadata author = "Fabrice Desclaux", author_email = "serpilliere@droid-corp.org", description = "Machine code manipulation library", license = "GPLv2", - # keywords = "", - # url = "", + long_description=io.open('README.md', encoding='utf-8').read(), + keywords = [ + "reverse engineering", + "disassembler", + "emulator", + "symbolic execution", + "intermediate representation", + "assembler", + ], + url = "http://miasm.re", ) - except SystemExit, e: - print repr(e) + except SystemExit as e: + print(repr(e)) continue build_ok = True break if not build_ok: raise ValueError("Unable to build Miasm!") - print "build", name + print("build", name) # we copy libraries from build dir to current miasm directory build_base = "build" if "build" in s.command_options: if "build_base" in s.command_options["build"]: build_base = s.command_options["build"]["build_base"] - print build_base + print(build_base) if is_win: libs = [] for root, _, files in os.walk(build_base): @@ -156,7 +204,7 @@ def buil_all(): dst = os.path.join(dst, "arch") dst = os.path.join(dst, filename) if not os.path.isfile(dst): - print "Copying", lib, "to", dst + print("Copying", lib, "to", dst) copy2(lib, dst) buil_all() diff --git a/test/analysis/data_flow.py b/test/analysis/data_flow.py index 2d4e2275..288f4bd6 100644 --- a/test/analysis/data_flow.py +++ b/test/analysis/data_flow.py @@ -1,4 +1,8 @@ """ Test cases for dead code elimination""" +from __future__ import print_function + +from future.utils import viewitems + from miasm2.expression.expression import ExprId, ExprInt, ExprAssign, ExprMem from miasm2.core.locationdb import LocationDB from miasm2.analysis.data_flow import * @@ -683,7 +687,7 @@ for test_nb, test in enumerate([(G1_IRA, G1_EXP_IRA), # Extract test elements g_ira, g_exp_ira = test - print "[+] Test", test_nb+1 + print("[+] Test", test_nb+1) # Print initial graph, for debug open("graph_%02d.dot" % (test_nb+1), "w").write(g_ira.dot()) @@ -700,6 +704,6 @@ for test_nb, test in enumerate([(G1_IRA, G1_EXP_IRA), # Same number of blocks assert len(g_ira.blocks) == len(g_exp_ira.blocks) # Check that each expr in the blocks are the same - for lbl, irb in g_ira.blocks.iteritems(): + for lbl, irb in viewitems(g_ira.blocks): exp_irb = g_exp_ira.blocks[lbl] assert exp_irb.assignblks == irb.assignblks diff --git a/test/analysis/depgraph.py b/test/analysis/depgraph.py index 4d9aa322..c229caf2 100644 --- a/test/analysis/depgraph.py +++ b/test/analysis/depgraph.py @@ -1,6 +1,10 @@ """Regression test module for DependencyGraph""" -from miasm2.expression.expression import ExprId, ExprInt, ExprAssign, ExprCond, \ - ExprLoc, LocKey +from __future__ import print_function + +from future.utils import viewitems + +from miasm2.expression.expression import ExprId, ExprInt, ExprAssign, \ + ExprCond, ExprLoc, LocKey from miasm2.core.locationdb import LocationDB from miasm2.ir.analysis import ira from miasm2.ir.ir import IRBlock, AssignBlock @@ -136,7 +140,7 @@ def bloc2graph(irgraph, label=False, lines=True): block_html_lines = [] if lines and irblock is not None: for assignblk in irblock: - for dst, src in assignblk.iteritems(): + for dst, src in viewitems(assignblk): if False: out_render = "%.8X</td><td %s> " % (0, td_attr) else: @@ -220,7 +224,7 @@ def dg2graph(graph, label=False, lines=True): return '\n'.join(out) -print " [+] Test dictionary equality" +print(" [+] Test dictionary equality") DNA = DependencyNode(LBL2, A, 0) DNB = DependencyNode(LBL1, B, 1) DNC = DependencyNode(LBL1, C, 0) @@ -747,10 +751,14 @@ def flatNode(node): element = int(node.element.arg) else: RuntimeError("Unsupported type '%s'" % type(enode.element)) - name = loc_db.pretty_str(node.loc_key) - return (name, - element, - node.line_nb) + names = loc_db.get_location_names(node.loc_key) + assert len(names) == 1 + name = next(iter(names)) + return ( + name, + element, + node.line_nb + ) else: return str(node) @@ -761,8 +769,10 @@ def flatGraph(graph): out_nodes.add(flatNode(node)) for nodeA, nodeB in graph.edges(): out_edges.add((flatNode(nodeA), flatNode(nodeB))) - out = (tuple(sorted(list(out_nodes))), - tuple(sorted(list(out_edges)))) + out = ( + tuple(sorted(list(out_nodes), key=str)), + tuple(sorted(list(out_edges), key=str)) + ) return out @@ -819,7 +829,7 @@ def test_result(graphA, graphB, leaves): if set(parentsA_noidx.keys()) != set(parentsB_noidx.keys()): return False - for node_noidx, nodeA in parentsA_noidx.iteritems(): + for node_noidx, nodeA in viewitems(parentsA_noidx): nodeB = parentsB_noidx[node_noidx] todo.add((nodeA, nodeB)) @@ -835,7 +845,8 @@ def match_results(resultsA, resultsB, nodes): if len(resultsA) != len(resultsB): return False - for resultA in resultsA: + for flatA in resultsA: + resultA = unflatGraph(flatA) nodes = resultA.leaves() for resultB in resultsB: if test_result(resultA, resultB, nodes): @@ -854,253 +865,253 @@ def get_flat_init_depnodes(depnodes): return out # TESTS -flat_test_results = [[((('lbl0', 1, 0), ('lbl0', 'c', 0), ('lbl1', 'b', 0), ('lbl2', 'a', 0)), - ((('lbl0', 1, 0), ('lbl0', 'c', 0)), - (('lbl0', 'c', 0), ('lbl1', 'b', 0)), - (('lbl1', 'b', 0), ('lbl2', 'a', 0))))], - [((('lbl0', 1, 0), - ('lbl0', 'c', 0), - ('lbl1', 2, 0), - ('lbl1', 'b', 0), - ('lbl2', 'a', 0)), - ((('lbl0', 1, 0), ('lbl0', 'c', 0)), - (('lbl0', 'c', 0), ('lbl2', 'a', 0)), - (('lbl1', 2, 0), ('lbl1', 'b', 0)), - (('lbl1', 'b', 0), ('lbl2', 'a', 0))))], - [((('lbl0', 1, 0), - ('lbl0', 'c', 0), - ('lbl1', 2, 0), - ('lbl1', 'b', 0), - ('lbl3', 'a', 0)), - ((('lbl0', 1, 0), ('lbl0', 'c', 0)), - (('lbl0', 'c', 0), ('lbl3', 'a', 0)), - (('lbl1', 2, 0), ('lbl1', 'b', 0)), - (('lbl1', 'b', 0), ('lbl3', 'a', 0)))), - ((('lbl0', 1, 0), - ('lbl0', 'c', 0), - ('lbl2', 3, 0), - ('lbl2', 'b', 0), - ('lbl3', 'a', 0)), - ((('lbl0', 1, 0), ('lbl0', 'c', 0)), - (('lbl0', 'c', 0), ('lbl3', 'a', 0)), - (('lbl2', 3, 0), ('lbl2', 'b', 0)), - (('lbl2', 'b', 0), ('lbl3', 'a', 0))))], - [(('b', ('lbl2', 'a', 0)), (('b', ('lbl2', 'a', 0)),))], - [((('lbl0', 1, 0), - ('lbl0', 'b', 0), - ('lbl1', 2, 0), - ('lbl1', 'b', 0), - ('lbl2', 'a', 0)), - ((('lbl0', 1, 0), ('lbl0', 'b', 0)), - (('lbl0', 'b', 0), ('lbl1', 'b', 0)), - (('lbl1', 2, 0), ('lbl1', 'b', 0)), - (('lbl1', 'b', 0), ('lbl1', 'b', 0)), - (('lbl1', 'b', 0), ('lbl2', 'a', 0)))), - ((('lbl0', 1, 0), - ('lbl0', 'b', 0), - ('lbl1', 2, 0), - ('lbl1', 'b', 0), - ('lbl2', 'a', 0)), - ((('lbl0', 1, 0), ('lbl0', 'b', 0)), - (('lbl0', 'b', 0), ('lbl1', 'b', 0)), - (('lbl1', 2, 0), ('lbl1', 'b', 0)), - (('lbl1', 'b', 0), ('lbl2', 'a', 0))))], - [((('lbl0', 1, 0), ('lbl0', 'b', 0), ('lbl1', 'a', 0)), - ((('lbl0', 1, 0), ('lbl0', 'b', 0)), - (('lbl0', 'b', 0), ('lbl1', 'a', 0))))], - [((('lbl0', 1, 0), - ('lbl0', 'c', 0), - ('lbl1', 'a', 1), - ('lbl1', 'b', 0), - ('lbl2', 'd', 0)), - ((('lbl0', 1, 0), ('lbl0', 'c', 0)), - (('lbl0', 'c', 0), ('lbl1', 'b', 0)), - (('lbl1', 'a', 1), ('lbl2', 'd', 0)), - (('lbl1', 'b', 0), ('lbl1', 'a', 1))))], - [(('d', ('lbl1', 'b', 0), ('lbl1', 'c', 1), ('lbl2', 'a', 0)), - (('d', ('lbl1', 'c', 1)), - (('lbl1', 'b', 0), ('lbl2', 'a', 0)), - (('lbl1', 'c', 1), ('lbl1', 'b', 0)))), - ((('lbl0', 1, 0), ('lbl0', 'c', 0), ('lbl1', 'b', 0), ('lbl2', 'a', 0)), - ((('lbl0', 1, 0), ('lbl0', 'c', 0)), - (('lbl0', 'c', 0), ('lbl1', 'b', 0)), - (('lbl1', 'b', 0), ('lbl2', 'a', 0))))], +flat_test_results = [[(((b'lbl0', 1, 0), (b'lbl0', 'c', 0), (b'lbl1', 'b', 0), (b'lbl2', 'a', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'c', 0)), + ((b'lbl0', 'c', 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))], + [(((b'lbl0', 1, 0), + (b'lbl0', 'c', 0), + (b'lbl1', 2, 0), + (b'lbl1', 'b', 0), + (b'lbl2', 'a', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'c', 0)), + ((b'lbl0', 'c', 0), (b'lbl2', 'a', 0)), + ((b'lbl1', 2, 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))], + [(((b'lbl0', 1, 0), + (b'lbl0', 'c', 0), + (b'lbl1', 2, 0), + (b'lbl1', 'b', 0), + (b'lbl3', 'a', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'c', 0)), + ((b'lbl0', 'c', 0), (b'lbl3', 'a', 0)), + ((b'lbl1', 2, 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'b', 0), (b'lbl3', 'a', 0)))), + (((b'lbl0', 1, 0), + (b'lbl0', 'c', 0), + (b'lbl2', 3, 0), + (b'lbl2', 'b', 0), + (b'lbl3', 'a', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'c', 0)), + ((b'lbl0', 'c', 0), (b'lbl3', 'a', 0)), + ((b'lbl2', 3, 0), (b'lbl2', 'b', 0)), + ((b'lbl2', 'b', 0), (b'lbl3', 'a', 0))))], + [(('b', (b'lbl2', 'a', 0)), (('b', (b'lbl2', 'a', 0)),))], + [(((b'lbl0', 1, 0), + (b'lbl0', 'b', 0), + (b'lbl1', 2, 0), + (b'lbl1', 'b', 0), + (b'lbl2', 'a', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'b', 0)), + ((b'lbl0', 'b', 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 2, 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'b', 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0)))), + (((b'lbl0', 1, 0), + (b'lbl0', 'b', 0), + (b'lbl1', 2, 0), + (b'lbl1', 'b', 0), + (b'lbl2', 'a', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'b', 0)), + ((b'lbl0', 'b', 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 2, 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))], + [(((b'lbl0', 1, 0), (b'lbl0', 'b', 0), (b'lbl1', 'a', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'b', 0)), + ((b'lbl0', 'b', 0), (b'lbl1', 'a', 0))))], + [(((b'lbl0', 1, 0), + (b'lbl0', 'c', 0), + (b'lbl1', 'a', 1), + (b'lbl1', 'b', 0), + (b'lbl2', 'd', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'c', 0)), + ((b'lbl0', 'c', 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'a', 1), (b'lbl2', 'd', 0)), + ((b'lbl1', 'b', 0), (b'lbl1', 'a', 1))))], + [(('d', (b'lbl1', 'b', 0), (b'lbl1', 'c', 1), (b'lbl2', 'a', 0)), + (('d', (b'lbl1', 'c', 1)), + ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0)), + ((b'lbl1', 'c', 1), (b'lbl1', 'b', 0)))), + (((b'lbl0', 1, 0), (b'lbl0', 'c', 0), (b'lbl1', 'b', 0), (b'lbl2', 'a', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'c', 0)), + ((b'lbl0', 'c', 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))], [(('d', - ('lbl0', 1, 0), - ('lbl0', 'c', 0), - ('lbl1', 'b', 0), - ('lbl1', 'c', 1), - ('lbl2', 'a', 0)), - (('d', ('lbl1', 'c', 1)), - (('lbl0', 1, 0), ('lbl0', 'c', 0)), - (('lbl0', 'c', 0), ('lbl1', 'b', 0)), - (('lbl1', 'b', 0), ('lbl2', 'a', 0)))), - (('d', ('lbl1', 'b', 0), ('lbl1', 'c', 1), ('lbl2', 'a', 0)), - (('d', ('lbl1', 'c', 1)), - (('lbl1', 'b', 0), ('lbl2', 'a', 0)), - (('lbl1', 'c', 1), ('lbl1', 'b', 0))))], - [(('b', ('lbl1', 2, 0), ('lbl1', 'b', 0), ('lbl2', 'a', 0)), - (('b', ('lbl1', 'b', 0)), - (('lbl1', 2, 0), ('lbl1', 'b', 0)), - (('lbl1', 'b', 0), ('lbl1', 'b', 0)), - (('lbl1', 'b', 0), ('lbl2', 'a', 0)))), - (('b', ('lbl1', 2, 0), ('lbl1', 'b', 0), ('lbl2', 'a', 0)), - (('b', ('lbl1', 'b', 0)), - (('lbl1', 2, 0), ('lbl1', 'b', 0)), - (('lbl1', 'b', 0), ('lbl2', 'a', 0))))], - [((('lbl0', 1, 0), - ('lbl0', 2, 0), - ('lbl0', 'a', 0), - ('lbl0', 'b', 0), - ('lbl1', 'a', 0), - ('lbl1', 'b', 0), - ('lbl2', 'a', 0)), - ((('lbl0', 1, 0), ('lbl0', 'a', 0)), - (('lbl0', 2, 0), ('lbl0', 'b', 0)), - (('lbl0', 'a', 0), ('lbl1', 'b', 0)), - (('lbl0', 'b', 0), ('lbl1', 'a', 0)), - (('lbl1', 'a', 0), ('lbl2', 'a', 0)), - (('lbl1', 'b', 0), ('lbl2', 'a', 0))))], - [((('lbl0', 1, 0), - ('lbl0', 'b', 0), - ('lbl1', 2, 1), - ('lbl1', 'a', 0), - ('lbl1', 'b', 1), - ('lbl2', 'b', 0)), - ((('lbl0', 1, 0), ('lbl0', 'b', 0)), - (('lbl0', 'b', 0), ('lbl1', 'b', 1)), - (('lbl1', 2, 1), ('lbl1', 'b', 1)), - (('lbl1', 'a', 0), ('lbl2', 'b', 0)), - (('lbl1', 'b', 1), ('lbl1', 'a', 0)))), - ((('lbl0', 1, 0), - ('lbl0', 'b', 0), - ('lbl1', 2, 1), - ('lbl1', 'a', 0), - ('lbl1', 'b', 1), - ('lbl2', 'b', 0)), - ((('lbl0', 1, 0), ('lbl0', 'b', 0)), - (('lbl0', 'b', 0), ('lbl1', 'b', 1)), - (('lbl1', 2, 1), ('lbl1', 'b', 1)), - (('lbl1', 'a', 0), ('lbl2', 'b', 0)), - (('lbl1', 'b', 1), ('lbl1', 'a', 0)), - (('lbl1', 'b', 1), ('lbl1', 'b', 1)))), - ((('lbl0', 1, 0), ('lbl0', 'b', 0), ('lbl1', 'a', 0), ('lbl2', 'b', 0)), - ((('lbl0', 1, 0), ('lbl0', 'b', 0)), - (('lbl0', 'b', 0), ('lbl1', 'a', 0)), - (('lbl1', 'a', 0), ('lbl2', 'b', 0))))], - [((('lbl0', 1, 0), - ('lbl0', 'a', 0), - ('lbl1', 'c', 0), - ('lbl2', 3, 0), - ('lbl2', 3, 1), - ('lbl2', 'a', 1), - ('lbl2', 'b', 0), - ('lbl3', 'r', 0)), - ((('lbl0', 1, 0), ('lbl0', 'a', 0)), - (('lbl0', 'a', 0), ('lbl2', 'b', 0)), - (('lbl1', 'c', 0), ('lbl3', 'r', 0)), - (('lbl2', 3, 0), ('lbl2', 'b', 0)), - (('lbl2', 3, 1), ('lbl2', 'a', 1)), - (('lbl2', 'a', 1), ('lbl1', 'c', 0)), - (('lbl2', 'a', 1), ('lbl2', 'b', 0)), - (('lbl2', 'b', 0), ('lbl2', 'a', 1)))), - ((('lbl0', 1, 0), - ('lbl0', 'a', 0), - ('lbl1', 'c', 0), - ('lbl2', 3, 0), - ('lbl2', 3, 1), - ('lbl2', 'a', 1), - ('lbl2', 'b', 0), - ('lbl3', 'r', 0)), - ((('lbl0', 1, 0), ('lbl0', 'a', 0)), - (('lbl0', 'a', 0), ('lbl2', 'b', 0)), - (('lbl1', 'c', 0), ('lbl3', 'r', 0)), - (('lbl2', 3, 0), ('lbl2', 'b', 0)), - (('lbl2', 3, 1), ('lbl2', 'a', 1)), - (('lbl2', 'a', 1), ('lbl1', 'c', 0)), - (('lbl2', 'b', 0), ('lbl2', 'a', 1)))), - ((('lbl0', 1, 0), ('lbl0', 'a', 0), ('lbl1', 'c', 0), ('lbl3', 'r', 0)), - ((('lbl0', 1, 0), ('lbl0', 'a', 0)), - (('lbl0', 'a', 0), ('lbl1', 'c', 0)), - (('lbl1', 'c', 0), ('lbl3', 'r', 0))))], + (b'lbl0', 1, 0), + (b'lbl0', 'c', 0), + (b'lbl1', 'b', 0), + (b'lbl1', 'c', 1), + (b'lbl2', 'a', 0)), + (('d', (b'lbl1', 'c', 1)), + ((b'lbl0', 1, 0), (b'lbl0', 'c', 0)), + ((b'lbl0', 'c', 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0)))), + (('d', (b'lbl1', 'b', 0), (b'lbl1', 'c', 1), (b'lbl2', 'a', 0)), + (('d', (b'lbl1', 'c', 1)), + ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0)), + ((b'lbl1', 'c', 1), (b'lbl1', 'b', 0))))], + [(('b', (b'lbl1', 2, 0), (b'lbl1', 'b', 0), (b'lbl2', 'a', 0)), + (('b', (b'lbl1', 'b', 0)), + ((b'lbl1', 2, 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'b', 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0)))), + (('b', (b'lbl1', 2, 0), (b'lbl1', 'b', 0), (b'lbl2', 'a', 0)), + (('b', (b'lbl1', 'b', 0)), + ((b'lbl1', 2, 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))], + [(((b'lbl0', 1, 0), + (b'lbl0', 2, 0), + (b'lbl0', 'a', 0), + (b'lbl0', 'b', 0), + (b'lbl1', 'a', 0), + (b'lbl1', 'b', 0), + (b'lbl2', 'a', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)), + ((b'lbl0', 2, 0), (b'lbl0', 'b', 0)), + ((b'lbl0', 'a', 0), (b'lbl1', 'b', 0)), + ((b'lbl0', 'b', 0), (b'lbl1', 'a', 0)), + ((b'lbl1', 'a', 0), (b'lbl2', 'a', 0)), + ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))], + [(((b'lbl0', 1, 0), + (b'lbl0', 'b', 0), + (b'lbl1', 2, 1), + (b'lbl1', 'a', 0), + (b'lbl1', 'b', 1), + (b'lbl2', 'b', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'b', 0)), + ((b'lbl0', 'b', 0), (b'lbl1', 'b', 1)), + ((b'lbl1', 2, 1), (b'lbl1', 'b', 1)), + ((b'lbl1', 'a', 0), (b'lbl2', 'b', 0)), + ((b'lbl1', 'b', 1), (b'lbl1', 'a', 0)))), + (((b'lbl0', 1, 0), + (b'lbl0', 'b', 0), + (b'lbl1', 2, 1), + (b'lbl1', 'a', 0), + (b'lbl1', 'b', 1), + (b'lbl2', 'b', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'b', 0)), + ((b'lbl0', 'b', 0), (b'lbl1', 'b', 1)), + ((b'lbl1', 2, 1), (b'lbl1', 'b', 1)), + ((b'lbl1', 'a', 0), (b'lbl2', 'b', 0)), + ((b'lbl1', 'b', 1), (b'lbl1', 'a', 0)), + ((b'lbl1', 'b', 1), (b'lbl1', 'b', 1)))), + (((b'lbl0', 1, 0), (b'lbl0', 'b', 0), (b'lbl1', 'a', 0), (b'lbl2', 'b', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'b', 0)), + ((b'lbl0', 'b', 0), (b'lbl1', 'a', 0)), + ((b'lbl1', 'a', 0), (b'lbl2', 'b', 0))))], + [(((b'lbl0', 1, 0), + (b'lbl0', 'a', 0), + (b'lbl1', 'c', 0), + (b'lbl2', 3, 0), + (b'lbl2', 3, 1), + (b'lbl2', 'a', 1), + (b'lbl2', 'b', 0), + (b'lbl3', 'r', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)), + ((b'lbl0', 'a', 0), (b'lbl2', 'b', 0)), + ((b'lbl1', 'c', 0), (b'lbl3', 'r', 0)), + ((b'lbl2', 3, 0), (b'lbl2', 'b', 0)), + ((b'lbl2', 3, 1), (b'lbl2', 'a', 1)), + ((b'lbl2', 'a', 1), (b'lbl1', 'c', 0)), + ((b'lbl2', 'a', 1), (b'lbl2', 'b', 0)), + ((b'lbl2', 'b', 0), (b'lbl2', 'a', 1)))), + (((b'lbl0', 1, 0), + (b'lbl0', 'a', 0), + (b'lbl1', 'c', 0), + (b'lbl2', 3, 0), + (b'lbl2', 3, 1), + (b'lbl2', 'a', 1), + (b'lbl2', 'b', 0), + (b'lbl3', 'r', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)), + ((b'lbl0', 'a', 0), (b'lbl2', 'b', 0)), + ((b'lbl1', 'c', 0), (b'lbl3', 'r', 0)), + ((b'lbl2', 3, 0), (b'lbl2', 'b', 0)), + ((b'lbl2', 3, 1), (b'lbl2', 'a', 1)), + ((b'lbl2', 'a', 1), (b'lbl1', 'c', 0)), + ((b'lbl2', 'b', 0), (b'lbl2', 'a', 1)))), + (((b'lbl0', 1, 0), (b'lbl0', 'a', 0), (b'lbl1', 'c', 0), (b'lbl3', 'r', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)), + ((b'lbl0', 'a', 0), (b'lbl1', 'c', 0)), + ((b'lbl1', 'c', 0), (b'lbl3', 'r', 0))))], [(('d', - ('lbl0', 1, 0), - ('lbl0', 'a', 0), - ('lbl1', 'b', 0), - ('lbl3', 'r', 0)), - (('d', ('lbl3', 'r', 0)), - (('lbl0', 1, 0), ('lbl0', 'a', 0)), - (('lbl0', 'a', 0), ('lbl1', 'b', 0)), - (('lbl1', 'b', 0), ('lbl3', 'r', 0)))), - ((('lbl0', 1, 0), - ('lbl0', 'a', 0), - ('lbl1', 'b', 0), - ('lbl2', 1, 1), - ('lbl2', 'a', 1), - ('lbl2', 'd', 0), - ('lbl3', 'r', 0)), - ((('lbl0', 1, 0), ('lbl0', 'a', 0)), - (('lbl0', 'a', 0), ('lbl2', 'd', 0)), - (('lbl1', 'b', 0), ('lbl3', 'r', 0)), - (('lbl2', 1, 1), ('lbl2', 'a', 1)), - (('lbl2', 'a', 1), ('lbl1', 'b', 0)), - (('lbl2', 'a', 1), ('lbl2', 'd', 0)), - (('lbl2', 'd', 0), ('lbl2', 'a', 1)), - (('lbl2', 'd', 0), ('lbl3', 'r', 0)))), - ((('lbl0', 1, 0), - ('lbl0', 'a', 0), - ('lbl1', 'b', 0), - ('lbl2', 1, 1), - ('lbl2', 'a', 1), - ('lbl2', 'd', 0), - ('lbl3', 'r', 0)), - ((('lbl0', 1, 0), ('lbl0', 'a', 0)), - (('lbl0', 'a', 0), ('lbl2', 'd', 0)), - (('lbl1', 'b', 0), ('lbl3', 'r', 0)), - (('lbl2', 1, 1), ('lbl2', 'a', 1)), - (('lbl2', 'a', 1), ('lbl1', 'b', 0)), - (('lbl2', 'd', 0), ('lbl2', 'a', 1)), - (('lbl2', 'd', 0), ('lbl3', 'r', 0))))], + (b'lbl0', 1, 0), + (b'lbl0', 'a', 0), + (b'lbl1', 'b', 0), + (b'lbl3', 'r', 0)), + (('d', (b'lbl3', 'r', 0)), + ((b'lbl0', 1, 0), (b'lbl0', 'a', 0)), + ((b'lbl0', 'a', 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'b', 0), (b'lbl3', 'r', 0)))), + (((b'lbl0', 1, 0), + (b'lbl0', 'a', 0), + (b'lbl1', 'b', 0), + (b'lbl2', 1, 1), + (b'lbl2', 'a', 1), + (b'lbl2', 'd', 0), + (b'lbl3', 'r', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)), + ((b'lbl0', 'a', 0), (b'lbl2', 'd', 0)), + ((b'lbl1', 'b', 0), (b'lbl3', 'r', 0)), + ((b'lbl2', 1, 1), (b'lbl2', 'a', 1)), + ((b'lbl2', 'a', 1), (b'lbl1', 'b', 0)), + ((b'lbl2', 'a', 1), (b'lbl2', 'd', 0)), + ((b'lbl2', 'd', 0), (b'lbl2', 'a', 1)), + ((b'lbl2', 'd', 0), (b'lbl3', 'r', 0)))), + (((b'lbl0', 1, 0), + (b'lbl0', 'a', 0), + (b'lbl1', 'b', 0), + (b'lbl2', 1, 1), + (b'lbl2', 'a', 1), + (b'lbl2', 'd', 0), + (b'lbl3', 'r', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)), + ((b'lbl0', 'a', 0), (b'lbl2', 'd', 0)), + ((b'lbl1', 'b', 0), (b'lbl3', 'r', 0)), + ((b'lbl2', 1, 1), (b'lbl2', 'a', 1)), + ((b'lbl2', 'a', 1), (b'lbl1', 'b', 0)), + ((b'lbl2', 'd', 0), (b'lbl2', 'a', 1)), + ((b'lbl2', 'd', 0), (b'lbl3', 'r', 0))))], [(('b', - ('lbl0', 1, 0), - ('lbl0', 'a', 0), - ('lbl1', 'b', 2), - ('lbl1', 'c', 1), - ('lbl1', 'd', 0), - ('lbl2', 'r', 0)), - (('b', ('lbl1', 'd', 0)), - (('lbl0', 1, 0), ('lbl0', 'a', 0)), - (('lbl0', 'a', 0), ('lbl1', 'd', 0)), - (('lbl1', 'b', 2), ('lbl1', 'd', 0)), - (('lbl1', 'b', 2), ('lbl2', 'r', 0)), - (('lbl1', 'c', 1), ('lbl1', 'b', 2)), - (('lbl1', 'd', 0), ('lbl1', 'c', 1)))), + (b'lbl0', 1, 0), + (b'lbl0', 'a', 0), + (b'lbl1', 'b', 2), + (b'lbl1', 'c', 1), + (b'lbl1', 'd', 0), + (b'lbl2', 'r', 0)), + (('b', (b'lbl1', 'd', 0)), + ((b'lbl0', 1, 0), (b'lbl0', 'a', 0)), + ((b'lbl0', 'a', 0), (b'lbl1', 'd', 0)), + ((b'lbl1', 'b', 2), (b'lbl1', 'd', 0)), + ((b'lbl1', 'b', 2), (b'lbl2', 'r', 0)), + ((b'lbl1', 'c', 1), (b'lbl1', 'b', 2)), + ((b'lbl1', 'd', 0), (b'lbl1', 'c', 1)))), (('b', - ('lbl0', 1, 0), - ('lbl0', 'a', 0), - ('lbl1', 'b', 2), - ('lbl1', 'c', 1), - ('lbl1', 'd', 0), - ('lbl2', 'r', 0)), - (('b', ('lbl1', 'd', 0)), - (('lbl0', 1, 0), ('lbl0', 'a', 0)), - (('lbl0', 'a', 0), ('lbl1', 'd', 0)), - (('lbl1', 'b', 2), ('lbl2', 'r', 0)), - (('lbl1', 'c', 1), ('lbl1', 'b', 2)), - (('lbl1', 'd', 0), ('lbl1', 'c', 1))))], - [((('lbl0', 1, 0), ('lbl0', 'a', 0), ('lbl5', 'r', 0)), - ((('lbl0', 1, 0), ('lbl0', 'a', 0)), - (('lbl0', 'a', 0), ('lbl5', 'r', 0))))], - [((('lbl0', 2, 0), - ('lbl0', 'd', 0), - ('lbl1', 'a', 0), - ('lbl1', 'b', 0), - ('lbl2', 'a', 0)), - ((('lbl0', 2, 0), ('lbl0', 'd', 0)), - (('lbl0', 'd', 0), ('lbl1', 'a', 0)), - (('lbl0', 'd', 0), ('lbl1', 'b', 0)), - (('lbl1', 'a', 0), ('lbl2', 'a', 0)), - (('lbl1', 'b', 0), ('lbl2', 'a', 0))))]] + (b'lbl0', 1, 0), + (b'lbl0', 'a', 0), + (b'lbl1', 'b', 2), + (b'lbl1', 'c', 1), + (b'lbl1', 'd', 0), + (b'lbl2', 'r', 0)), + (('b', (b'lbl1', 'd', 0)), + ((b'lbl0', 1, 0), (b'lbl0', 'a', 0)), + ((b'lbl0', 'a', 0), (b'lbl1', 'd', 0)), + ((b'lbl1', 'b', 2), (b'lbl2', 'r', 0)), + ((b'lbl1', 'c', 1), (b'lbl1', 'b', 2)), + ((b'lbl1', 'd', 0), (b'lbl1', 'c', 1))))], + [(((b'lbl0', 1, 0), (b'lbl0', 'a', 0), (b'lbl5', 'r', 0)), + (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)), + ((b'lbl0', 'a', 0), (b'lbl5', 'r', 0))))], + [(((b'lbl0', 2, 0), + (b'lbl0', 'd', 0), + (b'lbl1', 'a', 0), + (b'lbl1', 'b', 0), + (b'lbl2', 'a', 0)), + (((b'lbl0', 2, 0), (b'lbl0', 'd', 0)), + ((b'lbl0', 'd', 0), (b'lbl1', 'a', 0)), + ((b'lbl0', 'd', 0), (b'lbl1', 'b', 0)), + ((b'lbl1', 'a', 0), (b'lbl2', 'a', 0)), + ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))]] test_results = [[unflatGraph(flat_result) for flat_result in flat_results] for flat_results in flat_test_results] @@ -1127,7 +1138,7 @@ for test_nb, test in enumerate([(G1_IRA, G1_INPUT), ]): # Extract test elements - print "[+] Test", test_nb + 1 + print("[+] Test", test_nb + 1) ircfg, (depnodes, heads) = test open("graph_%02d.dot" % (test_nb + 1), "w").write(ircfg.dot()) @@ -1149,25 +1160,25 @@ for test_nb, test in enumerate([(G1_IRA, G1_INPUT), # if g_ind == 4: # TODO: Implicit specifications # continue - print " - Class %s - %s" % (g_dep.__class__.__name__, - suffix_key_list[g_ind]) + print(" - Class %s - %s" % (g_dep.__class__.__name__, + suffix_key_list[g_ind])) # Select the correct result key mode_suffix = suffix_key_list[g_ind] graph_test_key = "graph" + mode_suffix # Test public APIs results = g_dep.get_from_depnodes(depnodes, heads) - print "RESULTS" + print("RESULTS") all_results = set() all_flat = set() for i, result in enumerate(results): all_flat.add(flatGraph(result.graph)) - all_results.add(unflatGraph(flatGraph(result.graph))) + all_results.add(flatGraph(result.graph)) open("graph_test_%02d_%02d.dot" % (test_nb + 1, i), "w").write(dg2graph(result.graph)) if g_ind == 0: - all_flat = sorted(all_flat) + all_flat = sorted(all_flat, key=str) all_flats.append(all_flat) flat_depnodes = get_flat_init_depnodes(depnodes) if not match_results(all_results, test_results[test_nb], flat_depnodes): @@ -1175,11 +1186,11 @@ for test_nb, test in enumerate([(G1_IRA, G1_INPUT), continue if FAILED: - print "FAILED :", len(FAILED) + print("FAILED :", len(FAILED)) for test_num in sorted(FAILED): - print test_num, + print(test_num, end=' ') else: - print "SUCCESS" + print("SUCCESS") # Return an error status on error assert not FAILED diff --git a/test/analysis/dg_check.py b/test/analysis/dg_check.py index dd662079..a50855ef 100644 --- a/test/analysis/dg_check.py +++ b/test/analysis/dg_check.py @@ -1,3 +1,4 @@ +from __future__ import print_function from pdb import pm import sys import subprocess @@ -12,9 +13,7 @@ expected = json.load(open(expected_file)) result = json.loads(stdout) -expected.sort() -result.sort() +assert len(expected) == len(result) -print expected -print result -assert expected == result +assert all(r in result for r in expected) +assert all(r in expected for r in result) diff --git a/test/analysis/dse.py b/test/analysis/dse.py index 344b9108..82668ea8 100644 --- a/test/analysis/dse.py +++ b/test/analysis/dse.py @@ -1,6 +1,8 @@ import sys from pdb import pm +from future.utils import viewitems + from elfesteem.strpatchwork import StrPatchwork from miasm2.core import parse_asm from miasm2.expression.expression import ExprCompose, ExprOp, ExprInt, ExprId @@ -80,10 +82,10 @@ class DSETest(object): loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0) output = StrPatchwork() patches = asm_resolve_final(mn_x86, blocks, loc_db) - for offset, raw in patches.items(): + for offset, raw in viewitems(patches): output[offset] = raw - self.assembly = str(output) + self.assembly = bytes(output) def check(self): regs = self.dse.ir_arch.arch.regs diff --git a/test/analysis/modularintervals.py b/test/analysis/modularintervals.py index 45aa82bd..cf286e3a 100644 --- a/test/analysis/modularintervals.py +++ b/test/analysis/modularintervals.py @@ -1,3 +1,4 @@ +from builtins import range from random import shuffle, seed from miasm2.core.interval import interval @@ -11,10 +12,10 @@ def gen_all_intervals(size): -> 2**(2**size) (number of partition) """ nb_elements = 1 << size - for bvec in xrange(1 << nb_elements): + for bvec in range(1 << nb_elements): # Bit vector: if bit i is on, i is in the interval to_ret = interval() - for i in xrange(nb_elements): + for i in range(nb_elements): if bvec & i == i: to_ret += [(i, i)] yield to_ret @@ -22,12 +23,12 @@ def gen_all_intervals(size): def interval_elements(interv): """Generator on element of an interval""" for sub_range in interv: - for i in xrange(sub_range[0], sub_range[1] + 1): + for i in range(sub_range[0], sub_range[1] + 1): yield i size = 4 left, right = list(gen_all_intervals(size)), list(gen_all_intervals(size)) -right_int = range(1 << size) +right_int = list(range(1 << size)) mask = (1 << size) - 1 def test(left, right): diff --git a/test/analysis/range.py b/test/analysis/range.py index 0e38ec95..946d0116 100644 --- a/test/analysis/range.py +++ b/test/analysis/range.py @@ -1,3 +1,4 @@ +from __future__ import print_function from miasm2.expression.expression import * from miasm2.analysis.expression_range import expr_range from miasm2.ir.translators import Translator @@ -81,7 +82,7 @@ for expr in [ ]: computed_range = expr_range(expr) - print expr, computed_range + print(expr, computed_range) # Trivia checks assert all(x[1] < (1 << expr.size) for x in computed_range) diff --git a/test/analysis/unssa.py b/test/analysis/unssa.py index a796f3b6..42e56246 100644 --- a/test/analysis/unssa.py +++ b/test/analysis/unssa.py @@ -1,4 +1,6 @@ """ Test cases for dead code elimination""" +from future.utils import viewvalues + from miasm2.expression.expression import ExprId, ExprInt, ExprAssign, ExprMem, \ ExprCond, ExprLoc from miasm2.core.locationdb import LocationDB @@ -568,7 +570,7 @@ class IRAOutRegs(IRATest): continue if reg in regs_todo: out[reg] = dst - return set(out.values()) + return set(viewvalues(out)) @@ -623,7 +625,7 @@ for test_nb, ircfg in enumerate( # Save a copy of ircfg ircfg_orig = IRCFG(IRDst, loc_db) - for irblock in ircfg.blocks.values(): + for irblock in viewvalues(ircfg.blocks): ircfg_orig.add_irblock(irblock) # SSA diff --git a/test/arch/aarch64/arch.py b/test/arch/aarch64/arch.py index d2f5114e..948ee489 100644 --- a/test/arch/aarch64/arch.py +++ b/test/arch/aarch64/arch.py @@ -1,6 +1,8 @@ +from __future__ import print_function import sys import time from pdb import pm +from miasm2.core.utils import decode_hex from miasm2.arch.aarch64.arch import * from miasm2.core.locationdb import LocationDB @@ -1824,25 +1826,25 @@ reg_tests_aarch64 = [ def h2i(s): - return s.replace(' ', '').decode('hex') + return decode_hex(s.replace(' ', '')) ts = time.time() for s, l in reg_tests_aarch64[:]: - print "-" * 80 - print s[:12], l + print("-" * 80) + print(s[:12], l) s = s[12:] b = h2i((l)) mn = mn_aarch64.dis(b, 'l') - print [str(x) for x in mn.args] - print s - print mn + print([str(x) for x in mn.args]) + print(s) + print(mn) assert(str(mn) == s) l = mn_aarch64.fromstring(s, loc_db, 'l') assert(str(l) == s) a = mn_aarch64.asm(l) - print [x for x in a] - print repr(b) + print([x for x in a]) + print(repr(b)) assert(b in a) diff --git a/test/arch/aarch64/unit/asm_test.py b/test/arch/aarch64/unit/asm_test.py index 677d474f..e49a2a62 100644 --- a/test/arch/aarch64/unit/asm_test.py +++ b/test/arch/aarch64/unit/asm_test.py @@ -1,6 +1,8 @@ import sys import os +from future.utils import viewitems + from miasm2.arch.aarch64.arch import mn_aarch64, base_expr, variable from miasm2.core import parse_asm from miasm2.expression.expression import * @@ -28,10 +30,10 @@ class Asm_Test(object): loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0) s = StrPatchwork() patches = asmblock.asm_resolve_final(mn_aarch64, blocks, loc_db) - for offset, raw in patches.items(): + for offset, raw in viewitems(patches): s[offset] = raw - self.assembly = str(s) + self.assembly = bytes(s) def run(self): run_addr = 0 diff --git a/test/arch/arm/arch.py b/test/arch/arm/arch.py index f86c3cfb..bf2b1a02 100644 --- a/test/arch/arm/arch.py +++ b/test/arch/arm/arch.py @@ -1,4 +1,7 @@ +from __future__ import print_function import time + +from miasm2.core.utils import decode_hex, encode_hex from miasm2.arch.arm.arch import * from miasm2.core.locationdb import LocationDB from pdb import pm @@ -7,7 +10,7 @@ from pdb import pm loc_db = LocationDB() def h2i(s): - return s.replace(' ', '').decode('hex') + return decode_hex(s.replace(' ', '')) def u16swap(i): @@ -225,19 +228,19 @@ reg_tests_arm = [ ts = time.time() for s, l in reg_tests_arm: - print "-" * 80 + print("-" * 80) s = s[12:] b = h2i((l)) mn = mn_arm.dis(b, 'l') - print [str(x) for x in mn.args] - print s - print mn + print([str(x) for x in mn.args]) + print(s) + print(mn) assert(str(mn) == s) l = mn_arm.fromstring(s, loc_db, 'l') assert(str(l) == s) a = mn_arm.asm(l) - print [x for x in a] - print repr(b) + print([x for x in a]) + print(repr(b)) assert(b in a) reg_tests_armt = [ @@ -692,30 +695,30 @@ reg_tests_armt = [ ] -print "#" * 40, 'armthumb', '#' * 40 +print("#" * 40, 'armthumb', '#' * 40) for s, l in reg_tests_armt: - print "-" * 80 + print("-" * 80) s = s[12:] b = h2i((l)) - print b.encode('hex') + print(encode_hex(b)) mn = mn_armt.dis(b, 'l') - print [str(x) for x in mn.args] - print s - print mn + print([str(x) for x in mn.args]) + print(s) + print(mn) assert(str(mn) == s) l = mn_armt.fromstring(s, loc_db, 'l') assert(str(l) == s) - print 'Asm..', l + print('Asm..', l) a = mn_armt.asm(l) - print [x for x in a] - print repr(b) + print([x for x in a]) + print(repr(b)) assert(b in a) -print 'TEST time', time.time() - ts +print('TEST time', time.time() - ts) # speed test arm -o = "" +o = b"" for s, l in reg_tests_arm: s = s[12:] b = h2i((l)) @@ -731,11 +734,11 @@ while off < bs.getlen(): mn = mn_arm.dis(bs, 'l', off) instr_num += 1 off += 4 -print 'instr per sec:', instr_num / (time.time() - ts) +print('instr per sec:', instr_num // (time.time() - ts)) # speed test thumb -o = "" +o = b"" for s, l in reg_tests_armt: s = s[12:] b = h2i((l)) @@ -751,7 +754,7 @@ while off < bs.getlen(): mn = mn_armt.dis(bs, 'l', off) instr_num += 1 off += mn.l -print 'instr per sec:', instr_num / (time.time() - ts) +print('instr per sec:', instr_num // (time.time() - ts)) import cProfile cProfile.run(r'mn_arm.dis("\xe1\xa0\xa0\x06", "l")') diff --git a/test/arch/arm/sem.py b/test/arch/arm/sem.py index d94b7ded..9c19431b 100755 --- a/test/arch/arm/sem.py +++ b/test/arch/arm/sem.py @@ -1,9 +1,12 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from __future__ import print_function import unittest import logging +from future.utils import viewitems + from miasm2.ir.symbexec import SymbolicExecutionEngine from miasm2.arch.arm.arch import mn_arm as mn from miasm2.arch.arm.sem import ir_arml as ir_arch @@ -23,7 +26,7 @@ def M(addr): def compute(asm, inputstate={}, debug=False): loc_db = LocationDB() sympool = dict(regs_init) - sympool.update({k: ExprInt(v, k.size) for k, v in inputstate.iteritems()}) + sympool.update({k: ExprInt(v, k.size) for k, v in viewitems(inputstate)}) ir_tmp = ir_arch(loc_db) ircfg = ir_tmp.new_ircfg() symexec = SymbolicExecutionEngine(ir_tmp, sympool) @@ -34,17 +37,17 @@ def compute(asm, inputstate={}, debug=False): lbl = ir_tmp.add_instr_to_ircfg(instr, ircfg) symexec.run_at(ircfg, lbl) if debug: - for k, v in symexec.symbols.items(): + for k, v in viewitems(symexec.symbols): if regs_init.get(k, None) != v: - print k, v + print(k, v) out = {} - for k, v in symexec.symbols.items(): + for k, v in viewitems(symexec.symbols): if k in EXCLUDE_REGS: continue elif regs_init.get(k, None) == v: continue elif isinstance(v, ExprInt): - out[k] = long(v) + out[k] = int(v) else: out[k] = v return out @@ -58,210 +61,210 @@ class TestARMSemantic(unittest.TestCase): def test_shift(self): # §A8.4: Shifts applied to a register self.assertEqual( - compute('MOV R4, R4 ', {R4: 0xDEADBEEFL, }), {R4: 0xDEADBEEFL, }) + compute('MOV R4, R4 ', {R4: 0xDEADBEEF, }), {R4: 0xDEADBEEF, }) self.assertRaises(ValueError, compute, 'MOV R4, R4 LSL 0') self.assertEqual( - compute('MOV R4, R4 LSL 1', {R4: 0xDEADBEEFL, }), {R4: 0xBD5B7DDEL, }) + compute('MOV R4, R4 LSL 1', {R4: 0xDEADBEEF, }), {R4: 0xBD5B7DDE, }) self.assertEqual( - compute('MOV R4, R4 LSL 16', {R4: 0xDEADBEEFL, }), {R4: 0xBEEF0000L, }) + compute('MOV R4, R4 LSL 16', {R4: 0xDEADBEEF, }), {R4: 0xBEEF0000, }) self.assertEqual( - compute('MOV R4, R4 LSL 31', {R4: 0xDEADBEEFL, }), {R4: 0x80000000L, }) + compute('MOV R4, R4 LSL 31', {R4: 0xDEADBEEF, }), {R4: 0x80000000, }) self.assertRaises(ValueError, compute, 'MOV R4, R4 LSL 32') self.assertEqual( - compute('MOV R4, R4 LSL R5', {R4: 0xDEADBEEFL, R5: 0xBADBAD01L, }), {R4: 0xBD5B7DDEL, R5: 0xBADBAD01L, }) + compute('MOV R4, R4 LSL R5', {R4: 0xDEADBEEF, R5: 0xBADBAD01, }), {R4: 0xBD5B7DDE, R5: 0xBADBAD01, }) self.assertRaises(ValueError, compute, 'MOV R4, R4 LSR 0') self.assertEqual( - compute('MOV R4, R4 LSR 1', {R4: 0xDEADBEEFL, }), {R4: 0x6F56DF77L, }) + compute('MOV R4, R4 LSR 1', {R4: 0xDEADBEEF, }), {R4: 0x6F56DF77, }) self.assertEqual( - compute('MOV R4, R4 LSR 16', {R4: 0xDEADBEEFL, }), {R4: 0x0000DEADL, }) + compute('MOV R4, R4 LSR 16', {R4: 0xDEADBEEF, }), {R4: 0x0000DEAD, }) self.assertEqual( - compute('MOV R4, R4 LSR 31', {R4: 0xDEADBEEFL, }), {R4: 0x00000001L, }) + compute('MOV R4, R4 LSR 31', {R4: 0xDEADBEEF, }), {R4: 0x00000001, }) self.assertEqual( - compute('MOV R4, R4 LSR 32', {R4: 0xDEADBEEFL, }), {R4: 0xDEADBEEFL, }) + compute('MOV R4, R4 LSR 32', {R4: 0xDEADBEEF, }), {R4: 0xDEADBEEF, }) self.assertRaises(ValueError, compute, 'MOV R4, R4 LSR 33') self.assertEqual( - compute('MOV R4, R4 LSR R5', {R4: 0xDEADBEEFL, R5: 0xBADBAD01L, }), {R4: 0x6F56DF77L, R5: 0xBADBAD01L, }) + compute('MOV R4, R4 LSR R5', {R4: 0xDEADBEEF, R5: 0xBADBAD01, }), {R4: 0x6F56DF77, R5: 0xBADBAD01, }) self.assertRaises(ValueError, compute, 'MOV R4, R4 ASR 0') self.assertEqual( - compute('MOV R4, R4 ASR 1', {R4: 0xDEADBEEFL, }), {R4: 0xEF56DF77L, }) + compute('MOV R4, R4 ASR 1', {R4: 0xDEADBEEF, }), {R4: 0xEF56DF77, }) self.assertEqual( - compute('MOV R4, R4 ASR 16', {R4: 0xDEADBEEFL, }), {R4: 0xFFFFDEADL, }) + compute('MOV R4, R4 ASR 16', {R4: 0xDEADBEEF, }), {R4: 0xFFFFDEAD, }) self.assertEqual( - compute('MOV R4, R4 ASR 31', {R4: 0xDEADBEEFL, }), {R4: 0xFFFFFFFFL, }) + compute('MOV R4, R4 ASR 31', {R4: 0xDEADBEEF, }), {R4: 0xFFFFFFFF, }) self.assertEqual( - compute('MOV R4, R4 ASR 32', {R4: 0xDEADBEEFL, }), {R4: 0xDEADBEEFL, }) + compute('MOV R4, R4 ASR 32', {R4: 0xDEADBEEF, }), {R4: 0xDEADBEEF, }) self.assertRaises(ValueError, compute, 'MOV R4, R4 ASR 33') self.assertEqual( - compute('MOV R4, R4 ASR R5', {R4: 0xDEADBEEFL, R5: 0xBADBAD01L, }), {R4: 0xEF56DF77L, R5: 0xBADBAD01L, }) + compute('MOV R4, R4 ASR R5', {R4: 0xDEADBEEF, R5: 0xBADBAD01, }), {R4: 0xEF56DF77, R5: 0xBADBAD01, }) self.assertRaises(ValueError, compute, 'MOV R4, R4 ROR 0') self.assertEqual( - compute('MOV R4, R4 ROR 1', {R4: 0xDEADBEEFL, }), {R4: 0xEF56DF77L, }) + compute('MOV R4, R4 ROR 1', {R4: 0xDEADBEEF, }), {R4: 0xEF56DF77, }) self.assertEqual( - compute('MOV R4, R4 ROR 16', {R4: 0xDEADBEEFL, }), {R4: 0xBEEFDEADL, }) + compute('MOV R4, R4 ROR 16', {R4: 0xDEADBEEF, }), {R4: 0xBEEFDEAD, }) self.assertEqual( - compute('MOV R4, R4 ROR 31', {R4: 0xDEADBEEFL, }), {R4: 0xBD5B7DDFL, }) + compute('MOV R4, R4 ROR 31', {R4: 0xDEADBEEF, }), {R4: 0xBD5B7DDF, }) self.assertRaises(ValueError, compute, 'MOV R4, R4 ROR 32') self.assertEqual( - compute('MOV R4, R4 ROR R5', {R4: 0xDEADBEEFL, R5: 0xBADBAD01L, }), {R4: 0xEF56DF77L, R5: 0xBADBAD01L, }) - self.assertEqual(compute('MOV R4, R4 RRX ', {cf: 0L, R4: 0xDEADBEEFL, }), { - cf: 0L, R4: 0x6F56DF77L, }) - self.assertEqual(compute('MOV R4, R4 RRX ', {cf: 1L, R4: 0xDEADBEEFL, }), { - cf: 1L, R4: 0xEF56DF77L, }) + compute('MOV R4, R4 ROR R5', {R4: 0xDEADBEEF, R5: 0xBADBAD01, }), {R4: 0xEF56DF77, R5: 0xBADBAD01, }) + self.assertEqual(compute('MOV R4, R4 RRX ', {cf: 0, R4: 0xDEADBEEF, }), { + cf: 0, R4: 0x6F56DF77, }) + self.assertEqual(compute('MOV R4, R4 RRX ', {cf: 1, R4: 0xDEADBEEF, }), { + cf: 1, R4: 0xEF56DF77, }) def test_ADC(self): # §A8.8.1: ADC{S}{<c>}{<q>} {<Rd>,} <Rn>, #<const> self.assertRaises( ValueError, compute, 'ADC R4, 0x00000001 ') self.assertEqual(compute('ADC R4, R4, 0x00000001 ', { - cf: 0L, R4: 0x00000000L, }), {cf: 0L, R4: 0x00000001L, }) + cf: 0, R4: 0x00000000, }), {cf: 0, R4: 0x00000001, }) self.assertEqual(compute('ADC R4, R4, 0x00000000 ', { - cf: 1L, R4: 0x00000000L, }), {cf: 1L, R4: 0x00000001L, }) + cf: 1, R4: 0x00000000, }), {cf: 1, R4: 0x00000001, }) self.assertEqual(compute('ADC PC, R4, 0x00000001 ', { - cf: 0L, R4: 0xFFFFFFFFL, PC: 0x55555555L, }), {cf: 0L, R4: 0xFFFFFFFFL, PC: 0x00000000L, }) + cf: 0, R4: 0xFFFFFFFF, PC: 0x55555555, }), {cf: 0, R4: 0xFFFFFFFF, PC: 0x00000000, }) self.assertEqual(compute('ADC PC, R4, 0x00000000 ', { - cf: 1L, R4: 0xFFFFFFFFL, PC: 0x55555555L, }), {cf: 1L, R4: 0xFFFFFFFFL, PC: 0x00000000L, }) - self.assertEqual(compute('ADCS R4, R4, 0x80000000 ', {cf: 0L, R4: 0x80000000L, }), { - nf: 0L, zf: 1L, cf: 1L, of: 1L, R4: 0x00000000L, }) - self.assertEqual(compute('ADCS R4, R4, 0xFF000000 ', {cf: 1L, R4: 0x00FFFFFEL, }), { - nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xFFFFFFFFL, }) + cf: 1, R4: 0xFFFFFFFF, PC: 0x55555555, }), {cf: 1, R4: 0xFFFFFFFF, PC: 0x00000000, }) + self.assertEqual(compute('ADCS R4, R4, 0x80000000 ', {cf: 0, R4: 0x80000000, }), { + nf: 0, zf: 1, cf: 1, of: 1, R4: 0x00000000, }) + self.assertEqual(compute('ADCS R4, R4, 0xFF000000 ', {cf: 1, R4: 0x00FFFFFE, }), { + nf: 1, zf: 0, cf: 0, of: 0, R4: 0xFFFFFFFF, }) self.assertEqual(compute('ADCS PC, R4, 0x00000000 ', { - cf: 0L, R4: 0x00000000L, PC: 0x55555555L, }), {cf: 0L, R4: 0x00000000L, PC: 0x00000000L, }) + cf: 0, R4: 0x00000000, PC: 0x55555555, }), {cf: 0, R4: 0x00000000, PC: 0x00000000, }) self.assertEqual(compute('ADCS PC, R4, 0xFF000000 ', { - cf: 1L, R4: 0x01000000L, PC: 0x55555555L, }), {cf: 1L, R4: 0x01000000L, PC: 0x00000001L, }) + cf: 1, R4: 0x01000000, PC: 0x55555555, }), {cf: 1, R4: 0x01000000, PC: 0x00000001, }) # §A8.8.2: ADC{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {,<shift>} self.assertRaises( ValueError, compute, 'ADC R4, R5 ') self.assertEqual(compute('ADC R4, R4, R5 ', { - cf: 1L, R4: 0xFFFFFFFFL, R5: 0x00000000L, }), {cf: 1L, R4: 0x00000000L, R5: 0x00000000L, }) + cf: 1, R4: 0xFFFFFFFF, R5: 0x00000000, }), {cf: 1, R4: 0x00000000, R5: 0x00000000, }) self.assertEqual(compute('ADC R4, R4, R5 LSL 1 ', { - cf: 0L, R4: 0x00000001L, R5: 0x00000008L, }), {cf: 0L, R4: 0x00000011L, R5: 0x00000008L, }) + cf: 0, R4: 0x00000001, R5: 0x00000008, }), {cf: 0, R4: 0x00000011, R5: 0x00000008, }) self.assertEqual(compute('ADC R4, R4, R5 LSR 2 ', { - cf: 1L, R4: 0x00000000L, R5: 0x80000041L, }), {cf: 1L, R4: 0x20000011L, R5: 0x80000041L, }) + cf: 1, R4: 0x00000000, R5: 0x80000041, }), {cf: 1, R4: 0x20000011, R5: 0x80000041, }) self.assertEqual(compute('ADC R4, R4, R5 ASR 3 ', { - cf: 0L, R4: 0x00000001L, R5: 0x80000081L, }), {cf: 0L, R4: 0xF0000011L, R5: 0x80000081L, }) + cf: 0, R4: 0x00000001, R5: 0x80000081, }), {cf: 0, R4: 0xF0000011, R5: 0x80000081, }) self.assertEqual(compute('ADC R4, R4, R5 ROR 4 ', { - cf: 1L, R4: 0xFFFFFFFFL, R5: 0x0000010FL, }), {cf: 1L, R4: 0xF0000010L, R5: 0x0000010FL, }) + cf: 1, R4: 0xFFFFFFFF, R5: 0x0000010F, }), {cf: 1, R4: 0xF0000010, R5: 0x0000010F, }) self.assertEqual(compute('ADC R4, R4, R5 RRX ', { - cf: 1L, R4: 0xFFFFFFFFL, R5: 0x00000101L, }), {cf: 1L, R4: 0x80000080L, R5: 0x00000101L, }) - self.assertEqual(compute('ADCS R4, R4, R5 ', {cf: 1L, R4: 0xFFFFFFFFL, R5: 0x00000000L, }), { - nf: 0L, zf: 1L, cf: 1L, of: 0L, R4: 0x00000000L, R5: 0x00000000L, }) - self.assertEqual(compute('ADCS R4, R4, R5 LSL 1 ', {cf: 0L, R4: 0x00000001L, R5: 0x00000008L, }), { - nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x00000011L, R5: 0x00000008L, }) - self.assertEqual(compute('ADCS R4, R4, R5 LSR 2 ', {cf: 1L, R4: 0x00000000L, R5: 0x80000041L, }), { - nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x20000011L, R5: 0x80000041L, }) - self.assertEqual(compute('ADCS R4, R4, R5 ASR 3 ', {cf: 0L, R4: 0x00000001L, R5: 0x80000081L, }), { - nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xF0000011L, R5: 0x80000081L, }) - self.assertEqual(compute('ADCS R4, R4, R5 ROR 4 ', {cf: 1L, R4: 0xFFFFFFFFL, R5: 0x0000010FL, }), { - nf: 1L, zf: 0L, cf: 1L, of: 0L, R4: 0xF0000010L, R5: 0x0000010FL, }) - self.assertEqual(compute('ADCS R4, R4, R5 RRX ', {cf: 1L, R4: 0xFFFFFFFFL, R5: 0x00000101L, }), { - nf: 1L, zf: 0L, cf: 1L, of: 0L, R4: 0x80000080L, R5: 0x00000101L, }) + cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {cf: 1, R4: 0x80000080, R5: 0x00000101, }) + self.assertEqual(compute('ADCS R4, R4, R5 ', {cf: 1, R4: 0xFFFFFFFF, R5: 0x00000000, }), { + nf: 0, zf: 1, cf: 1, of: 0, R4: 0x00000000, R5: 0x00000000, }) + self.assertEqual(compute('ADCS R4, R4, R5 LSL 1 ', {cf: 0, R4: 0x00000001, R5: 0x00000008, }), { + nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000011, R5: 0x00000008, }) + self.assertEqual(compute('ADCS R4, R4, R5 LSR 2 ', {cf: 1, R4: 0x00000000, R5: 0x80000041, }), { + nf: 0, zf: 0, cf: 0, of: 0, R4: 0x20000011, R5: 0x80000041, }) + self.assertEqual(compute('ADCS R4, R4, R5 ASR 3 ', {cf: 0, R4: 0x00000001, R5: 0x80000081, }), { + nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF0000011, R5: 0x80000081, }) + self.assertEqual(compute('ADCS R4, R4, R5 ROR 4 ', {cf: 1, R4: 0xFFFFFFFF, R5: 0x0000010F, }), { + nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF0000010, R5: 0x0000010F, }) + self.assertEqual(compute('ADCS R4, R4, R5 RRX ', {cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), { + nf: 1, zf: 0, cf: 1, of: 0, R4: 0x80000080, R5: 0x00000101, }) # §A8.8.3: ADC{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>, <type> <Rs> self.assertEqual(compute('ADC R4, R6, R4 LSL R5', { - cf: 0L, R4: 0x00000001L, R5: 0x00000004L, R6: 0L, }), {cf: 0L, R4: 0x00000010L, R5: 0x00000004L, R6: 0L, }) + cf: 0, R4: 0x00000001, R5: 0x00000004, R6: 0, }), {cf: 0, R4: 0x00000010, R5: 0x00000004, R6: 0, }) self.assertEqual(compute('ADC R4, R6, R4 LSR R5', { - cf: 1L, R4: 0x00000110L, R5: 0x80000004L, R6: 0L, }), {cf: 1L, R4: 0x00000012L, R5: 0x80000004L, R6: 0L, }) + cf: 1, R4: 0x00000110, R5: 0x80000004, R6: 0, }), {cf: 1, R4: 0x00000012, R5: 0x80000004, R6: 0, }) self.assertEqual(compute('ADC R4, R6, R4 ASR R5', { - cf: 0L, R4: 0x80000010L, R5: 0xF0000001L, R6: 0L, }), {cf: 0L, R4: 0xC0000008L, R5: 0xF0000001L, R6: 0L, }) + cf: 0, R4: 0x80000010, R5: 0xF0000001, R6: 0, }), {cf: 0, R4: 0xC0000008, R5: 0xF0000001, R6: 0, }) self.assertEqual(compute('ADC R4, R6, R4 ROR R5', { - cf: 1L, R4: 0x000000FFL, R5: 0x00000F04L, R6: 0L, }), {cf: 1L, R4: 0xF0000010L, R5: 0x00000F04L, R6: 0L, }) - self.assertEqual(compute('ADCS R4, R6, R4 LSL R5', {cf: 0L, R4: 0x00000001L, R5: 0x00000004L, R6: 0L, }), { - nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x00000010L, R5: 0x00000004L, R6: 0L, }) - self.assertEqual(compute('ADCS R4, R6, R4 LSR R5', {cf: 1L, R4: 0x00000110L, R5: 0x80000004L, R6: 0L, }), { - nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x00000012L, R5: 0x80000004L, R6: 0L, }) - self.assertEqual(compute('ADCS R4, R6, R4 ASR R5', {cf: 0L, R4: 0x80000010L, R5: 0xF0000001L, R6: 0L, }), { - nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xC0000008L, R5: 0xF0000001L, R6: 0L, }) - self.assertEqual(compute('ADCS R4, R6, R4 ROR R5', {cf: 1L, R4: 0x000000FFL, R5: 0x00000F04L, R6: 0L, }), { - nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xF0000010L, R5: 0x00000F04L, R6: 0L, }) + cf: 1, R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {cf: 1, R4: 0xF0000010, R5: 0x00000F04, R6: 0, }) + self.assertEqual(compute('ADCS R4, R6, R4 LSL R5', {cf: 0, R4: 0x00000001, R5: 0x00000004, R6: 0, }), { + nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000010, R5: 0x00000004, R6: 0, }) + self.assertEqual(compute('ADCS R4, R6, R4 LSR R5', {cf: 1, R4: 0x00000110, R5: 0x80000004, R6: 0, }), { + nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000012, R5: 0x80000004, R6: 0, }) + self.assertEqual(compute('ADCS R4, R6, R4 ASR R5', {cf: 0, R4: 0x80000010, R5: 0xF0000001, R6: 0, }), { + nf: 1, zf: 0, cf: 0, of: 0, R4: 0xC0000008, R5: 0xF0000001, R6: 0, }) + self.assertEqual(compute('ADCS R4, R6, R4 ROR R5', {cf: 1, R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), { + nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF0000010, R5: 0x00000F04, R6: 0, }) def test_ADD(self): # §A8.8.{5,9}: ADD{S}{<c>}{<q>} {<Rd>,} <Rn>, #<const> self.assertRaises( ValueError, compute, 'ADD R4, 0x00000001L ') self.assertEqual(compute('ADD R4, R4, 0x00000001 ', { - R4: 0x00000000L, }), {R4: 0x00000001L, }) + R4: 0x00000000, }), {R4: 0x00000001, }) self.assertEqual(compute('ADD R4, R4, 0x00000000 ', { - R4: 0x00000000L, }), {R4: 0x00000000L, }) + R4: 0x00000000, }), {R4: 0x00000000, }) self.assertEqual(compute('ADD PC, R4, 0x00000001 ', { - R4: 0xFFFFFFFFL, PC: 0x55555555L, }), {R4: 0xFFFFFFFFL, PC: 0x00000000L, }) + R4: 0xFFFFFFFF, PC: 0x55555555, }), {R4: 0xFFFFFFFF, PC: 0x00000000, }) self.assertEqual(compute('ADD PC, R4, 0x00000000 ', { - R4: 0xFFFFFFFFL, PC: 0x55555555L, }), {R4: 0xFFFFFFFFL, PC: 0xFFFFFFFFL, }) - self.assertEqual(compute('ADDS R4, R4, 0x80000000 ', {R4: 0x80000000L, }), { - nf: 0L, zf: 1L, cf: 1L, of: 1L, R4: 0x00000000L, }) - self.assertEqual(compute('ADDS R4, R4, 0xFF000000 ', {R4: 0x00FFFFFEL, }), { - nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xFFFFFFFEL, }) + R4: 0xFFFFFFFF, PC: 0x55555555, }), {R4: 0xFFFFFFFF, PC: 0xFFFFFFFF, }) + self.assertEqual(compute('ADDS R4, R4, 0x80000000 ', {R4: 0x80000000, }), { + nf: 0, zf: 1, cf: 1, of: 1, R4: 0x00000000, }) + self.assertEqual(compute('ADDS R4, R4, 0xFF000000 ', {R4: 0x00FFFFFE, }), { + nf: 1, zf: 0, cf: 0, of: 0, R4: 0xFFFFFFFE, }) self.assertEqual(compute('ADDS PC, R4, 0x00000000 ', { - R4: 0x00000000L, PC: 0x55555555L, }), {R4: 0x00000000L, PC: 0x00000000L, }) + R4: 0x00000000, PC: 0x55555555, }), {R4: 0x00000000, PC: 0x00000000, }) self.assertEqual(compute('ADDS PC, R4, 0xFF000000 ', { - R4: 0x01000000L, PC: 0x55555555L, }), {R4: 0x01000000L, PC: 0x00000000L, }) + R4: 0x01000000, PC: 0x55555555, }), {R4: 0x01000000, PC: 0x00000000, }) # SP special part self.assertEqual(compute('ADD R4, SP, 0x00000001 ', { - R4: 0x00000000L, SP: 0x00000000L, }), {R4: 0x00000001L, SP: 0x00000000L, }) + R4: 0x00000000, SP: 0x00000000, }), {R4: 0x00000001, SP: 0x00000000, }) # §A8.8.{7,11}: ADD{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {,<shift>} self.assertRaises( ValueError, compute, 'ADD R4, R5 ') self.assertEqual(compute('ADD R4, R4, R5 ', { - R4: 0xFFFFFFFFL, R5: 0x00000001L, }), {R4: 0x00000000L, R5: 0x00000001L, }) + R4: 0xFFFFFFFF, R5: 0x00000001, }), {R4: 0x00000000, R5: 0x00000001, }) self.assertEqual(compute('ADD R4, R4, R5 LSL 1 ', { - R4: 0x00000001L, R5: 0x00000008L, }), {R4: 0x00000011L, R5: 0x00000008L, }) + R4: 0x00000001, R5: 0x00000008, }), {R4: 0x00000011, R5: 0x00000008, }) self.assertEqual(compute('ADD R4, R4, R5 LSR 2 ', { - R4: 0x00000000L, R5: 0x80000041L, }), {R4: 0x20000010L, R5: 0x80000041L, }) + R4: 0x00000000, R5: 0x80000041, }), {R4: 0x20000010, R5: 0x80000041, }) self.assertEqual(compute('ADD R4, R4, R5 ASR 3 ', { - R4: 0x00000001L, R5: 0x80000081L, }), {R4: 0xF0000011L, R5: 0x80000081L, }) + R4: 0x00000001, R5: 0x80000081, }), {R4: 0xF0000011, R5: 0x80000081, }) self.assertEqual(compute('ADD R4, R4, R5 ROR 4 ', { - R4: 0xFFFFFFFFL, R5: 0x0000010FL, }), {R4: 0xF000000FL, R5: 0x0000010FL, }) + R4: 0xFFFFFFFF, R5: 0x0000010F, }), {R4: 0xF000000F, R5: 0x0000010F, }) self.assertEqual(compute('ADD R4, R4, R5 RRX ', { - cf: 1L, R4: 0xFFFFFFFFL, R5: 0x00000101L, }), {cf: 1L, R4: 0x8000007FL, R5: 0x00000101L, }) - self.assertEqual(compute('ADDS R4, R4, R5 ', {R4: 0xFFFFFFFFL, R5: 0x00000001L, }), { - nf: 0L, zf: 1L, cf: 1L, of: 0L, R4: 0x00000000L, R5: 0x00000001L, }) - self.assertEqual(compute('ADDS R4, R4, R5 LSL 1 ', {R4: 0x00000001L, R5: 0x00000008L, }), { - nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x00000011L, R5: 0x00000008L, }) - self.assertEqual(compute('ADDS R4, R4, R5 LSR 2 ', {R4: 0x00000000L, R5: 0x80000041L, }), { - nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x20000010L, R5: 0x80000041L, }) - self.assertEqual(compute('ADDS R4, R4, R5 ASR 3 ', {R4: 0x00000001L, R5: 0x80000081L, }), { - nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xF0000011L, R5: 0x80000081L, }) - self.assertEqual(compute('ADDS R4, R4, R5 ROR 4 ', {R4: 0xFFFFFFFFL, R5: 0x0000010FL, }), { - nf: 1L, zf: 0L, cf: 1L, of: 0L, R4: 0xF000000FL, R5: 0x0000010FL, }) - self.assertEqual(compute('ADDS R4, R4, R5 RRX ', {cf: 1L, R4: 0xFFFFFFFFL, R5: 0x00000101L, }), { - nf: 1L, zf: 0L, cf: 1L, of: 0L, R4: 0x8000007FL, R5: 0x00000101L, }) + cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {cf: 1, R4: 0x8000007F, R5: 0x00000101, }) + self.assertEqual(compute('ADDS R4, R4, R5 ', {R4: 0xFFFFFFFF, R5: 0x00000001, }), { + nf: 0, zf: 1, cf: 1, of: 0, R4: 0x00000000, R5: 0x00000001, }) + self.assertEqual(compute('ADDS R4, R4, R5 LSL 1 ', {R4: 0x00000001, R5: 0x00000008, }), { + nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000011, R5: 0x00000008, }) + self.assertEqual(compute('ADDS R4, R4, R5 LSR 2 ', {R4: 0x00000000, R5: 0x80000041, }), { + nf: 0, zf: 0, cf: 0, of: 0, R4: 0x20000010, R5: 0x80000041, }) + self.assertEqual(compute('ADDS R4, R4, R5 ASR 3 ', {R4: 0x00000001, R5: 0x80000081, }), { + nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF0000011, R5: 0x80000081, }) + self.assertEqual(compute('ADDS R4, R4, R5 ROR 4 ', {R4: 0xFFFFFFFF, R5: 0x0000010F, }), { + nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF000000F, R5: 0x0000010F, }) + self.assertEqual(compute('ADDS R4, R4, R5 RRX ', {cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), { + nf: 1, zf: 0, cf: 1, of: 0, R4: 0x8000007F, R5: 0x00000101, }) # SP special part self.assertEqual(compute('ADD R4, SP, R4 LSR 1 ', { - R4: 0x00000002L, SP: 0x00000000L, }), {R4: 0x00000001L, SP: 0x00000000L, }) + R4: 0x00000002, SP: 0x00000000, }), {R4: 0x00000001, SP: 0x00000000, }) # §A8.8.8: ADD{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>, <type> <Rs> self.assertEqual(compute('ADD R4, R6, R4 LSL R5', { - R4: 0x00000001L, R5: 0x00000004L, R6: 0L, }), {R4: 0x00000010L, R5: 0x00000004L, R6: 0L, }) + R4: 0x00000001, R5: 0x00000004, R6: 0, }), {R4: 0x00000010, R5: 0x00000004, R6: 0, }) self.assertEqual(compute('ADD R4, R6, R4 LSR R5', { - R4: 0x00000110L, R5: 0x80000004L, R6: 0L, }), {R4: 0x00000011L, R5: 0x80000004L, R6: 0L, }) + R4: 0x00000110, R5: 0x80000004, R6: 0, }), {R4: 0x00000011, R5: 0x80000004, R6: 0, }) self.assertEqual(compute('ADD R4, R6, R4 ASR R5', { - R4: 0x80000010L, R5: 0xF0000001L, R6: 0L, }), {R4: 0xC0000008L, R5: 0xF0000001L, R6: 0L, }) + R4: 0x80000010, R5: 0xF0000001, R6: 0, }), {R4: 0xC0000008, R5: 0xF0000001, R6: 0, }) self.assertEqual(compute('ADD R4, R6, R4 ROR R5', { - R4: 0x000000FFL, R5: 0x00000F04L, R6: 0L, }), {R4: 0xF000000FL, R5: 0x00000F04L, R6: 0L, }) - self.assertEqual(compute('ADDS R4, R6, R4 LSL R5', {R4: 0x00000001L, R5: 0x00000004L, R6: 0L, }), { - nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x00000010L, R5: 0x00000004L, R6: 0L, }) - self.assertEqual(compute('ADDS R4, R6, R4 LSR R5', {R4: 0x00000110L, R5: 0x80000004L, R6: 0L, }), { - nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x00000011L, R5: 0x80000004L, R6: 0L, }) - self.assertEqual(compute('ADDS R4, R6, R4 ASR R5', {R4: 0x80000010L, R5: 0xF0000001L, R6: 0L, }), { - nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xC0000008L, R5: 0xF0000001L, R6: 0L, }) - self.assertEqual(compute('ADDS R4, R6, R4 ROR R5', {R4: 0x000000FFL, R5: 0x00000F04L, R6: 0L, }), { - nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xF000000FL, R5: 0x00000F04L, R6: 0L, }) + R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {R4: 0xF000000F, R5: 0x00000F04, R6: 0, }) + self.assertEqual(compute('ADDS R4, R6, R4 LSL R5', {R4: 0x00000001, R5: 0x00000004, R6: 0, }), { + nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000010, R5: 0x00000004, R6: 0, }) + self.assertEqual(compute('ADDS R4, R6, R4 LSR R5', {R4: 0x00000110, R5: 0x80000004, R6: 0, }), { + nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000011, R5: 0x80000004, R6: 0, }) + self.assertEqual(compute('ADDS R4, R6, R4 ASR R5', {R4: 0x80000010, R5: 0xF0000001, R6: 0, }), { + nf: 1, zf: 0, cf: 0, of: 0, R4: 0xC0000008, R5: 0xF0000001, R6: 0, }) + self.assertEqual(compute('ADDS R4, R6, R4 ROR R5', {R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), { + nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF000000F, R5: 0x00000F04, R6: 0, }) # Test against qemu - self.assertEqual(compute('ADDS R3, R2, R3 ', {R2: 0x1L, R3: 0x1L}), - { nf: 0L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000001L, R3: 0x00000002L}) - self.assertEqual(compute('ADDS R3, R2, R3 ', {R2: 0x1L, R3: 0x7FFFFFFFL}), - { nf: 1L, zf: 0L, cf: 0L, of: 1L, R2: 0x00000001L, R3: 0x80000000L}) - self.assertEqual(compute('ADDS R3, R2, R3 ', {R2: 0x80000000L, R3: 0x80000000L}), - { nf: 0L, zf: 1L, cf: 1L, of: 1L, R2: 0x80000000L, R3: 0x00000000L}) - self.assertEqual(compute('ADDS R3, R2, R3 ', {R2: 0x7FFFFFFFL, R3:0x7FFFFFFFL}), - { nf: 1L, zf: 0L, cf: 0L, of: 1L, R2: 0x7FFFFFFFL, R3:0xFFFFFFFEL}) - self.assertEqual(compute('ADDS R3, R2, R3 ', {R2: 0L, R3:0}), - { nf: 0L, zf: 1L, cf: 0L, of: 0L, R2: 0L, R3:0}) - self.assertEqual(compute('ADDS R3, R2, R3 ', {R2: 0xFFFFFFFFL, R3:0xFFFFFFFFL}), - { nf: 1L, zf: 0L, cf: 1L, of: 0L, R2: 0xFFFFFFFFL, R3:0xFFFFFFFEL}) + self.assertEqual(compute('ADDS R3, R2, R3 ', {R2: 0x1, R3: 0x1}), + { nf: 0, zf: 0, cf: 0, of: 0, R2: 0x00000001, R3: 0x00000002}) + self.assertEqual(compute('ADDS R3, R2, R3 ', {R2: 0x1, R3: 0x7FFFFFFF}), + { nf: 1, zf: 0, cf: 0, of: 1, R2: 0x00000001, R3: 0x80000000}) + self.assertEqual(compute('ADDS R3, R2, R3 ', {R2: 0x80000000, R3: 0x80000000}), + { nf: 0, zf: 1, cf: 1, of: 1, R2: 0x80000000, R3: 0x00000000}) + self.assertEqual(compute('ADDS R3, R2, R3 ', {R2: 0x7FFFFFFF, R3:0x7FFFFFFF}), + { nf: 1, zf: 0, cf: 0, of: 1, R2: 0x7FFFFFFF, R3:0xFFFFFFFE}) + self.assertEqual(compute('ADDS R3, R2, R3 ', {R2: 0, R3:0}), + { nf: 0, zf: 1, cf: 0, of: 0, R2: 0, R3:0}) + self.assertEqual(compute('ADDS R3, R2, R3 ', {R2: 0xFFFFFFFF, R3:0xFFFFFFFF}), + { nf: 1, zf: 0, cf: 1, of: 0, R2: 0xFFFFFFFF, R3:0xFFFFFFFE}) @@ -275,26 +278,26 @@ class TestARMSemantic(unittest.TestCase): # §A8.8.13: AND{S}{<c>}{<q>} {<Rd>,} <Rn>, #<const> self.assertRaises( ValueError, compute, 'AND R4, 0x00000001 ') - self.assertEqual(compute('AND R4, R4, 0x00000001 ', {R4: 0xDEADBEEFL, }), {R4: 0x00000001L, }) - self.assertEqual(compute('AND R4, R4, 0x00000000 ', {R4: 0x00000000L, }), {R4: 0x00000000L, }) - self.assertEqual(compute('AND PC, R4, 0x00000001 ', {R4: 0xFFFFFFFFL, PC: 0x55555555L, }), {R4: 0xFFFFFFFFL, PC: 0x00000001L, }) - self.assertEqual(compute('AND PC, R4, 0x00000000 ', {R4: 0xFFFFFFFFL, PC: 0x55555555L, }), {R4: 0xFFFFFFFFL, PC: 0x00000000L, }) + self.assertEqual(compute('AND R4, R4, 0x00000001 ', {R4: 0xDEADBEEF, }), {R4: 0x00000001, }) + self.assertEqual(compute('AND R4, R4, 0x00000000 ', {R4: 0x00000000, }), {R4: 0x00000000, }) + self.assertEqual(compute('AND PC, R4, 0x00000001 ', {R4: 0xFFFFFFFF, PC: 0x55555555, }), {R4: 0xFFFFFFFF, PC: 0x00000001, }) + self.assertEqual(compute('AND PC, R4, 0x00000000 ', {R4: 0xFFFFFFFF, PC: 0x55555555, }), {R4: 0xFFFFFFFF, PC: 0x00000000, }) # §A8.8.14: AND{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {,<shift>} self.assertRaises( ValueError, compute, 'AND R4, R5 ') - self.assertEqual(compute('AND R4, R4, R5 ', {R4: 0xFFFFFFFEL, R5: 0x00000001L, }), {R4: 0x00000000L, R5: 0x00000001L, }) - self.assertEqual(compute('AND R4, R4, R5 LSL 1 ', {R4: 0x00000011L, R5: 0x00000008L, }), {R4: 0x00000010L, R5: 0x00000008L, }) - self.assertEqual(compute('AND R4, R4, R5 LSR 2 ', {R4: 0xFFFFFFFFL, R5: 0x80000041L, }), {R4: 0x20000010L, R5: 0x80000041L, }) - self.assertEqual(compute('AND R4, R4, R5 ASR 3 ', {R4: 0xF00000FFL, R5: 0x80000081L, }), {R4: 0xF0000010L, R5: 0x80000081L, }) - self.assertEqual(compute('AND R4, R4, R5 ROR 4 ', {R4: 0xFFFFFFFFL, R5: 0x000000FFL, }), {R4: 0xF000000FL, R5: 0x000000FFL, }) - self.assertEqual(compute('AND R4, R4, R5 RRX ', {R4: 0xFFFFFFFFL, R5: 0x00000101L, }), {R4: ExprCompose(ExprInt(0x80L, 31), cf_init), R5: 0x00000101L, }) + self.assertEqual(compute('AND R4, R4, R5 ', {R4: 0xFFFFFFFE, R5: 0x00000001, }), {R4: 0x00000000, R5: 0x00000001, }) + self.assertEqual(compute('AND R4, R4, R5 LSL 1 ', {R4: 0x00000011, R5: 0x00000008, }), {R4: 0x00000010, R5: 0x00000008, }) + self.assertEqual(compute('AND R4, R4, R5 LSR 2 ', {R4: 0xFFFFFFFF, R5: 0x80000041, }), {R4: 0x20000010, R5: 0x80000041, }) + self.assertEqual(compute('AND R4, R4, R5 ASR 3 ', {R4: 0xF00000FF, R5: 0x80000081, }), {R4: 0xF0000010, R5: 0x80000081, }) + self.assertEqual(compute('AND R4, R4, R5 ROR 4 ', {R4: 0xFFFFFFFF, R5: 0x000000FF, }), {R4: 0xF000000F, R5: 0x000000FF, }) + self.assertEqual(compute('AND R4, R4, R5 RRX ', {R4: 0xFFFFFFFF, R5: 0x00000101, }), {R4: ExprCompose(ExprInt(0x80, 31), cf_init), R5: 0x00000101, }) # §A8.8.15: AND{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>, <type> <Rs> - self.assertEqual(compute('AND R4, R6, R4 LSL R5', {R4: 0x00000001L, R5: 0x00000004L, R6: -1, }), {R4: 0x00000010L, R5: 0x00000004L, R6: 0xFFFFFFFFL, }) - self.assertEqual(compute('AND R4, R6, R4 LSR R5', {R4: 0x00000110L, R5: 0x80000004L, R6: -1, }), {R4: 0x00000011L, R5: 0x80000004L, R6: 0xFFFFFFFFL, }) - self.assertEqual(compute('AND R4, R6, R4 ASR R5', {R4: 0x80000010L, R5: 0xF0000001L, R6: -1, }), {R4: 0xC0000008L, R5: 0xF0000001L, R6: 0xFFFFFFFFL, }) - self.assertEqual(compute('AND R4, R6, R4 ROR R5', {R4: 0x000000FFL, R5: 0x00000F04L, R6: -1, }), {R4: 0xF000000FL, R5: 0x00000F04L, R6: 0xFFFFFFFFL, }) + self.assertEqual(compute('AND R4, R6, R4 LSL R5', {R4: 0x00000001, R5: 0x00000004, R6: -1, }), {R4: 0x00000010, R5: 0x00000004, R6: 0xFFFFFFFF, }) + self.assertEqual(compute('AND R4, R6, R4 LSR R5', {R4: 0x00000110, R5: 0x80000004, R6: -1, }), {R4: 0x00000011, R5: 0x80000004, R6: 0xFFFFFFFF, }) + self.assertEqual(compute('AND R4, R6, R4 ASR R5', {R4: 0x80000010, R5: 0xF0000001, R6: -1, }), {R4: 0xC0000008, R5: 0xF0000001, R6: 0xFFFFFFFF, }) + self.assertEqual(compute('AND R4, R6, R4 ROR R5', {R4: 0x000000FF, R5: 0x00000F04, R6: -1, }), {R4: 0xF000000F, R5: 0x00000F04, R6: 0xFFFFFFFF, }) def test_ASR(self): # §A8.8.16: ASR{S}{<c>}{<q>} {<Rd>,} <Rm>, #<imm> <==> MOV{S}{<c>}{<q>} {<Rd>,} <Rm>, ASR #<n> @@ -305,191 +308,191 @@ class TestARMSemantic(unittest.TestCase): def test_SUBS(self): # Test against qemu - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x2L, R3: 0x1L}), - { nf: 0L, zf: 0L, cf: 1L, of: 0L, R2: 0x00000002L, R3: 0x1L}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x1L, R3: 0x2L}), - { nf: 1L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000001L, R3: 0xFFFFFFFFL}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x0L, R3: 0xFFFFFFFFL}), - { nf: 0L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000000L, R3: 0x1L}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0xFFFFFFFFL, R3: 0x0L}), - { nf: 1L, zf: 0L, cf: 1L, of: 0L, R2: 0xFFFFFFFFL, R3: 0xFFFFFFFFL}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x1L, R3: 0x7FFFFFFFL}), - { nf: 1L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000001L, R3: 0x80000002L}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x7FFFFFFFL, R3: 0x1L}), - { nf: 0L, zf: 0L, cf: 1L, of: 0L, R2: 0x7FFFFFFFL, R3: 0x7FFFFFFEL}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x80000000L, R3: 0x80000001L}), - { nf: 1L, zf: 0L, cf: 0L, of: 0L, R2: 0x80000000L, R3: 0xFFFFFFFFL}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x80000001L, R3: 0x80000000L}), - { nf: 0L, zf: 0L, cf: 1L, of: 0L, R2: 0x80000001L, R3: 0x1L}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x2, R3: 0x1}), + { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x00000002, R3: 0x1}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x1, R3: 0x2}), + { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x00000001, R3: 0xFFFFFFFF}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x0, R3: 0xFFFFFFFF}), + { nf: 0, zf: 0, cf: 0, of: 0, R2: 0x00000000, R3: 0x1}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0xFFFFFFFF, R3: 0x0}), + { nf: 1, zf: 0, cf: 1, of: 0, R2: 0xFFFFFFFF, R3: 0xFFFFFFFF}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x1, R3: 0x7FFFFFFF}), + { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x00000001, R3: 0x80000002}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x7FFFFFFF, R3: 0x1}), + { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x7FFFFFFF, R3: 0x7FFFFFFE}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x80000000, R3: 0x80000001}), + { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x80000000, R3: 0xFFFFFFFF}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x80000001, R3: 0x80000000}), + { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x80000001, R3: 0x1}) def test_CMP(self): # Test against qemu - self.assertEqual(compute('CMP R0, R1 ', {R0: 0x11223344L, R1: 0x88223344L}), - { nf: 1L, zf: 0L, cf: 0L, of: 1L, R0: 0x11223344L, R1: 0x88223344L}) - - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x2L, R3: 0x1L}), - { nf: 0L, zf: 0L, cf: 1L, of: 0L, R2: 0x00000002L, R3: 0x1L}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x1L, R3: 0x2L}), - { nf: 1L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000001L, R3: 0xFFFFFFFFL}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x0L, R3: 0xFFFFFFFFL}), - { nf: 0L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000000L, R3: 0x1L}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0xFFFFFFFFL, R3: 0x0L}), - { nf: 1L, zf: 0L, cf: 1L, of: 0L, R2: 0xFFFFFFFFL, R3: 0xFFFFFFFFL}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x1L, R3: 0x7FFFFFFFL}), - { nf: 1L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000001L, R3: 0x80000002L}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x7FFFFFFFL, R3: 0x1L}), - { nf: 0L, zf: 0L, cf: 1L, of: 0L, R2: 0x7FFFFFFFL, R3: 0x7FFFFFFEL}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x80000000L, R3: 0x80000001L}), - { nf: 1L, zf: 0L, cf: 0L, of: 0L, R2: 0x80000000L, R3: 0xFFFFFFFFL}) - self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x80000001L, R3: 0x80000000L}), - { nf: 0L, zf: 0L, cf: 1L, of: 0L, R2: 0x80000001L, R3: 0x1L}) + self.assertEqual(compute('CMP R0, R1 ', {R0: 0x11223344, R1: 0x88223344}), + { nf: 1, zf: 0, cf: 0, of: 1, R0: 0x11223344, R1: 0x88223344}) + + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x2, R3: 0x1}), + { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x00000002, R3: 0x1}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x1, R3: 0x2}), + { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x00000001, R3: 0xFFFFFFFF}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x0, R3: 0xFFFFFFFF}), + { nf: 0, zf: 0, cf: 0, of: 0, R2: 0x00000000, R3: 0x1}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0xFFFFFFFF, R3: 0x0}), + { nf: 1, zf: 0, cf: 1, of: 0, R2: 0xFFFFFFFF, R3: 0xFFFFFFFF}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x1, R3: 0x7FFFFFFF}), + { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x00000001, R3: 0x80000002}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x7FFFFFFF, R3: 0x1}), + { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x7FFFFFFF, R3: 0x7FFFFFFE}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x80000000, R3: 0x80000001}), + { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x80000000, R3: 0xFFFFFFFF}) + self.assertEqual(compute('SUBS R3, R2, R3 ', {R2: 0x80000001, R3: 0x80000000}), + { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x80000001, R3: 0x1}) def test_ADDS(self): - self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {R2: 0x3L, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L}) - self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {R2: 0x3L, R3: 0x2L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L}) - self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {R2: 0xffffffffL, R3: 0xffffffffL, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {R2: 0xffffffffL, R3: 0x0L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {R2: 0x80000000L, R3: 0x7fffffffL, of: 0x1L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {R2: 0x80000000L, R3: 0x1L, of: 0x1L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {R2: 0x1L, R3: 0x80000001L, of: 0x1L, zf: 0x0L, cf: 0x1L, nf: 0x0L}) - self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {R2: 0x1L, R3: 0x80000000L, of: 0x1L, zf: 0x0L, cf: 0x1L, nf: 0x0L}) + self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x2, R3: 0x1}), {R2: 0x3, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0}) + self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x1, R3: 0x2}), {R2: 0x3, R3: 0x2, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0}) + self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {R2: 0xffffffff, R3: 0xffffffff, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {R2: 0xffffffff, R3: 0x0, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {R2: 0x80000000, R3: 0x7fffffff, of: 0x1, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {R2: 0x80000000, R3: 0x1, of: 0x1, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {R2: 0x1, R3: 0x80000001, of: 0x1, zf: 0x0, cf: 0x1, nf: 0x0}) + self.assertEqual(compute('ADDS R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {R2: 0x1, R3: 0x80000000, of: 0x1, zf: 0x0, cf: 0x1, nf: 0x0}) def test_ANDS(self): - self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0x2L}) - self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0xffffffffL}) - self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0x0L}) - self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x7fffffffL}) - self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x0L, R2: 0x80000000L, nf: 0x1L, R3: 0x80000001L}) - self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x80000000L, nf: 0x1L, R3: 0x80000000L}) + self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0x2}) + self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0xffffffff}) + self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0x0}) + self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x7fffffff}) + self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x0, R2: 0x80000000, nf: 0x1, R3: 0x80000001}) + self.assertEqual(compute('ANDS R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x80000000, nf: 0x1, R3: 0x80000000}) def test_BICS(self): - self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x0L, R2: 0x2L, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x2L}) - self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0xffffffffL}) - self.assertEqual(compute('BICS R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x0L, R2: 0xffffffffL, nf: 0x1L, R3: 0x0L}) - self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0x7fffffffL}) - self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x7ffffffeL, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0x80000001L}) - self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x80000000L}) + self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x0, R2: 0x2, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x2}) + self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0xffffffff}) + self.assertEqual(compute('BICS R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x0, R2: 0xffffffff, nf: 0x1, R3: 0x0}) + self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0x7fffffff}) + self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x7ffffffe, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0x80000001}) + self.assertEqual(compute('BICS R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x80000000}) def test_CMN(self): - self.assertEqual(compute('CMN R2, R3', {R2: 0x2L, R3: 0x1L}), {R2: 0x2L, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L}) - self.assertEqual(compute('CMN R2, R3', {R2: 0x1L, R3: 0x2L}), {R2: 0x1L, R3: 0x2L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L}) - self.assertEqual(compute('CMN R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {R2: 0x0L, R3: 0xffffffffL, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('CMN R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {R2: 0xffffffffL, R3: 0x0L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('CMN R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {R2: 0x1L, R3: 0x7fffffffL, of: 0x1L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('CMN R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {R2: 0x7fffffffL, R3: 0x1L, of: 0x1L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('CMN R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {R2: 0x80000000L, R3: 0x80000001L, of: 0x1L, zf: 0x0L, cf: 0x1L, nf: 0x0L}) - self.assertEqual(compute('CMN R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {R2: 0x80000001L, R3: 0x80000000L, of: 0x1L, zf: 0x0L, cf: 0x1L, nf: 0x0L}) + self.assertEqual(compute('CMN R2, R3', {R2: 0x2, R3: 0x1}), {R2: 0x2, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0}) + self.assertEqual(compute('CMN R2, R3', {R2: 0x1, R3: 0x2}), {R2: 0x1, R3: 0x2, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0}) + self.assertEqual(compute('CMN R2, R3', {R2: 0x0, R3: 0xffffffff}), {R2: 0x0, R3: 0xffffffff, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('CMN R2, R3', {R2: 0xffffffff, R3: 0x0}), {R2: 0xffffffff, R3: 0x0, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('CMN R2, R3', {R2: 0x1, R3: 0x7fffffff}), {R2: 0x1, R3: 0x7fffffff, of: 0x1, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('CMN R2, R3', {R2: 0x7fffffff, R3: 0x1}), {R2: 0x7fffffff, R3: 0x1, of: 0x1, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('CMN R2, R3', {R2: 0x80000000, R3: 0x80000001}), {R2: 0x80000000, R3: 0x80000001, of: 0x1, zf: 0x0, cf: 0x1, nf: 0x0}) + self.assertEqual(compute('CMN R2, R3', {R2: 0x80000001, R3: 0x80000000}), {R2: 0x80000001, R3: 0x80000000, of: 0x1, zf: 0x0, cf: 0x1, nf: 0x0}) def test_CMP(self): - self.assertEqual(compute('CMP R2, R3', {R2: 0x2L, R3: 0x1L}), {R2: 0x2L, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L}) - self.assertEqual(compute('CMP R2, R3', {R2: 0x1L, R3: 0x2L}), {R2: 0x1L, R3: 0x2L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('CMP R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {R2: 0x0L, R3: 0xffffffffL, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L}) - self.assertEqual(compute('CMP R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {R2: 0xffffffffL, R3: 0x0L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x1L}) - self.assertEqual(compute('CMP R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {R2: 0x1L, R3: 0x7fffffffL, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('CMP R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {R2: 0x7fffffffL, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L}) - self.assertEqual(compute('CMP R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {R2: 0x80000000L, R3: 0x80000001L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('CMP R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {R2: 0x80000001L, R3: 0x80000000L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L}) + self.assertEqual(compute('CMP R2, R3', {R2: 0x2, R3: 0x1}), {R2: 0x2, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0}) + self.assertEqual(compute('CMP R2, R3', {R2: 0x1, R3: 0x2}), {R2: 0x1, R3: 0x2, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('CMP R2, R3', {R2: 0x0, R3: 0xffffffff}), {R2: 0x0, R3: 0xffffffff, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0}) + self.assertEqual(compute('CMP R2, R3', {R2: 0xffffffff, R3: 0x0}), {R2: 0xffffffff, R3: 0x0, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x1}) + self.assertEqual(compute('CMP R2, R3', {R2: 0x1, R3: 0x7fffffff}), {R2: 0x1, R3: 0x7fffffff, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('CMP R2, R3', {R2: 0x7fffffff, R3: 0x1}), {R2: 0x7fffffff, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0}) + self.assertEqual(compute('CMP R2, R3', {R2: 0x80000000, R3: 0x80000001}), {R2: 0x80000000, R3: 0x80000001, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('CMP R2, R3', {R2: 0x80000001, R3: 0x80000000}), {R2: 0x80000001, R3: 0x80000000, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0}) def test_EORS(self): - self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x0L, R2: 0x3L, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x0L, R2: 0x3L, nf: 0x0L, R3: 0x2L}) - self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x0L, R2: 0xffffffffL, nf: 0x1L, R3: 0xffffffffL}) - self.assertEqual(compute('EORS R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x0L, R2: 0xffffffffL, nf: 0x1L, R3: 0x0L}) - self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x0L, R2: 0x7ffffffeL, nf: 0x0L, R3: 0x7fffffffL}) - self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x7ffffffeL, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x80000001L}) - self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x80000000L}) + self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x0, R2: 0x3, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x0, R2: 0x3, nf: 0x0, R3: 0x2}) + self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x0, R2: 0xffffffff, nf: 0x1, R3: 0xffffffff}) + self.assertEqual(compute('EORS R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x0, R2: 0xffffffff, nf: 0x1, R3: 0x0}) + self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x0, R2: 0x7ffffffe, nf: 0x0, R3: 0x7fffffff}) + self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x7ffffffe, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x80000001}) + self.assertEqual(compute('EORS R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x80000000}) def test_MULS(self): - self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x0L, R2: 0x2L, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x0L, R2: 0x2L, nf: 0x0L, R3: 0x2L}) - self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0xffffffffL}) - self.assertEqual(compute('MULS R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0x0L}) - self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x0L, R2: 0x7fffffffL, nf: 0x0L, R3: 0x7fffffffL}) - self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x7fffffffL, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x0L, R2: 0x80000000L, nf: 0x1L, R3: 0x80000001L}) - self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x80000000L, nf: 0x1L, R3: 0x80000000L}) + self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x0, R2: 0x2, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x0, R2: 0x2, nf: 0x0, R3: 0x2}) + self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0xffffffff}) + self.assertEqual(compute('MULS R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0x0}) + self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x0, R2: 0x7fffffff, nf: 0x0, R3: 0x7fffffff}) + self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x7fffffff, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x0, R2: 0x80000000, nf: 0x1, R3: 0x80000001}) + self.assertEqual(compute('MULS R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x80000000, nf: 0x1, R3: 0x80000000}) def test_ORRS(self): - self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x0L, R2: 0x3L, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x0L, R2: 0x3L, nf: 0x0L, R3: 0x2L}) - self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x0L, R2: 0xffffffffL, nf: 0x1L, R3: 0xffffffffL}) - self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x0L, R2: 0xffffffffL, nf: 0x1L, R3: 0x0L}) - self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x0L, R2: 0x7fffffffL, nf: 0x0L, R3: 0x7fffffffL}) - self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x7fffffffL, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x0L, R2: 0x80000001L, nf: 0x1L, R3: 0x80000001L}) - self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x80000001L, nf: 0x1L, R3: 0x80000000L}) + self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x0, R2: 0x3, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x0, R2: 0x3, nf: 0x0, R3: 0x2}) + self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x0, R2: 0xffffffff, nf: 0x1, R3: 0xffffffff}) + self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x0, R2: 0xffffffff, nf: 0x1, R3: 0x0}) + self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x0, R2: 0x7fffffff, nf: 0x0, R3: 0x7fffffff}) + self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x7fffffff, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x0, R2: 0x80000001, nf: 0x1, R3: 0x80000001}) + self.assertEqual(compute('ORRS R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x80000001, nf: 0x1, R3: 0x80000000}) def test_RSBS(self): - self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {R2: 0xffffffffL, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {R2: 0x1L, R3: 0x2L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L}) - self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {R2: 0xffffffffL, R3: 0xffffffffL, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x1L}) - self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {R2: 0x1L, R3: 0x0L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L}) - self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {R2: 0x7ffffffeL, R3: 0x7fffffffL, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L}) - self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {R2: 0x80000002L, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {R2: 0x1L, R3: 0x80000001L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L}) - self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {R2: 0xffffffffL, R3: 0x80000000L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) + self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x2, R3: 0x1}), {R2: 0xffffffff, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x1, R3: 0x2}), {R2: 0x1, R3: 0x2, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0}) + self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {R2: 0xffffffff, R3: 0xffffffff, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x1}) + self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {R2: 0x1, R3: 0x0, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0}) + self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {R2: 0x7ffffffe, R3: 0x7fffffff, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0}) + self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {R2: 0x80000002, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {R2: 0x1, R3: 0x80000001, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0}) + self.assertEqual(compute('RSBS R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {R2: 0xffffffff, R3: 0x80000000, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1}) def test_SUBS(self): - self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {R2: 0x1L, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L}) - self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {R2: 0xffffffffL, R3: 0x2L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {R2: 0x1L, R3: 0xffffffffL, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L}) - self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {R2: 0xffffffffL, R3: 0x0L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x1L}) - self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {R2: 0x80000002L, R3: 0x7fffffffL, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {R2: 0x7ffffffeL, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L}) - self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {R2: 0xffffffffL, R3: 0x80000001L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L}) - self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {R2: 0x1L, R3: 0x80000000L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L}) + self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x2, R3: 0x1}), {R2: 0x1, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0}) + self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x1, R3: 0x2}), {R2: 0xffffffff, R3: 0x2, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {R2: 0x1, R3: 0xffffffff, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0}) + self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {R2: 0xffffffff, R3: 0x0, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x1}) + self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {R2: 0x80000002, R3: 0x7fffffff, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {R2: 0x7ffffffe, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0}) + self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {R2: 0xffffffff, R3: 0x80000001, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1}) + self.assertEqual(compute('SUBS R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {R2: 0x1, R3: 0x80000000, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0}) def test_TEQ(self): - self.assertEqual(compute('TEQ R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x0L, R2: 0x2L, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('TEQ R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x2L}) - self.assertEqual(compute('TEQ R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x0L, R2: 0x0L, nf: 0x1L, R3: 0xffffffffL}) - self.assertEqual(compute('TEQ R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x0L, R2: 0xffffffffL, nf: 0x1L, R3: 0x0L}) - self.assertEqual(compute('TEQ R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x7fffffffL}) - self.assertEqual(compute('TEQ R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x7fffffffL, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('TEQ R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x0L, R2: 0x80000000L, nf: 0x0L, R3: 0x80000001L}) - self.assertEqual(compute('TEQ R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x80000001L, nf: 0x0L, R3: 0x80000000L}) + self.assertEqual(compute('TEQ R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x0, R2: 0x2, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('TEQ R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x2}) + self.assertEqual(compute('TEQ R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x0, R2: 0x0, nf: 0x1, R3: 0xffffffff}) + self.assertEqual(compute('TEQ R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x0, R2: 0xffffffff, nf: 0x1, R3: 0x0}) + self.assertEqual(compute('TEQ R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x7fffffff}) + self.assertEqual(compute('TEQ R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x7fffffff, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('TEQ R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x0, R2: 0x80000000, nf: 0x0, R3: 0x80000001}) + self.assertEqual(compute('TEQ R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x80000001, nf: 0x0, R3: 0x80000000}) def test_TST(self): - self.assertEqual(compute('TST R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x1L, R2: 0x2L, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('TST R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x1L, R2: 0x1L, nf: 0x0L, R3: 0x2L}) - self.assertEqual(compute('TST R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0xffffffffL}) - self.assertEqual(compute('TST R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x1L, R2: 0xffffffffL, nf: 0x0L, R3: 0x0L}) - self.assertEqual(compute('TST R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x7fffffffL}) - self.assertEqual(compute('TST R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x7fffffffL, nf: 0x0L, R3: 0x1L}) - self.assertEqual(compute('TST R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x0L, R2: 0x80000000L, nf: 0x1L, R3: 0x80000001L}) - self.assertEqual(compute('TST R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x80000001L, nf: 0x1L, R3: 0x80000000L}) + self.assertEqual(compute('TST R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x1, R2: 0x2, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('TST R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x1, R2: 0x1, nf: 0x0, R3: 0x2}) + self.assertEqual(compute('TST R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0xffffffff}) + self.assertEqual(compute('TST R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x1, R2: 0xffffffff, nf: 0x0, R3: 0x0}) + self.assertEqual(compute('TST R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x7fffffff}) + self.assertEqual(compute('TST R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x7fffffff, nf: 0x0, R3: 0x1}) + self.assertEqual(compute('TST R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x0, R2: 0x80000000, nf: 0x1, R3: 0x80000001}) + self.assertEqual(compute('TST R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x80000001, nf: 0x1, R3: 0x80000000}) def test_UMUL(self): - self.assertEqual(compute('UMULL R1, R2, R4, R5', {R4: 0x0L, R5: 0x0L}), {R1: 0x0L, R2: 0x0L, R4: 0x0L, R5: 0x0L}) - self.assertEqual(compute('UMULL R0, R1, R2, R3', {R2: 0x1L, R3: 0x80808080L}), {R0: 0x80808080L, R1: 0x0L, R2: 0x1L, R3: 0x80808080L}) - self.assertEqual(compute('UMULL R2, R3, R4, R5', {R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d78L, R3: 0x09a0cd05L, R4: 0x12345678L, R5: 0x87654321L}) - self.assertEqual(compute('UMULL R2, R3, R4, R5', {R4: 0xffffffffL, R5: 0x00000002L}), {R2: 0xfffffffeL, R3: 0x00000001L, R4: 0xffffffffL, R5: 0x00000002L}) + self.assertEqual(compute('UMULL R1, R2, R4, R5', {R4: 0x0, R5: 0x0}), {R1: 0x0, R2: 0x0, R4: 0x0, R5: 0x0}) + self.assertEqual(compute('UMULL R0, R1, R2, R3', {R2: 0x1, R3: 0x80808080}), {R0: 0x80808080, R1: 0x0, R2: 0x1, R3: 0x80808080}) + self.assertEqual(compute('UMULL R2, R3, R4, R5', {R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d78, R3: 0x09a0cd05, R4: 0x12345678, R5: 0x87654321}) + self.assertEqual(compute('UMULL R2, R3, R4, R5', {R4: 0xffffffff, R5: 0x00000002}), {R2: 0xfffffffe, R3: 0x00000001, R4: 0xffffffff, R5: 0x00000002}) def test_UMLAL(self): - self.assertEqual(compute('UMLAL R1, R2, R4, R5', {R1: 0x0L, R2: 0x0L, R4: 0x1L, R5: 0x0L}), {R1: 0x0L, R2: 0x0L, R4: 0x1L, R5: 0x0L}) - self.assertEqual(compute('UMLAL R0, R1, R2, R3', {R0: 0x0L, R1: 0x0L, R2: 0x1L, R3: 0x80808080L}), {R0: 0x80808080L, R1: 0x0L, R2: 0x1L, R3: 0x80808080L}) - self.assertEqual(compute('UMLAL R2, R3, R4, R5', {R2: 0xffffffffL, R3: 0x0L, R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d77L, R3: 0x09a0cd06L, R4: 0x12345678L, R5: 0x87654321L}) - self.assertEqual(compute('UMLAL R2, R3, R4, R5', {R2: 0xffffffffL, R3: 0x2L, R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d77L, R3: 0x09a0cd08L, R4: 0x12345678L, R5: 0x87654321L}) + self.assertEqual(compute('UMLAL R1, R2, R4, R5', {R1: 0x0, R2: 0x0, R4: 0x1, R5: 0x0}), {R1: 0x0, R2: 0x0, R4: 0x1, R5: 0x0}) + self.assertEqual(compute('UMLAL R0, R1, R2, R3', {R0: 0x0, R1: 0x0, R2: 0x1, R3: 0x80808080}), {R0: 0x80808080, R1: 0x0, R2: 0x1, R3: 0x80808080}) + self.assertEqual(compute('UMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x0, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0x09a0cd06, R4: 0x12345678, R5: 0x87654321}) + self.assertEqual(compute('UMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x2, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0x09a0cd08, R4: 0x12345678, R5: 0x87654321}) def test_SMUL(self): - self.assertEqual(compute('SMULL R1, R2, R4, R5', {R4: 0x0L, R5: 0x0L}), {R1: 0x0L, R2: 0x0L, R4: 0x0L, R5: 0x0L}) - self.assertEqual(compute('SMULL R0, R1, R2, R3', {R2: 0x1L, R3: 0x80808080L}), {R0: 0x80808080L, R1: 0xffffffffL, R2: 0x1L, R3: 0x80808080L}) - self.assertEqual(compute('SMULL R0, R1, R2, R3', {R2: 0xffff0000L, R3: 0xffff0000L}), {R0: 0x0L, R1: 0x1L, R2: 0xffff0000L, R3: 0xffff0000L}) - self.assertEqual(compute('SMULL R2, R3, R4, R5', {R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d78L, R3: 0xf76c768dL, R4: 0x12345678L, R5: 0x87654321L}) - self.assertEqual(compute('SMULL R2, R3, R4, R5', {R4: 0xffffffffL, R5: 0x00000002L}), {R2: 0xfffffffeL, R3: 0xffffffffL, R4: 0xffffffffL, R5: 0x00000002L}) + self.assertEqual(compute('SMULL R1, R2, R4, R5', {R4: 0x0, R5: 0x0}), {R1: 0x0, R2: 0x0, R4: 0x0, R5: 0x0}) + self.assertEqual(compute('SMULL R0, R1, R2, R3', {R2: 0x1, R3: 0x80808080}), {R0: 0x80808080, R1: 0xffffffff, R2: 0x1, R3: 0x80808080}) + self.assertEqual(compute('SMULL R0, R1, R2, R3', {R2: 0xffff0000, R3: 0xffff0000}), {R0: 0x0, R1: 0x1, R2: 0xffff0000, R3: 0xffff0000}) + self.assertEqual(compute('SMULL R2, R3, R4, R5', {R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d78, R3: 0xf76c768d, R4: 0x12345678, R5: 0x87654321}) + self.assertEqual(compute('SMULL R2, R3, R4, R5', {R4: 0xffffffff, R5: 0x00000002}), {R2: 0xfffffffe, R3: 0xffffffff, R4: 0xffffffff, R5: 0x00000002}) def test_SMLAL(self): - self.assertEqual(compute('SMLAL R1, R2, R4, R5', {R1: 0x0L, R2: 0x0L, R4: 0x1L, R5: 0x0L}), {R1: 0x0L, R2: 0x0L, R4: 0x1L, R5: 0x0L}) - self.assertEqual(compute('SMLAL R0, R1, R2, R3', {R0: 0x0L, R1: 0x0L, R2: 0x1L, R3: 0x80808080L}), {R0: 0x80808080L, R1: 0xffffffffL, R2: 0x1L, R3: 0x80808080L}) - self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffffL, R3: 0x0L, R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d77L, R3: 0xf76c768eL, R4: 0x12345678L, R5: 0x87654321L}) - self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffffL, R3: 0x00000002L, R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d77L, R3: 0xf76c7690L, R4: 0x12345678L, R5: 0x87654321L}) + self.assertEqual(compute('SMLAL R1, R2, R4, R5', {R1: 0x0, R2: 0x0, R4: 0x1, R5: 0x0}), {R1: 0x0, R2: 0x0, R4: 0x1, R5: 0x0}) + self.assertEqual(compute('SMLAL R0, R1, R2, R3', {R0: 0x0, R1: 0x0, R2: 0x1, R3: 0x80808080}), {R0: 0x80808080, R1: 0xffffffff, R2: 0x1, R3: 0x80808080}) + self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x0, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0xf76c768e, R4: 0x12345678, R5: 0x87654321}) + self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x00000002, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0xf76c7690, R4: 0x12345678, R5: 0x87654321}) if __name__ == '__main__': testsuite = unittest.TestLoader().loadTestsFromTestCase(TestARMSemantic) diff --git a/test/arch/mep/asm/test_asm.py b/test/arch/mep/asm/test_asm.py index ddf91ed6..217def86 100644 --- a/test/arch/mep/asm/test_asm.py +++ b/test/arch/mep/asm/test_asm.py @@ -1,9 +1,11 @@ # Toshiba MeP-c4 - Misc unit tests # Guillaume Valadon <guillaume@valadon.net> +from __future__ import print_function +from miasm2.core.utils import decode_hex, encode_hex from miasm2.arch.mep.arch import mn_mep -class TestMisc: +class TestMisc(object): def test(self): @@ -18,21 +20,23 @@ class TestMisc: unit_tests += [("SW R7, 0x50(SP)", "4752")] for mn_str, mn_hex in unit_tests: - print "-" * 49 # Tests separation + print("-" * 49) # Tests separation # Dissassemble - mn_bin = mn_hex.decode("hex") + mn_bin = decode_hex(mn_hex) mn = mn_mep.dis(mn_bin, "b") - print "dis: %s -> %s" % (mn_hex.rjust(20), str(mn).rjust(20)) + print("dis: %s -> %s" % (mn_hex.rjust(20), str(mn).rjust(20))) assert(str(mn) == mn_str) # dissassemble assertion # Assemble and return all possible candidates instr = mn_mep.fromstring(str(mn), "b") instr.mode = "b" - asm_list = [i.encode("hex") for i in mn_mep.asm(instr)] + asm_list = [encode_hex(i).decode() for i in mn_mep.asm(instr)] # Print the results - print "asm: %s -> %s" % (mn_str.rjust(20), - ", ".join(asm_list).rjust(20)) + print("asm: %s -> %s" % ( + mn_str.rjust(20), + ", ".join(asm_list).rjust(20)) + ) assert(mn_hex in asm_list) # assemble assertion diff --git a/test/arch/mep/asm/test_major_opcode_0.py b/test/arch/mep/asm/test_major_opcode_0.py index 69a9685c..db288e47 100644 --- a/test/arch/mep/asm/test_major_opcode_0.py +++ b/test/arch/mep/asm/test_major_opcode_0.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor0: +class TestMajor0(object): def test_MOV(self): """Test the MOV instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_1.py b/test/arch/mep/asm/test_major_opcode_1.py index c401bfd2..3a3c6538 100644 --- a/test/arch/mep/asm/test_major_opcode_1.py +++ b/test/arch/mep/asm/test_major_opcode_1.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor1: +class TestMajor1(object): def test_OR(self): """Test the OR instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_10.py b/test/arch/mep/asm/test_major_opcode_10.py index f1089c61..e10992c8 100644 --- a/test/arch/mep/asm/test_major_opcode_10.py +++ b/test/arch/mep/asm/test_major_opcode_10.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor10: +class TestMajor10(object): def test_BEQZ(self): """Test the BEQZ instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_11.py b/test/arch/mep/asm/test_major_opcode_11.py index b5d8a278..38f93e8b 100644 --- a/test/arch/mep/asm/test_major_opcode_11.py +++ b/test/arch/mep/asm/test_major_opcode_11.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor11: +class TestMajor11(object): def test_BRA(self): """Test the BRA instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_12.py b/test/arch/mep/asm/test_major_opcode_12.py index e721d287..c353861e 100644 --- a/test/arch/mep/asm/test_major_opcode_12.py +++ b/test/arch/mep/asm/test_major_opcode_12.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor12: +class TestMajor12(object): def test_ADD3(self): """Test the ADD3 instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_13.py b/test/arch/mep/asm/test_major_opcode_13.py index 996b47e3..bf95572c 100644 --- a/test/arch/mep/asm/test_major_opcode_13.py +++ b/test/arch/mep/asm/test_major_opcode_13.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor13: +class TestMajor13(object): def test_MOVU(self): """Test the MOVU instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_14.py b/test/arch/mep/asm/test_major_opcode_14.py index 6ad3c757..9ec99550 100644 --- a/test/arch/mep/asm/test_major_opcode_14.py +++ b/test/arch/mep/asm/test_major_opcode_14.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor14: +class TestMajor14(object): def test_BEQI(self): """Test the BEQI instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_15.py b/test/arch/mep/asm/test_major_opcode_15.py index ecad8b3f..891626e8 100644 --- a/test/arch/mep/asm/test_major_opcode_15.py +++ b/test/arch/mep/asm/test_major_opcode_15.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor15: +class TestMajor15(object): def test_DSP(self): """Test the DSP instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_2.py b/test/arch/mep/asm/test_major_opcode_2.py index 07743813..4cbe36ca 100644 --- a/test/arch/mep/asm/test_major_opcode_2.py +++ b/test/arch/mep/asm/test_major_opcode_2.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor2: +class TestMajor2(object): def test_BSETM(self): """Test the BSETM instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_3.py b/test/arch/mep/asm/test_major_opcode_3.py index 3e0c5864..793a4e87 100644 --- a/test/arch/mep/asm/test_major_opcode_3.py +++ b/test/arch/mep/asm/test_major_opcode_3.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor3: +class TestMajor3(object): def test_SWCPI(self): """Test the SWCPI instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_4.py b/test/arch/mep/asm/test_major_opcode_4.py index e52acf3f..a6f57ac2 100644 --- a/test/arch/mep/asm/test_major_opcode_4.py +++ b/test/arch/mep/asm/test_major_opcode_4.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor4: +class TestMajor4(object): def test_ADD3(self): """Test the ADD3 instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_5.py b/test/arch/mep/asm/test_major_opcode_5.py index e39230f4..2250c123 100644 --- a/test/arch/mep/asm/test_major_opcode_5.py +++ b/test/arch/mep/asm/test_major_opcode_5.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor5: +class TestMajor5(object): def test_MOV(self): """Test the MOV instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_6.py b/test/arch/mep/asm/test_major_opcode_6.py index 5eda1ea6..e10d1064 100644 --- a/test/arch/mep/asm/test_major_opcode_6.py +++ b/test/arch/mep/asm/test_major_opcode_6.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor6: +class TestMajor6(object): def test_ADD(self): """Test the ADD instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_7.py b/test/arch/mep/asm/test_major_opcode_7.py index 15a045da..1b1fba78 100644 --- a/test/arch/mep/asm/test_major_opcode_7.py +++ b/test/arch/mep/asm/test_major_opcode_7.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor7: +class TestMajor7(object): def test_DI(self): """Test the DI instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_8.py b/test/arch/mep/asm/test_major_opcode_8.py index 7f15f9e8..900cf004 100644 --- a/test/arch/mep/asm/test_major_opcode_8.py +++ b/test/arch/mep/asm/test_major_opcode_8.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor8: +class TestMajor8(object): def test_SB(self): """Test the SB instruction""" diff --git a/test/arch/mep/asm/test_major_opcode_9.py b/test/arch/mep/asm/test_major_opcode_9.py index b8949887..9e59a863 100644 --- a/test/arch/mep/asm/test_major_opcode_9.py +++ b/test/arch/mep/asm/test_major_opcode_9.py @@ -4,7 +4,7 @@ from ut_helpers_asm import check_instruction -class TestMajor9: +class TestMajor9(object): def test_ADD3(self): """Test the ADD3 instruction""" diff --git a/test/arch/mep/asm/ut_helpers_asm.py b/test/arch/mep/asm/ut_helpers_asm.py index af010afc..26520787 100644 --- a/test/arch/mep/asm/ut_helpers_asm.py +++ b/test/arch/mep/asm/ut_helpers_asm.py @@ -1,6 +1,11 @@ # Toshiba MeP-c4 - unit tests helpers # Guillaume Valadon <guillaume@valadon.net> +from __future__ import print_function + +from builtins import range + +from miasm2.core.utils import decode_hex, encode_hex from miasm2.arch.mep.arch import mn_mep from miasm2.core.cpu import Disasm_Exception from miasm2.core.locationdb import LocationDB @@ -11,7 +16,7 @@ import re def dis(mn_hex): """Disassembly helper""" - mn_bin = mn_hex.decode("hex") + mn_bin = decode_hex(mn_hex) try: return mn_mep.dis(mn_bin, "b") except Disasm_Exception: @@ -50,7 +55,7 @@ def check_instruction(mn_str, mn_hex, multi=None, offset=0): addr = loc_db.get_location_offset(mn.args[i].loc_key) mn.args[i] = ExprInt(addr, args_size[i]) - print "dis: %s -> %s" % (mn_hex.rjust(20), str(mn).rjust(20)) + print("dis: %s -> %s" % (mn_hex.rjust(20), str(mn).rjust(20))) assert(str(mn) == mn_str) # disassemble assertion # Assemble and return all possible candidates @@ -59,21 +64,25 @@ def check_instruction(mn_str, mn_hex, multi=None, offset=0): instr.mode = "b" if instr.offset: instr.fixDstOffset() - asm_list = [i.encode("hex") for i in mn_mep.asm(instr)] + asm_list = [encode_hex(i).decode() for i in mn_mep.asm(instr)] # Check instructions variants if multi: - print "Instructions count:", len(asm_list) + print("Instructions count:", len(asm_list)) assert(len(asm_list) == multi) # Ensure that variants correspond to the same disassembled instruction - for mn_hex in asm_list: - mn = dis(mn_hex) - print "dis: %s -> %s" % (mn_hex.rjust(20), str(mn).rjust(20)) + for mn_hex_tmp in asm_list: + mn = dis(mn_hex_tmp) + print("dis: %s -> %s" % (mn_hex_tmp.rjust(20), str(mn).rjust(20))) # Check the assembly result - print "asm: %s -> %s" % (mn_str.rjust(20), - ", ".join(asm_list).rjust(20)) + print( + "asm: %s -> %s" % ( + mn_str.rjust(20), + ", ".join(asm_list).rjust(20) + ) + ) assert(mn_hex in asm_list) # assemble assertion @@ -83,10 +92,10 @@ def launch_tests(obj): test_methods = [name for name in dir(obj) if name.startswith("test")] for method in test_methods: - print method + print(method) try: getattr(obj, method)() except AttributeError as e: - print "Method not found: %s" % method + print("Method not found: %s" % method) assert(False) - print '-' * 42 + print('-' * 42) diff --git a/test/arch/mep/ir/test_arithmetic.py b/test/arch/mep/ir/test_arithmetic.py index 6da938e9..2e0dbf32 100644 --- a/test/arch/mep/ir/test_arithmetic.py +++ b/test/arch/mep/ir/test_arithmetic.py @@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp -class TestArithmetic: +class TestArithmetic(object): def test_add3(self): """Test ADD3 execution""" diff --git a/test/arch/mep/ir/test_bitmanipulation.py b/test/arch/mep/ir/test_bitmanipulation.py index 06466f9d..f4ea2f29 100644 --- a/test/arch/mep/ir/test_bitmanipulation.py +++ b/test/arch/mep/ir/test_bitmanipulation.py @@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction from miasm2.expression.expression import ExprId, ExprInt, ExprMem -class TestBitManipulation: +class TestBitManipulation(object): def test_bsetm(self): """Test BSETM execution""" diff --git a/test/arch/mep/ir/test_branchjump.py b/test/arch/mep/ir/test_branchjump.py index 3f78558b..7e0953fd 100644 --- a/test/arch/mep/ir/test_branchjump.py +++ b/test/arch/mep/ir/test_branchjump.py @@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction from miasm2.expression.expression import ExprId, ExprInt -class TestBranchJump: +class TestBranchJump(object): def test_bra(self): """Test BRA execution""" diff --git a/test/arch/mep/ir/test_control.py b/test/arch/mep/ir/test_control.py index a1b3c7c7..92dcb371 100644 --- a/test/arch/mep/ir/test_control.py +++ b/test/arch/mep/ir/test_control.py @@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp -class TestControl: +class TestControl(object): def test_stc(self): """Test STC execution""" diff --git a/test/arch/mep/ir/test_coprocessor.py b/test/arch/mep/ir/test_coprocessor.py index e9b745ff..e9829c08 100644 --- a/test/arch/mep/ir/test_coprocessor.py +++ b/test/arch/mep/ir/test_coprocessor.py @@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction from miasm2.expression.expression import ExprId, ExprMem, ExprInt -class TestCoprocessor: +class TestCoprocessor(object): def test_swcp(self): """Test SWCP execution""" diff --git a/test/arch/mep/ir/test_datacache.py b/test/arch/mep/ir/test_datacache.py index a462315d..7d92f9c7 100644 --- a/test/arch/mep/ir/test_datacache.py +++ b/test/arch/mep/ir/test_datacache.py @@ -4,7 +4,7 @@ from ut_helpers_ir import exec_instruction -class TestDataCache: +class TestDataCache(object): def test_cache(self): """Test CACHE execution""" diff --git a/test/arch/mep/ir/test_debug.py b/test/arch/mep/ir/test_debug.py index 53f4064d..b25e3a19 100644 --- a/test/arch/mep/ir/test_debug.py +++ b/test/arch/mep/ir/test_debug.py @@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp -class TestDebug: +class TestDebug(object): def test_dret(self): """Test DRET execution""" diff --git a/test/arch/mep/ir/test_divide.py b/test/arch/mep/ir/test_divide.py index a63d0c5e..e3e4cb99 100644 --- a/test/arch/mep/ir/test_divide.py +++ b/test/arch/mep/ir/test_divide.py @@ -7,7 +7,7 @@ from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO -class TestDivide: +class TestDivide(object): def test_div(self): """Test DIV execution""" diff --git a/test/arch/mep/ir/test_extension.py b/test/arch/mep/ir/test_extension.py index 72423220..10f16ebf 100644 --- a/test/arch/mep/ir/test_extension.py +++ b/test/arch/mep/ir/test_extension.py @@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction from miasm2.expression.expression import ExprId, ExprMem, ExprInt -class TestExtension: +class TestExtension(object): def test_extb(self): """Test EXTB execution""" diff --git a/test/arch/mep/ir/test_ir.py b/test/arch/mep/ir/test_ir.py index 3fec9ec9..be717db8 100644 --- a/test/arch/mep/ir/test_ir.py +++ b/test/arch/mep/ir/test_ir.py @@ -1,6 +1,9 @@ # Toshiba MeP-c4 - Misc unit tests # Guillaume Valadon <guillaume@valadon.net> +from __future__ import print_function + +from miasm2.core.utils import decode_hex from miasm2.arch.mep.arch import mn_mep from miasm2.arch.mep.regs import regs_init from miasm2.arch.mep.ira import ir_mepb, ir_a_mepb @@ -9,7 +12,7 @@ from miasm2.ir.symbexec import SymbolicExecutionEngine from miasm2.core.locationdb import LocationDB -class TestMisc: +class TestMisc(object): def test(self): @@ -18,16 +21,16 @@ class TestMisc: def exec_instruction(hex_asm, init_values): """Symbolically execute an instruction""" - print "Hex:", hex_asm + print("Hex:", hex_asm) # Disassemble an instruction - mn = mn_mep.dis(hex_asm.decode("hex"), "b") - print "Dis:", mn + mn = mn_mep.dis(decode_hex(hex_asm), "b") + print("Dis:", mn) # Get the IR im = ir_mepb() iir, eiir, = im.get_ir(mn) - print "\nInternal representation:", iir + print("\nInternal representation:", iir) # Symbolic execution loc_db = LocationDB() @@ -37,13 +40,13 @@ class TestMisc: for reg_expr_id, reg_expr_value in init_values: sb.symbols[reg_expr_id] = reg_expr_value - print "\nModified registers:", [reg for reg in sb.modified(mems=False)] - print "Modified memories:", [mem for mem in sb.modified()] + print("\nModified registers:", [reg for reg in sb.modified(mems=False)]) + print("Modified memories:", [mem for mem in sb.modified()]) - print "\nFinal registers:" + print("\nFinal registers:") sb.dump(mems=False) - print "\nFinal mems:" + print("\nFinal mems:") sb.dump() for hex_asm, init_values in [("6108", [(ExprId("R1", 32), ExprInt(0x40, 32))]), @@ -52,5 +55,5 @@ class TestMisc: ("0948", [(ExprId("R4", 32), ExprInt(0x41, 32)), (ExprId("R9", 32), ExprInt(0x28, 32)), (ExprMem(ExprInt(0x41, 32), 8), ExprInt(0, 8))])]: - print "-" * 49 # Tests separation + print("-" * 49) # Tests separation exec_instruction(hex_asm, init_values) diff --git a/test/arch/mep/ir/test_ldz.py b/test/arch/mep/ir/test_ldz.py index 02960b60..668030c8 100644 --- a/test/arch/mep/ir/test_ldz.py +++ b/test/arch/mep/ir/test_ldz.py @@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp -class TestLdz: +class TestLdz(object): def test_ldz(self): """Test LDZ execution""" diff --git a/test/arch/mep/ir/test_loadstore.py b/test/arch/mep/ir/test_loadstore.py index c6b40d55..22cb4304 100644 --- a/test/arch/mep/ir/test_loadstore.py +++ b/test/arch/mep/ir/test_loadstore.py @@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction from miasm2.expression.expression import ExprId, ExprMem, ExprInt -class TestLoadStore: +class TestLoadStore(object): def test_sb(self): """Test SB execution""" diff --git a/test/arch/mep/ir/test_logical.py b/test/arch/mep/ir/test_logical.py index 61cbbf0a..e78b5488 100644 --- a/test/arch/mep/ir/test_logical.py +++ b/test/arch/mep/ir/test_logical.py @@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp -class TestLogical: +class TestLogical(object): def test_or(self): """Test OR execution""" diff --git a/test/arch/mep/ir/test_move.py b/test/arch/mep/ir/test_move.py index 56a4225e..8da7a18a 100644 --- a/test/arch/mep/ir/test_move.py +++ b/test/arch/mep/ir/test_move.py @@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction from miasm2.expression.expression import ExprId, ExprMem, ExprInt -class TestMove: +class TestMove(object): def test_mov(self): """Test MOV execution""" diff --git a/test/arch/mep/ir/test_multiply.py b/test/arch/mep/ir/test_multiply.py index 0618f69f..5673994c 100644 --- a/test/arch/mep/ir/test_multiply.py +++ b/test/arch/mep/ir/test_multiply.py @@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp -class TestMultiply: +class TestMultiply(object): def test_mul(self): """Test MUL execution""" diff --git a/test/arch/mep/ir/test_repeat.py b/test/arch/mep/ir/test_repeat.py index 252764b1..1e0e2f86 100644 --- a/test/arch/mep/ir/test_repeat.py +++ b/test/arch/mep/ir/test_repeat.py @@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp -class TestRepeat: +class TestRepeat(object): def test_repeat(self): """Test REPEAT execution""" diff --git a/test/arch/mep/ir/test_shift.py b/test/arch/mep/ir/test_shift.py index b63f9ed7..99755ba5 100644 --- a/test/arch/mep/ir/test_shift.py +++ b/test/arch/mep/ir/test_shift.py @@ -7,7 +7,7 @@ from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp from miasm2.core.cpu import sign_ext -class TestShift: +class TestShift(object): def test_sra(self): """Test SRA execution""" diff --git a/test/arch/mep/ir/ut_helpers_ir.py b/test/arch/mep/ir/ut_helpers_ir.py index 9c9efdfa..26eebeda 100644 --- a/test/arch/mep/ir/ut_helpers_ir.py +++ b/test/arch/mep/ir/ut_helpers_ir.py @@ -1,6 +1,8 @@ # Toshiba MeP-c4 - unit tests helpers # Guillaume Valadon <guillaume@valadon.net> +from __future__ import print_function + from miasm2.arch.mep.arch import mn_mep from miasm2.arch.mep.sem import ir_mepb from miasm2.arch.mep.regs import regs_init @@ -10,7 +12,8 @@ from miasm2.core.locationdb import LocationDB from miasm2.core.utils import Disasm_Exception from miasm2.ir.ir import AssignBlock from miasm2.arch.mep.ira import ir_a_mepb -from miasm2.expression.expression import ExprId, ExprInt, ExprOp, ExprMem, ExprAssign, ExprLoc +from miasm2.expression.expression import ExprId, ExprInt, ExprOp, ExprMem, \ + ExprAssign, ExprLoc def exec_instruction(mn_str, init_values, results, index=0, offset=0): @@ -67,8 +70,8 @@ def exec_instruction(mn_str, init_values, results, index=0, offset=0): # Ensure that all expected results were verified if len(results) is not matched_results: - print "Expected:", results - print "Modified:", [r for r in sb.modified(mems=False)] + print("Expected:", results) + print("Modified:", [r for r in sb.modified(mems=False)]) assert(False) @@ -78,10 +81,10 @@ def launch_tests(obj): test_methods = [name for name in dir(obj) if name.startswith("test")] for method in test_methods: - print method + print(method) try: getattr(obj, method)() except AttributeError as e: - print "Method not found: %s" % method + print("Method not found: %s" % method) assert(False) - print '-' * 42 + print('-' * 42) diff --git a/test/arch/mep/jit/test_jit_branchjump.py b/test/arch/mep/jit/test_jit_branchjump.py index baf602d8..1f932aa9 100644 --- a/test/arch/mep/jit/test_jit_branchjump.py +++ b/test/arch/mep/jit/test_jit_branchjump.py @@ -4,7 +4,7 @@ from ut_helpers_jit import jit_instructions -class TestBranchJump: +class TestBranchJump(object): def test_blti(self): """Test BLTI jit""" diff --git a/test/arch/mep/jit/test_jit_repeat.py b/test/arch/mep/jit/test_jit_repeat.py index 9fa64fa5..eaac1a1d 100644 --- a/test/arch/mep/jit/test_jit_repeat.py +++ b/test/arch/mep/jit/test_jit_repeat.py @@ -4,7 +4,7 @@ from ut_helpers_jit import jit_instructions -class TestRepeat: +class TestRepeat(object): def test_repeat(self): """Test REPEAT jit""" diff --git a/test/arch/mep/jit/ut_helpers_jit.py b/test/arch/mep/jit/ut_helpers_jit.py index 590c534f..999ead42 100644 --- a/test/arch/mep/jit/ut_helpers_jit.py +++ b/test/arch/mep/jit/ut_helpers_jit.py @@ -1,6 +1,8 @@ # Toshiba MeP-c4 - unit tests helpers # Guillaume Valadon <guillaume@valadon.net> +from __future__ import print_function + from miasm2.analysis.machine import Machine from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE @@ -13,7 +15,7 @@ def jit_instructions(mn_str): mn_mep = machine.mn() # Assemble the instructions - asm = "" + asm = b"" for instr_str in mn_str.split("\n"): instr = mn_mep.fromstring(instr_str, "b") instr.mode = "b" @@ -40,10 +42,10 @@ def launch_tests(obj): test_methods = [name for name in dir(obj) if name.startswith("test")] for method in test_methods: - print method + print(method) try: getattr(obj, method)() except AttributeError as e: - print "Method not found: %s" % method + print("Method not found: %s" % method) assert(False) - print '-' * 42 + print('-' * 42) diff --git a/test/arch/mips32/arch.py b/test/arch/mips32/arch.py index 1cbb554d..f71d3ee8 100644 --- a/test/arch/mips32/arch.py +++ b/test/arch/mips32/arch.py @@ -1,6 +1,8 @@ +from __future__ import print_function import time from pdb import pm +from miasm2.core.utils import decode_hex, encode_hex from miasm2.core.locationdb import LocationDB from miasm2.arch.mips32.arch import * @@ -217,20 +219,20 @@ reg_tests_mips32 = [ ts = time.time() def h2i(s): - return s.replace(' ', '').decode('hex') + return decode_hex(s.replace(' ', '')) for s, l in reg_tests_mips32: - print "-" * 80 + print("-" * 80) s = s[12:] b = h2i((l)) mn = mn_mips32.dis(b, 'b') - print [str(x) for x in mn.args] - print s - print mn + print([str(x) for x in mn.args]) + print(s) + print(mn) assert(str(mn) == s) l = mn_mips32.fromstring(s, loc_db, 'b') assert(str(l) == s) a = mn_mips32.asm(l, 'b') - print [x for x in a] - print repr(b) + print([x for x in a]) + print(repr(b)) assert(b in a) diff --git a/test/arch/mips32/unit/asm_test.py b/test/arch/mips32/unit/asm_test.py index da792874..7a50b38e 100644 --- a/test/arch/mips32/unit/asm_test.py +++ b/test/arch/mips32/unit/asm_test.py @@ -1,6 +1,8 @@ import sys import os +from future.utils import viewitems + from miasm2.arch.mips32.arch import mn_mips32 from miasm2.core import parse_asm from miasm2.expression.expression import * @@ -30,10 +32,10 @@ class Asm_Test(object): loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0) s = StrPatchwork() patches = asmblock.asm_resolve_final(mn_mips32, blocks, loc_db) - for offset, raw in patches.items(): + for offset, raw in viewitems(patches): s[offset] = raw - s = str(s) + s = bytes(s) self.assembly = s def run(self): diff --git a/test/arch/msp430/arch.py b/test/arch/msp430/arch.py index 91de95b3..eea87091 100644 --- a/test/arch/msp430/arch.py +++ b/test/arch/msp430/arch.py @@ -1,12 +1,15 @@ +from __future__ import print_function + import time from pdb import pm +from miasm2.core.utils import decode_hex, encode_hex from miasm2.arch.msp430.arch import * from miasm2.core.locationdb import LocationDB loc_db = LocationDB() def h2i(s): - return s.replace(' ', '').decode('hex') + return decode_hex(s.replace(' ', '')) def u16swap(i): @@ -86,18 +89,18 @@ reg_tests_msp = [ ts = time.time() for s, l in reg_tests_msp: - print "-" * 80 + print("-" * 80) s = s[8:] b = h2i((l)) - print repr(b) + print(repr(b)) mn = mn_msp430.dis(b, None) - print [str(x) for x in mn.args] - print s - print mn + print([str(x) for x in mn.args]) + print(s) + print(mn) assert(str(mn) == s) l = mn_msp430.fromstring(s, loc_db, None) assert(str(l) == s) a = mn_msp430.asm(l) - print [x for x in a] - print repr(b) + print([x for x in a]) + print(repr(b)) assert(b in a) diff --git a/test/arch/msp430/sem.py b/test/arch/msp430/sem.py index 10e57e36..88aa990d 100755 --- a/test/arch/msp430/sem.py +++ b/test/arch/msp430/sem.py @@ -1,9 +1,12 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from __future__ import print_function import unittest import logging +from future.utils import viewitems + from miasm2.ir.symbexec import SymbolicExecutionEngine from miasm2.arch.msp430.arch import mn_msp430 as mn, mode_msp430 as mode from miasm2.arch.msp430.sem import ir_msp430 as ir_arch @@ -22,7 +25,7 @@ def M(addr): def compute(asm, inputstate={}, debug=False): loc_db = LocationDB() sympool = dict(regs_init) - sympool.update({k: ExprInt(v, k.size) for k, v in inputstate.iteritems()}) + sympool.update({k: ExprInt(v, k.size) for k, v in viewitems(inputstate)}) ir_tmp = ir_arch(loc_db) ircfg = ir_tmp.new_ircfg() symexec = SymbolicExecutionEngine(ir_tmp, sympool) @@ -33,11 +36,13 @@ def compute(asm, inputstate={}, debug=False): loc_key = ir_tmp.add_instr_to_ircfg(instr, ircfg) symexec.run_at(ircfg, loc_key) if debug: - for k, v in symexec.symbols.items(): + for k, v in viewitems(symexec.symbols): if regs_init.get(k, None) != v: - print k, v - return {k: v.arg.arg for k, v in symexec.symbols.items() - if k not in EXCLUDE_REGS and regs_init.get(k, None) != v} + print(k, v) + return { + k: v.arg.arg for k, v in viewitems(symexec.symbols) + if k not in EXCLUDE_REGS and regs_init.get(k, None) != v + } class TestMSP430Semantic(unittest.TestCase): diff --git a/test/arch/sh4/arch.py b/test/arch/sh4/arch.py index f744b215..f52ed070 100644 --- a/test/arch/sh4/arch.py +++ b/test/arch/sh4/arch.py @@ -1,13 +1,15 @@ +from __future__ import print_function import time from pdb import pm from sys import stderr +from miasm2.core.utils import decode_hex, encode_hex from miasm2.arch.sh4.arch import * from miasm2.core.locationdb import LocationDB loc_db = LocationDB() def h2i(s): - return s.replace(' ', '').decode('hex') + return decode_hex(s.replace(' ', '')) reg_tests_sh4 = [ # vxworks @@ -389,25 +391,25 @@ reg_tests_sh4 = [ ] for s, l in reg_tests_sh4: - print "-" * 80 + print("-" * 80) s = s[12:] b = h2i((l)) - print b.encode('hex') + print(encode_hex(b)) mn = mn_sh4.dis(b, None) - print [str(x) for x in mn.args] - print s - print mn + print([str(x) for x in mn.args]) + print(s) + print(mn) assert(str(mn) == s) l = mn_sh4.fromstring(s, loc_db, None) assert(str(l) == s) a = mn_sh4.asm(l) - print [x for x in a] - print repr(b) + print([x for x in a]) + print(repr(b)) assert(b in a) # speed test -o = "" +o = b"" for s, l, in reg_tests_sh4: s = s[12:] b = h2i((l)) @@ -421,10 +423,10 @@ instr_num = 0 ts = time.time() while off < bs.getlen(): mn = mn_sh4.dis(bs, None, off) - print instr_num, off, mn.l, str(mn) + print(instr_num, off, mn.l, str(mn)) instr_num += 1 off += mn.l -print 'instr per sec:', instr_num / (time.time() - ts) +print('instr per sec:', instr_num // (time.time() - ts)) import cProfile -cProfile.run(r'mn_sh4.dis("\x17\xfe", None)') +cProfile.run(r'mn_sh4.dis(b"\x17\xfe", None)') diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py index d2204d77..b4cebd28 100644 --- a/test/arch/x86/arch.py +++ b/test/arch/x86/arch.py @@ -1,5 +1,8 @@ +from __future__ import print_function import time from pdb import pm + +from miasm2.core.utils import decode_hex, encode_hex import miasm2.expression.expression as m2_expr from miasm2.arch.x86.arch import mn_x86, deref_mem_ad, \ base_expr, rmarg, print_size @@ -22,7 +25,7 @@ reg_and_id.update({'mylabel16': mylabel16, def h2i(s): - return int(s.replace(' ', '').decode('hex')[::].encode('hex'), 16) + return int(encode_hex(decode_hex(s.replace(' ', ''))[::]), 16) m16 = 16 # (16, 16) @@ -3101,56 +3104,58 @@ reg_tests = [ ] -test_file = {16: open('regression_test16_ia32.bin', 'w'), - 32: open('regression_test32_ia32.bin', 'w'), - 64: open('regression_test64_ia32.bin', 'w')} +test_file = { + 16: open('regression_test16_ia32.bin', 'wb'), + 32: open('regression_test32_ia32.bin', 'wb'), + 64: open('regression_test64_ia32.bin', 'wb') +} ts = time.time() for mode, s, l, in reg_tests: - print "-" * 80 + print("-" * 80) s = s[12:] - b = l.decode('hex') - print mode, repr(b) + b = decode_hex(l) + print(mode, repr(b)) mn = mn_x86.dis(b, mode) - print "dis args", [(str(x), x.size) for x in mn.args] - print s - print mn + print("dis args", [(str(x), x.size) for x in mn.args]) + print(s) + print(mn) assert(str(mn).strip() == s) - print 'fromstring', repr(s) + print('fromstring', repr(s)) l = mn_x86.fromstring(s, loc_db, mode) - print 'str args', [(str(x), x.size) for x in l.args] + print('str args', [(str(x), x.size) for x in l.args]) assert(str(l).strip(' ') == s) a = mn_x86.asm(l) - print 'asm result', [x for x in a] - print repr(b) + print('asm result', [x for x in a]) + print(repr(b)) for x in a: - print "BYTES", repr(x) + print("BYTES", repr(x)) test_file[mode].write(x) - test_file[mode].write("\x90" * 2) + test_file[mode].write(b"\x90" * 2) - print 'test re dis' + print('test re dis') for x in a: - print repr(x) + print(repr(x)) rl = mn_x86.dis(x, mode) assert(str(rl).strip(' ') == s) - print repr(b), a + print(repr(b), a) assert(b in a) -print 'TEST time', time.time() - ts +print('TEST time', time.time() - ts) # speed test thumb -o = "" +o = b"" mode_x = m32 for mode, s, l, in reg_tests: if mode != mode_x: continue s = s[12:] - b = l.decode('hex') + b = decode_hex(l) o += b while len(o) < 1000: o += o -open('x86_speed_reg_test.bin', 'w').write(o) +open('x86_speed_reg_test.bin', 'wb').write(o) def profile_dis(o): @@ -3163,12 +3168,12 @@ def profile_dis(o): # print instr_num, off, mn.l, str(mn) instr_num += 1 off += mn.l - print 'instr per sec:', instr_num / (time.time() - ts) + print('instr per sec:', instr_num // (time.time() - ts)) import cProfile cProfile.run('profile_dis(o)') # Test instruction representation with prefix -instr_bytes = '\x65\xc7\x00\x09\x00\x00\x00' +instr_bytes = b'\x65\xc7\x00\x09\x00\x00\x00' inst = mn_x86.dis(instr_bytes, 32, 0) assert(inst.b == instr_bytes) diff --git a/test/arch/x86/qemu/testqemu.py b/test/arch/x86/qemu/testqemu.py index dccd9c83..264a84b9 100644 --- a/test/arch/x86/qemu/testqemu.py +++ b/test/arch/x86/qemu/testqemu.py @@ -1,36 +1,42 @@ +from __future__ import print_function import os -import sys import struct import logging +from sys import stdout from pdb import pm +try: + stdout = stdout.buffer +except AttributeError: + pass + from miasm2.analysis.sandbox import Sandbox_Linux_x86_32 from miasm2.jitter.jitload import log_func from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE # Utils def parse_fmt(s): - fmt = s[:]+"\x00" + fmt = s[:]+b"\x00" out = [] i = 0 while i < len(fmt): - c = fmt[i] - if c != "%": + c = fmt[i:i+1] + if c != b"%": i+=1 continue - if fmt[i+1] == "%": + if fmt[i+1:i+2] == b"%": i+=2 continue j = 0 i+=1 - while fmt[i+j] in "0123456789$.-": + while fmt[i+j:i+j+1] in b"0123456789$.-": j+=1 - if fmt[i+j] in ['l']: + if fmt[i+j:i+j+1] in [b'l']: j +=1 - if fmt[i+j] == "h": + if fmt[i+j:i+j+1] == b"h": x = fmt[i+j:i+j+2] else: - x = fmt[i+j] + x = fmt[i+j:i+j+1] i+=j out.append(x) return out @@ -44,25 +50,24 @@ def xxx___printf_chk(jitter): raise RuntimeError("Not implemented") fmt = jitter.get_str_ansi(args.format) # Manage llx - fmt = fmt.replace("llx", "lx") - fmt = fmt.replace("%016lx", "%016z") + fmt = fmt.replace(b"llx", b"lx") + fmt = fmt.replace(b"%016lx", b"%016z") fmt_a = parse_fmt(fmt) esp = jitter.cpu.ESP args = [] i = 0 - for x in fmt_a: a = jitter.vm.get_u32(esp + 8 + 4*i) - if x == "s": + if x == b"s": a = jitter.get_str_ansi(a) - elif x.lower() in ("x", 'd'): + elif x in (b"x", b'X', b"d"): pass - elif x.lower() in ("f", "l"): + elif x.lower() in (b"f", b"l"): a2 = jitter.vm.get_u32(esp + 8 + 4*(i+1)) a = struct.unpack("d", struct.pack("Q", a2 << 32 | a))[0] i += 1 - elif x.lower() == 'z': + elif x.lower() == b'z': a2 = jitter.vm.get_u32(esp + 8 + 4*(i+1)) a = a2 << 32 | a i += 1 @@ -70,23 +75,22 @@ def xxx___printf_chk(jitter): raise RuntimeError("Not implemented format") args.append(a) i += 1 - - fmt = fmt.replace("%016z", "%016lx") + fmt = fmt.replace(b"%016z", b"%016lx") output = fmt%(tuple(args)) # NaN bad repr in Python - output = output.replace("nan", "-nan") + output = output.replace(b"nan", b"-nan") - if "\n" not in output: + if b"\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 + line = next(expected) + if output != line.encode(): + print("Expected:", line) + print("Obtained:", output) raise RuntimeError("Bad semantic") - sys.stdout.write("[%d] %s" % (nb_tests, output)) + stdout.write(b"[%d] %s" % (nb_tests, output)) nb_tests += 1 jitter.func_ret_systemv(ret_ad, 0) @@ -100,10 +104,10 @@ def xxx_puts(jitter): ret_addr, args = jitter.func_args_systemv(['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 + line = next(expected) + if output != line.rstrip().encode(): + print("Expected:", line) + print("Obtained:", output) raise RuntimeError("Bad semantic") return jitter.func_ret_systemv(ret_addr, 1) @@ -120,7 +124,7 @@ 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 + addr = sb.elf.getsectionbyname(".symtab")[options.funcname].value except AttributeError: raise RuntimeError("The target binary must have a symtab section") @@ -129,7 +133,7 @@ log_func.setLevel(logging.ERROR) # Segmentation sb.jitter.cpu.set_segm_base(8, 0x7fff0000) sb.jitter.cpu.GS = 8 -sb.jitter.vm.add_memory_page(0x7fff0000 + 0x14, PAGE_READ | PAGE_WRITE, "AAAA") +sb.jitter.vm.add_memory_page(0x7fff0000 + 0x14, PAGE_READ | PAGE_WRITE, b"AAAA") # Run diff --git a/test/arch/x86/qemu/testqemu64.py b/test/arch/x86/qemu/testqemu64.py index bd82d414..4fe51992 100644 --- a/test/arch/x86/qemu/testqemu64.py +++ b/test/arch/x86/qemu/testqemu64.py @@ -1,36 +1,42 @@ +from __future__ import print_function import os -import sys import struct import logging +from sys import stdout from pdb import pm +try: + stdout = stdout.buffer +except AttributeError: + pass + from miasm2.analysis.sandbox import Sandbox_Linux_x86_64 from miasm2.jitter.jitload import log_func from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE # Utils def parse_fmt(s): - fmt = s[:]+"\x00" + fmt = s[:]+b"\x00" out = [] i = 0 while i < len(fmt): - c = fmt[i] - if c != "%": + c = fmt[i:i+1] + if c != b"%": i+=1 continue - if fmt[i+1] == "%": + if fmt[i+1:i+2] == b"%": i+=2 continue j = 0 i+=1 - while fmt[i+j] in "0123456789$.-": + while fmt[i+j:i+j+1] in b"0123456789$.-": j+=1 - if fmt[i+j] in ['l']: + if fmt[i+j:i+j+1] in [b'l']: j +=1 - if fmt[i+j] == "h": + if fmt[i+j:i+j+1] == b"h": x = fmt[i+j:i+j+2] else: - x = fmt[i+j] + x = fmt[i+j:i+j+1] i+=j out.append(x) return out @@ -44,8 +50,8 @@ def xxx___printf_chk(jitter): raise RuntimeError("Not implemented") fmt = jitter.get_str_ansi(args.format) # Manage llx - fmt = fmt.replace("llx", "lx") - fmt = fmt.replace("%016lx", "%016z") + fmt = fmt.replace(b"llx", b"lx") + fmt = fmt.replace(b"%016lx", b"%016z") fmt_a = parse_fmt(fmt) args = [] @@ -53,11 +59,11 @@ def xxx___printf_chk(jitter): for x in fmt_a: a = jitter.get_arg_n_systemv(2 + i) - if x == "s": + if x == b"s": a = jitter.get_str_ansi(a) - elif x.lower() in ("x", 'd', 'z'): + elif x in (b"x", b'X', b'd', b'z', b'Z'): pass - elif x.lower() in ("f", "l"): + elif x.lower() in (b"f","l"): a = struct.unpack("d", struct.pack("Q", a))[0] i += 1 else: @@ -65,22 +71,22 @@ def xxx___printf_chk(jitter): args.append(a) i += 1 - fmt = fmt.replace("%016z", "%016lx") + fmt = fmt.replace(b"%016z", b"%016lx") output = fmt%(tuple(args)) # NaN bad repr in Python - output = output.replace("nan", "-nan") + output = output.replace(b"nan", b"-nan") - if "\n" not in output: + if b"\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 + line = next(expected) + if output != line.encode(): + print("Expected:", line) + print("Obtained:", output) raise RuntimeError("Bad semantic") - sys.stdout.write("[%d] %s" % (nb_tests, output)) + stdout.write(b"[%d] %s" % (nb_tests, output)) nb_tests += 1 jitter.func_ret_systemv(ret_ad, 0) @@ -94,10 +100,10 @@ def xxx_puts(jitter): ret_addr, args = jitter.func_args_systemv(['target']) output = jitter.get_str_ansi(args.target) # Check with expected result - line = expected.next() + line = next(expected) if output != line.rstrip(): - print "Expected:", line - print "Obtained:", output + print("Expected:", line) + print("Obtained:", output) raise RuntimeError("Bad semantic") return jitter.func_ret_systemv(ret_addr, 1) @@ -114,7 +120,7 @@ expected = open(options.expected) # Create sandbox sb = Sandbox_Linux_x86_64(options.filename, options, globals()) try: - addr = sb.elf.getsectionbyname(".symtab").symbols[options.funcname].value + addr = sb.elf.getsectionbyname(".symtab")[options.funcname].value except AttributeError: raise RuntimeError("The target binary must have a symtab section") @@ -123,7 +129,7 @@ log_func.setLevel(logging.ERROR) # Segmentation sb.jitter.cpu.set_segm_base(8, 0x7fff0000) sb.jitter.cpu.FS = 8 -sb.jitter.vm.add_memory_page(0x7fff0000 + 0x28, PAGE_READ | PAGE_WRITE, "AAAAAAAA") +sb.jitter.vm.add_memory_page(0x7fff0000 + 0x28, PAGE_READ | PAGE_WRITE, b"AAAAAAAA") # Run diff --git a/test/arch/x86/sem.py b/test/arch/x86/sem.py index 0783089d..c0cfc8f2 100755 --- a/test/arch/x86/sem.py +++ b/test/arch/x86/sem.py @@ -3,6 +3,11 @@ # Loosely based on ARM's sem.py +from __future__ import print_function +from builtins import range + +from future.utils import viewitems + import unittest import logging import copy @@ -30,11 +35,13 @@ def symb_exec(lbl, ir_arch, ircfg, inputstate, debug): symexec = SymbolicExecutionEngine(ir_arch, sympool) symexec.run_at(ircfg, lbl) if debug: - for k, v in symexec.symbols.items(): + for k, v in viewitems(symexec.symbols): if regs_init.get(k, None) != v: - print k, v - return {k: v for k, v in symexec.symbols.items() - if k not in EXCLUDE_REGS and regs_init.get(k, None) != v} + print(k, v) + return { + k: v for k, v in viewitems(symexec.symbols) + if k not in EXCLUDE_REGS and regs_init.get(k, None) != v + } def compute(ir, mode, asm, inputstate={}, debug=False): loc_db = LocationDB() @@ -60,7 +67,7 @@ def compute_txt(ir, mode, txt, inputstate={}, debug=False): op_add = lambda a, b: a+b op_sub = lambda a, b: a-b op_mul = lambda a, b: a*b -op_div = lambda a, b: a/b +op_div = lambda a, b: a //b op_and = lambda a, b: a&b op_or = lambda a, b: a|b @@ -72,8 +79,8 @@ def int_vec_op(op, elt_size, reg_size, arg1, arg2): assert(reg_size % elt_size == 0) ret = 0 mask = (1<<elt_size)-1 - nelts = reg_size/elt_size - for i in xrange(0, nelts): + nelts = reg_size // elt_size + for i in range(0, nelts): ret |= (op(arg1 & mask, arg2 & mask) & mask) << (i*elt_size) arg1 >>= elt_size arg2 >>= elt_size diff --git a/test/arch/x86/unit/access_xmm.py b/test/arch/x86/unit/access_xmm.py index 950c8b56..8354c30f 100644 --- a/test/arch/x86/unit/access_xmm.py +++ b/test/arch/x86/unit/access_xmm.py @@ -10,7 +10,7 @@ myjit = Machine("x86_32").jitter("python") assert myjit.cpu.XMM0 == 0 # Test set -myjit.cpu.XMM1 = 0x00112233445566778899aabbccddeeffL +myjit.cpu.XMM1 = 0x00112233445566778899aabbccddeeff # Ensure set has been correctly handled -assert myjit.cpu.XMM1 == 0x00112233445566778899aabbccddeeffL +assert myjit.cpu.XMM1 == 0x00112233445566778899aabbccddeeff diff --git a/test/arch/x86/unit/asm_test.py b/test/arch/x86/unit/asm_test.py index 91da1942..a87fe278 100644 --- a/test/arch/x86/unit/asm_test.py +++ b/test/arch/x86/unit/asm_test.py @@ -1,6 +1,10 @@ +from builtins import str +from builtins import object import sys import os +from future.utils import viewitems + from miasm2.arch.x86.arch import mn_x86, base_expr, variable from miasm2.core import parse_asm from miasm2.expression.expression import * @@ -46,10 +50,10 @@ class Asm_Test(object): loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0) s = StrPatchwork() patches = asmblock.asm_resolve_final(mn_x86, blocks, loc_db) - for offset, raw in patches.items(): + for offset, raw in viewitems(patches): s[offset] = raw - s = str(s) + s = bytes(s) self.assembly = s def check(self): diff --git a/test/arch/x86/unit/mn_getset128.py b/test/arch/x86/unit/mn_getset128.py index a084d663..f20f452e 100644 --- a/test/arch/x86/unit/mn_getset128.py +++ b/test/arch/x86/unit/mn_getset128.py @@ -35,15 +35,15 @@ class Test_get_set_128(Asm_Test_32): assert self.myjit.cpu.get_gpreg()['XMM0'] == val def check(self): - assert self.myjit.cpu.XMM0 == 0xffffffffffffffff0000000000000000L + assert self.myjit.cpu.XMM0 == 0xffffffffffffffff0000000000000000 assert self.myjit.cpu.XMM1 == 0x11223345 # Check 128 get / set - assert self.myjit.cpu.get_gpreg()['XMM0'] == 0xffffffffffffffff0000000000000000L + assert self.myjit.cpu.get_gpreg()['XMM0'] == 0xffffffffffffffff0000000000000000 assert self.myjit.cpu.get_gpreg()['XMM1'] == 0x11223345 - assert self.myjit.cpu.get_gpreg()['XMM2'] == 0x11112222333344445555666677778888L - assert self.myjit.cpu.get_gpreg()['XMM2'] == 0x11112222333344445555666677778888L + assert self.myjit.cpu.get_gpreg()['XMM2'] == 0x11112222333344445555666677778888 + assert self.myjit.cpu.get_gpreg()['XMM2'] == 0x11112222333344445555666677778888 if __name__ == "__main__": diff --git a/test/arch/x86/unit/mn_pcmpeq.py b/test/arch/x86/unit/mn_pcmpeq.py index e934d6b5..b8eeafba 100755 --- a/test/arch/x86/unit/mn_pcmpeq.py +++ b/test/arch/x86/unit/mn_pcmpeq.py @@ -81,7 +81,7 @@ class Test_PCMPEQQ(Asm_Test_32): self.myjit.cpu.XMM0 = val def check(self): - assert self.myjit.cpu.XMM0 == 0xffffffffffffffff0000000000000000L + assert self.myjit.cpu.XMM0 == 0xffffffffffffffff0000000000000000 assert self.myjit.cpu.XMM1 == 0x11223345 diff --git a/test/arch/x86/unit/mn_pshufb.py b/test/arch/x86/unit/mn_pshufb.py index d10c18e3..9167b0c1 100755 --- a/test/arch/x86/unit/mn_pshufb.py +++ b/test/arch/x86/unit/mn_pshufb.py @@ -18,8 +18,8 @@ class Test_PSHUFB(Asm_Test_32): ''' def check(self): - assert self.myjit.cpu.MM0 == 0x1122334455667788L - assert self.myjit.cpu.MM1 == 0x8877665544332211L + assert self.myjit.cpu.MM0 == 0x1122334455667788 + assert self.myjit.cpu.MM1 == 0x8877665544332211 if __name__ == "__main__": diff --git a/test/arch/x86/unit/mn_psrl_psll.py b/test/arch/x86/unit/mn_psrl_psll.py index a5428dab..7d9572b0 100755 --- a/test/arch/x86/unit/mn_psrl_psll.py +++ b/test/arch/x86/unit/mn_psrl_psll.py @@ -22,10 +22,10 @@ class Test_PSRL(Asm_Test_32): ''' def check(self): - assert self.myjit.cpu.MM0 == 0x1122334455667788L - assert self.myjit.cpu.MM1 == 0x0112033405560778L - assert self.myjit.cpu.MM2 == 0x0112233405566778L - assert self.myjit.cpu.MM3 == 0x0112233445566778L + assert self.myjit.cpu.MM0 == 0x1122334455667788 + assert self.myjit.cpu.MM1 == 0x0112033405560778 + assert self.myjit.cpu.MM2 == 0x0112233405566778 + assert self.myjit.cpu.MM3 == 0x0112233445566778 class Test_PSLL(Asm_Test_32): TXT = ''' @@ -46,10 +46,10 @@ class Test_PSLL(Asm_Test_32): ''' def check(self): - assert self.myjit.cpu.MM0 == 0x1122334455667788L - assert self.myjit.cpu.MM1 == 0x1220344056607880L - assert self.myjit.cpu.MM2 == 0x1223344056677880L - assert self.myjit.cpu.MM3 == 0x1223344556677880L + assert self.myjit.cpu.MM0 == 0x1122334455667788 + assert self.myjit.cpu.MM1 == 0x1220344056607880 + assert self.myjit.cpu.MM2 == 0x1223344056677880 + assert self.myjit.cpu.MM3 == 0x1223344556677880 if __name__ == "__main__": diff --git a/test/arch/x86/unit/mn_pushpop.py b/test/arch/x86/unit/mn_pushpop.py index 6e9005ca..fedd197b 100755 --- a/test/arch/x86/unit/mn_pushpop.py +++ b/test/arch/x86/unit/mn_pushpop.py @@ -25,7 +25,7 @@ class Test_PUSHAD_32(Asm_Test_32): def test_init(self): init_regs(self) - self.buf = "" + self.buf = b"" for reg_name in reversed(["EAX", "ECX", "EDX", "EBX", "ESP", "EBP", @@ -52,7 +52,7 @@ class Test_PUSHA_32(Asm_Test_32): def test_init(self): init_regs(self) - self.buf = "" + self.buf = b"" for reg_name in reversed(["AX", "CX", "DX", "BX", "SP", "BP", @@ -79,7 +79,7 @@ class Test_PUSHA_16(Asm_Test_16): def test_init(self): init_regs(self) - self.buf = "" + self.buf = b"" for reg_name in reversed(["AX", "CX", "DX", "BX", "SP", "BP", @@ -106,7 +106,7 @@ class Test_PUSHAD_16(Asm_Test_16): def test_init(self): init_regs(self) - self.buf = "" + self.buf = b"" for reg_name in reversed(["EAX", "ECX", "EDX", "EBX", "ESP", "EBP", @@ -133,7 +133,7 @@ class Test_PUSH_mode32_32(Asm_Test_32): def test_init(self): init_regs(self) - self.buf = "" + self.buf = b"" self.buf += pck32(0x11223344) TXT = ''' @@ -156,7 +156,7 @@ class Test_PUSH_mode32_16(Asm_Test_32): def test_init(self): init_regs(self) - self.buf = "" + self.buf = b"" self.buf += pck16(0x1122) TXT = ''' @@ -179,7 +179,7 @@ class Test_PUSH_mode16_16(Asm_Test_16): def test_init(self): init_regs(self) - self.buf = "" + self.buf = b"" self.buf += pck16(0x1122) TXT = ''' @@ -202,7 +202,7 @@ class Test_PUSH_mode16_32(Asm_Test_16): def test_init(self): init_regs(self) - self.buf = "" + self.buf = b"" self.buf += pck32(0x11223344) TXT = ''' diff --git a/test/arch/x86/unit/mn_seh.py b/test/arch/x86/unit/mn_seh.py index dd3fd4ef..1fa0900e 100755 --- a/test/arch/x86/unit/mn_seh.py +++ b/test/arch/x86/unit/mn_seh.py @@ -1,4 +1,5 @@ #! /usr/bin/env python2 +from __future__ import print_function import sys from miasm2.os_dep.win_api_x86_32_seh import fake_seh_handler, build_teb, \ @@ -15,7 +16,7 @@ class Test_SEH(Asm_Test_32): @staticmethod def deal_exception_priv(jitter): - print 'Exception Priv', hex(jitter.cpu.ESP) + print('Exception Priv', hex(jitter.cpu.ESP)) pc = fake_seh_handler(jitter, EXCEPTION_PRIV_INSTRUCTION) jitter.pc = pc jitter.cpu.EIP = pc diff --git a/test/core/asmblock.py b/test/core/asmblock.py index c3e1d11d..48e81e78 100644 --- a/test/core/asmblock.py +++ b/test/core/asmblock.py @@ -1,5 +1,10 @@ +from __future__ import print_function +from builtins import map from pdb import pm +from future.utils import viewitems + +from miasm2.core.utils import decode_hex from miasm2.analysis.machine import Machine from miasm2.analysis.binary import Container from miasm2.core.asmblock import AsmCFG, AsmConstraint, AsmBlock, \ @@ -9,7 +14,7 @@ from miasm2.core.graph import DiGraphSimplifier, MatchGraphJoker from miasm2.expression.expression import ExprId # Initial data: from 'samples/simple_test.bin' -data = "5589e583ec10837d08007509c745fc01100000eb73837d08017709c745fc02100000eb64837d08057709c745fc03100000eb55837d080774138b450801c083f80e7509c745fc04100000eb3c8b450801c083f80e7509c745fc05100000eb298b450883e03085c07409c745fc06100000eb16837d08427509c745fc07100000eb07c745fc081000008b45fcc9c3".decode("hex") +data = decode_hex("5589e583ec10837d08007509c745fc01100000eb73837d08017709c745fc02100000eb64837d08057709c745fc03100000eb55837d080774138b450801c083f80e7509c745fc04100000eb3c8b450801c083f80e7509c745fc05100000eb298b450883e03085c07409c745fc06100000eb16837d08427509c745fc07100000eb07c745fc081000008b45fcc9c3") cont = Container.from_string(data) # Test Disasm engine @@ -18,12 +23,12 @@ mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) ## Disassembly of one block first_block = mdis.dis_block(0) assert len(first_block.lines) == 5 -print first_block +print(first_block) ## Test redisassemble asmcfg first_block_bis = mdis.dis_block(0) assert len(first_block.lines) == len(first_block_bis.lines) -print first_block_bis +print(first_block_bis) ## Disassembly of several block, with cache asmcfg = mdis.dis_multiblock(0) @@ -214,7 +219,7 @@ assert len(asmcfg.pendings) == 0 asmcfg.sanity_check() # Test block_merge -data2 = "31c0eb0c31c9750c31d2eb0c31ffebf831dbebf031edebfc31f6ebf031e4c3".decode("hex") +data2 = decode_hex("31c0eb0c31c9750c31d2eb0c31ffebf831dbebf031edebfc31f6ebf031e4c3") cont2 = Container.from_string(data2) mdis = machine.dis_engine(cont2.bin_stream, loc_db=cont2.loc_db) ## Elements to merge @@ -234,35 +239,35 @@ assert len(asmcfg) == 5 assert len(list(asmcfg.get_bad_blocks())) == 1 ### Check "special" asmcfg entry_asmcfg = asmcfg.heads() -bad_block_lbl = (lbl for lbl in entry_asmcfg - if isinstance(asmcfg.loc_key_to_block(lbl), AsmBlockBad)).next() +bad_block_lbl = next((lbl for lbl in entry_asmcfg + if isinstance(asmcfg.loc_key_to_block(lbl), AsmBlockBad))) entry_asmcfg.remove(bad_block_lbl) -alone_block = (asmcfg.loc_key_to_block(lbl) for lbl in entry_asmcfg - if len(asmcfg.successors(lbl)) == 0).next() +alone_block = next((asmcfg.loc_key_to_block(lbl) for lbl in entry_asmcfg + if len(asmcfg.successors(lbl)) == 0)) entry_asmcfg.remove(alone_block.loc_key) assert alone_block.lines[-1].name == "RET" assert len(alone_block.lines) == 2 ### Check resulting function entry_block = asmcfg.loc_key_to_block(entry_asmcfg.pop()) assert len(entry_block.lines) == 4 -assert map(str, entry_block.lines) == ['XOR EAX, EAX', +assert list(map(str, entry_block.lines)) == ['XOR EAX, EAX', 'XOR EBX, EBX', 'XOR ECX, ECX', 'JNZ loc_key_3'] assert len(asmcfg.successors(entry_block.loc_key)) == 2 assert len(entry_block.bto) == 2 -nextb = asmcfg.loc_key_to_block((cons.loc_key for cons in entry_block.bto - if cons.c_t == AsmConstraint.c_next).next()) -tob = asmcfg.loc_key_to_block((cons.loc_key for cons in entry_block.bto - if cons.c_t == AsmConstraint.c_to).next()) +nextb = asmcfg.loc_key_to_block(next((cons.loc_key for cons in entry_block.bto + if cons.c_t == AsmConstraint.c_next))) +tob = asmcfg.loc_key_to_block(next((cons.loc_key for cons in entry_block.bto + if cons.c_t == AsmConstraint.c_to))) assert len(nextb.lines) == 4 -assert map(str, nextb.lines) == ['XOR EDX, EDX', +assert list(map(str, nextb.lines)) == ['XOR EDX, EDX', 'XOR ESI, ESI', 'XOR EDI, EDI', 'JMP loc_key_4'] assert asmcfg.successors(nextb.loc_key) == [nextb.loc_key] assert len(tob.lines) == 2 -assert map(str, tob.lines) == ['XOR EBP, EBP', +assert list(map(str, tob.lines)) == ['XOR EBP, EBP', 'JMP loc_key_3'] assert asmcfg.successors(tob.loc_key) == [tob.loc_key] @@ -283,13 +288,13 @@ asmcfg.apply_splitting(mdis.loc_db) assert len(asmcfg) == 6 assert len(asmcfg.pendings) == 0 assert len(entry_block.lines) == 2 -assert map(str, entry_block.lines) == ['XOR EAX, EAX', +assert list(map(str, entry_block.lines)) == ['XOR EAX, EAX', 'XOR EBX, EBX'] assert len(asmcfg.successors(entry_block.loc_key)) == 1 lbl_newb = asmcfg.successors(entry_block.loc_key)[0] newb = asmcfg.loc_key_to_block(lbl_newb) assert len(newb.lines) == 2 -assert map(str, newb.lines) == ['XOR ECX, ECX', +assert list(map(str, newb.lines)) == ['XOR ECX, ECX', 'JNZ loc_key_3'] preds = asmcfg.predecessors(lbl_newb) assert len(preds) == 2 @@ -300,7 +305,7 @@ assert asmcfg.edges2constraint[(tob.loc_key, lbl_newb)] == AsmConstraint.c_to # Check double block split -data = "74097405b8020000007405b803000000b804000000c3".decode('hex') +data = decode_hex("74097405b8020000007405b803000000b804000000c3") cont = Container.from_string(data) mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) asmcfg = mdis.dis_multiblock(0) @@ -322,7 +327,7 @@ matcher += bbl0 >> bblB solutions = list(matcher.match(asmcfg)) assert len(solutions) == 1 solution = solutions.pop() -for jbbl, label in solution.iteritems(): +for jbbl, label in viewitems(solution): offset = mdis.loc_db.get_location_offset(label) assert offset == int(jbbl._name, 16) diff --git a/test/core/graph.py b/test/core/graph.py index b71c3d51..484591b7 100644 --- a/test/core/graph.py +++ b/test/core/graph.py @@ -1,3 +1,4 @@ +from __future__ import print_function from miasm2.core.graph import * g = DiGraph() @@ -9,13 +10,13 @@ g.add_edge('a', 'c') g.add_edge('a', 'c') g.add_edge('c', 'c') -print g +print(g) -print [x for x in g.successors('a')] -print [x for x in g.predecessors('a')] -print [x for x in g.predecessors('b')] -print [x for x in g.predecessors('c')] -print [x for x in g.successors('c')] +print([x for x in g.successors('a')]) +print([x for x in g.predecessors('a')]) +print([x for x in g.predecessors('b')]) +print([x for x in g.predecessors('c')]) +print([x for x in g.successors('c')]) """ @@ -226,7 +227,7 @@ j2 = MatchGraphJoker(name="son") ### Check '>>' helper matcher = j1 >> j2 >> j1 ### Check __str__ -print matcher +print(matcher) ### Ensure form assert isinstance(matcher, MatchGraph) assert len(matcher.nodes()) == 2 diff --git a/test/core/interval.py b/test/core/interval.py index 97d45a39..76c95d66 100755 --- a/test/core/interval.py +++ b/test/core/interval.py @@ -1,6 +1,7 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from builtins import range from miasm2.core.interval import * from random import randint from pdb import pm @@ -107,7 +108,7 @@ assert(i_empty.hull() == (None, None)) def gen_random_interval(l=100): r = [] - for j in xrange(5): + for j in range(5): a = randint(0, l) b = a + randint(0, l) r.append((a, b)) @@ -117,7 +118,7 @@ def gen_random_interval(l=100): def check_add(r1, r2): i_sum = interval(r1) + interval(r2) for a, b in r1 + r2: - for i in xrange(a, b + 1): + for i in range(a, b + 1): assert(i in i_sum) @@ -126,7 +127,7 @@ def check_sub(r1, r2): i2 = interval(r2) i_sub = i1 - i2 for a, b in r1: - for i in xrange(a, b + 1): + for i in range(a, b + 1): if i in i2: assert(i not in i_sub) else: @@ -138,14 +139,14 @@ def check_and(r1, r2): i2 = interval(r2) i_and = i1 & i2 for a, b in r1: - for i in xrange(a, b + 1): + for i in range(a, b + 1): if i in i2: assert(i in i_and) else: assert(i not in i_and) -for i in xrange(1000): +for i in range(1000): r1 = gen_random_interval() r2 = gen_random_interval() r3 = gen_random_interval() diff --git a/test/core/locationdb.py b/test/core/locationdb.py index 61bc4563..3db760d8 100644 --- a/test/core/locationdb.py +++ b/test/core/locationdb.py @@ -1,3 +1,4 @@ +from builtins import str from miasm2.core.locationdb import LocationDB @@ -57,9 +58,9 @@ loc_db.consistency_check() # Names manipulation loc_key5 = loc_db.add_location() -name1 = "name1" -name2 = "name2" -name3 = "name3" +name1 = b"name1" +name2 = b"name2" +name3 = b"name3" assert len(loc_db.get_location_names(loc_key5)) == 0 loc_db.add_location_name(loc_key5, name1) loc_db.add_location_name(loc_key5, name2) diff --git a/test/core/parse_asm.py b/test/core/parse_asm.py index ddb195d2..ade9040d 100755 --- a/test/core/parse_asm.py +++ b/test/core/parse_asm.py @@ -1,6 +1,7 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from builtins import range import unittest @@ -69,7 +70,7 @@ class TestParseAsm(unittest.TestCase): asmcfg, loc_db) lbls = [] - for i in xrange(6): + for i in range(6): lbls.append(loc_db.get_name_location('lbl%d' % i)) # align test offset = loc_db.get_location_offset(lbls[5]) @@ -97,7 +98,7 @@ class TestParseAsm(unittest.TestCase): asmcfg, loc_db = parse_txt(mn_x86, 32, ASM0) lbls = [] - for i in xrange(2): + for i in range(2): lbls.append(loc_db.get_name_location('lbl%d' % i)) lbl2block = {} for block in asmcfg.blocks: diff --git a/test/core/sembuilder.py b/test/core/sembuilder.py index f7a96b89..53e9e60e 100644 --- a/test/core/sembuilder.py +++ b/test/core/sembuilder.py @@ -1,3 +1,4 @@ +from __future__ import print_function import inspect from pdb import pm @@ -50,18 +51,18 @@ ir = IR(loc_db) instr = Instr() res = test(ir, instr, a, b, c) -print "[+] Returned:" -print res -print "[+] DocString:", test.__doc__ +print("[+] Returned:") +print(res) +print("[+] DocString:", test.__doc__) -print "[+] Cur instr:" +print("[+] Cur instr:") for statement in res[0]: - print statement + print(statement) -print "[+] Blocks:" +print("[+] Blocks:") for irb in res[1]: - print irb.loc_key + print(irb.loc_key) for assignblk in irb: for expr in assignblk: - print expr - print + print(expr) + print() diff --git a/test/core/test_types.py b/test/core/test_types.py index 92867748..e3914185 100755 --- a/test/core/test_types.py +++ b/test/core/test_types.py @@ -2,8 +2,11 @@ # miasm2.core.types tests +from __future__ import print_function +from builtins import range import struct +from miasm2.core.utils import int_to_byte from miasm2.analysis.machine import Machine from miasm2.core.types import MemStruct, Num, Ptr, Str, \ Array, RawStruct, Union, \ @@ -40,7 +43,7 @@ addr_str = 0x1100 addr_str2 = 0x1200 addr_str3 = 0x1300 # Initialize all mem with 0xaa -jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, "\xaa"*size) +jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, b"\xaa"*size) # MemStruct tests @@ -64,7 +67,7 @@ assert mstruct.flags == 0 assert mstruct.other.val == 0 assert mstruct.s.val == 0 assert mstruct.i.val == 0 -mstruct.memset('\x11') +mstruct.memset(b'\x11') assert mstruct.num == 0x11111111 assert mstruct.flags == 0x11 assert mstruct.other.val == 0x11111111 @@ -122,10 +125,10 @@ assert memval == 8 memstr = Str().lval(jitter.vm, addr_str) memstr.val = "" assert memstr.val == "" -assert jitter.vm.get_mem(memstr.get_addr(), 1) == '\x00' +assert jitter.vm.get_mem(memstr.get_addr(), 1) == b'\x00' memstr.val = "lala" -assert jitter.vm.get_mem(memstr.get_addr(), memstr.get_size()) == 'lala\x00' -jitter.vm.set_mem(memstr.get_addr(), 'MIAMs\x00') +assert jitter.vm.get_mem(memstr.get_addr(), memstr.get_size()) == b'lala\x00' +jitter.vm.set_mem(memstr.get_addr(), b'MIAMs\x00') assert memstr.val == 'MIAMs' ## Ptr(Str()) manipulations @@ -148,7 +151,7 @@ memstr3 = Str("utf16").lval(jitter.vm, addr_str3) memstr3.val = "That's all folks!" assert memstr3.get_addr() != memstr.get_addr() assert memstr3.get_size() != memstr.get_size() # Size is different -assert str(memstr3) != str(memstr) # Mem representation is different +assert bytes(memstr3) != bytes(memstr) # Mem representation is different assert memstr3 != memstr # Encoding is different, so they are not eq assert memstr3.val == memstr.val # But the python value is the same @@ -163,13 +166,13 @@ memarray = Array(Num("I")).lval(jitter.vm, alloc_addr) memarray[0] = 0x02 assert memarray[0] == 0x02 assert jitter.vm.get_mem(memarray.get_addr(), - Num("I").size) == '\x02\x00\x00\x00' + Num("I").size) == b'\x02\x00\x00\x00' memarray[2] = 0xbbbbbbbb assert memarray[2] == 0xbbbbbbbb assert jitter.vm.get_mem(memarray.get_addr() + 2 * Num("I").size, - Num("I").size) == '\xbb\xbb\xbb\xbb' + Num("I").size) == b'\xbb\xbb\xbb\xbb' try: - s = str(memarray) + s = bytes(memarray) assert False, "Should raise" except (NotImplementedError, ValueError): pass @@ -194,16 +197,16 @@ except ValueError: memsarray = Array(Num("I"), 10).lval(jitter.vm) # And Array(type, size).lval generates statically sized types assert memsarray.sizeof() == Num("I").size * 10 -memsarray.memset('\xcc') +memsarray.memset(b'\xcc') assert memsarray[0] == 0xcccccccc assert len(memsarray) == 10 * 4 -assert str(memsarray) == '\xcc' * (4 * 10) +assert bytes(memsarray) == b'\xcc' * (4 * 10) for val in memsarray: assert val == 0xcccccccc assert list(memsarray) == [0xcccccccc] * 10 memsarray[0] = 2 assert memsarray[0] == 2 -assert str(memsarray) == '\x02\x00\x00\x00' + '\xcc' * (4 * 9) +assert bytes(memsarray) == b'\x02\x00\x00\x00' + b'\xcc' * (4 * 9) # Atypical fields (RawStruct and Array) @@ -214,7 +217,7 @@ class MyStruct2(MemStruct): ] ms2 = MyStruct2(jitter.vm) -ms2.memset('\xaa') +ms2.memset(b'\xaa') assert len(ms2) == 15 ## RawStruct @@ -241,7 +244,7 @@ for val in ms2.s2: ### Field assignment (MemSizedArray) array2 = Array(Num("B"), 10).lval(jitter.vm) -jitter.vm.set_mem(array2.get_addr(), '\x02'*10) +jitter.vm.set_mem(array2.get_addr(), b'\x02'*10) for val in array2: assert val == 2 ms2.s2 = array2 @@ -272,7 +275,7 @@ assert cont.one == 0 assert cont.last == 0 assert cont.instruct.foo == 0 assert cont.instruct.bar == 0 -cont.memset('\x11') +cont.memset(b'\x11') assert cont.one == 0x11 assert cont.last == 0x11 assert cont.instruct.foo == 0x11 @@ -286,7 +289,7 @@ assert cont.one == 0x01 assert cont.instruct.foo == 0x02 assert cont.instruct.bar == 0x03 assert cont.last == 0x04 -assert jitter.vm.get_mem(cont.get_addr(), len(cont)) == '\x01\x02\x03\x04' +assert jitter.vm.get_mem(cont.get_addr(), len(cont)) == b'\x01\x02\x03\x04' # Union test @@ -301,7 +304,7 @@ class UniStruct(MemStruct): ] uni = UniStruct(jitter.vm) -jitter.vm.set_mem(uni.get_addr(), ''.join(chr(x) for x in xrange(len(uni)))) +jitter.vm.set_mem(uni.get_addr(), b''.join(int_to_byte(x) for x in range(len(uni)))) assert len(uni) == 6 # 1 + max(InStruct.sizeof(), 4) + 1 assert uni.one == 0x00 assert uni.union.instruct.foo == 0x01 @@ -535,18 +538,18 @@ for idx, off in ((0, 0), (1, 2), (30, 60)): # Repr tests -print "Some struct reprs:\n" -print repr(mstruct), '\n' -print repr(ms2), '\n' -print repr(cont), '\n' -print repr(uni), '\n' -print repr(bit), '\n' -print repr(ideas), '\n' -print repr(Array(MyStruct2.get_type(), 2).lval(jitter.vm, addr)), '\n' -print repr(Num("f").lval(jitter.vm, addr)), '\n' -print repr(memarray) -print repr(memsarray) -print repr(memstr) -print repr(memstr3) - -print "\nOk" # That's all folks! +print("Some struct reprs:\n") +print(repr(mstruct), '\n') +print(repr(ms2), '\n') +print(repr(cont), '\n') +print(repr(uni), '\n') +print(repr(bit), '\n') +print(repr(ideas), '\n') +print(repr(Array(MyStruct2.get_type(), 2).lval(jitter.vm, addr)), '\n') +print(repr(Num("f").lval(jitter.vm, addr)), '\n') +print(repr(memarray)) +print(repr(memsarray)) +print(repr(memstr)) +print(repr(memstr3)) + +print("\nOk") # That's all folks! diff --git a/test/core/utils.py b/test/core/utils.py index b506f904..6f69fdf1 100755 --- a/test/core/utils.py +++ b/test/core/utils.py @@ -2,6 +2,8 @@ #-*- coding:utf-8 -*- +from __future__ import print_function +from builtins import range import unittest @@ -12,7 +14,7 @@ class TestUtils(unittest.TestCase): # Use a callback def logger(key): - print "DELETE", key + print("DELETE", key) # Create a 5/2 dictionary bd = BoundedDict(5, 2, initialdata={"element": "value"}, @@ -26,9 +28,9 @@ class TestUtils(unittest.TestCase): # Increase 'element2' use _ = bd["element2"] - for i in xrange(6): + for i in range(6): bd[i] = i - print "Insert %d -> %s" % (i, bd) + print("Insert %d -> %s" % (i, bd)) assert(len(bd) == 2) diff --git a/test/expr_type/test_chandler.py b/test/expr_type/test_chandler.py index 09c588cb..92ebd0f2 100644 --- a/test/expr_type/test_chandler.py +++ b/test/expr_type/test_chandler.py @@ -4,7 +4,11 @@ Regression test for objc * C Miasm expression to native expression * Miasm expression to type """ +from __future__ import print_function +from future.utils import viewitems +from past.builtins import cmp +from builtins import str from miasm2.expression.expression import ExprInt, ExprId, ExprMem from miasm2.expression.simplifications import expr_simp @@ -147,18 +151,18 @@ types_ast.add_c_decl(text_2) types_mngr = CTypesManagerNotPacked(types_ast, base_types) -for type_id, type_desc in types_mngr.types_ast._types.iteritems(): - print type_id +for type_id, type_desc in viewitems(types_mngr.types_ast._types): + print(type_id) obj = types_mngr.get_objc(type_id) - print obj - print repr(obj) + print(obj) + print(repr(obj)) types_mngr.check_objc(obj) -for type_id, type_desc in types_mngr.types_ast._typedefs.iteritems(): - print type_id +for type_id, type_desc in viewitems(types_mngr.types_ast._typedefs): + print(type_id) obj = types_mngr.get_objc(type_id) - print obj - print repr(obj) + print(obj) + print(repr(obj)) types_mngr.check_objc(obj) void_ptr = types_mngr.void_ptr @@ -200,9 +204,9 @@ ptr_recurse = ExprId("ptr_recurse", 64) obj_test_st = types_mngr.get_objc(CTypeStruct("test_st")) -print repr(obj_test_st) +print(repr(obj_test_st)) obj_test_context = types_mngr.get_objc(CTypeStruct("test_context")) -print repr(obj_test_context) +print(repr(obj_test_context)) assert obj_test_context.size > obj_test_st.size assert cmp(obj_test_st, obj_recurse) != 0 @@ -513,8 +517,8 @@ mychandler.updt_expr_types(expr_types) for (expr, result) in tests: - print "*" * 80 - print "Native expr:", expr + print("*" * 80) + print("Native expr:", expr) result = set(result) expr_c = mychandler.expr_to_c(expr) types = mychandler.expr_to_types(expr) @@ -524,7 +528,7 @@ for (expr, result) in tests: access_c_gen = ExprToAccessC(expr_types, types_mngr) computed = set() for c_str, ctype in mychandler.expr_to_c_and_types(expr): - print c_str, ctype + print(c_str, ctype) computed.add((str(ctype), c_str)) assert computed == result @@ -532,12 +536,12 @@ for (expr, result) in tests: for out_type, out_str in computed: parsed_expr = mychandler.c_to_expr(out_str) parsed_type = mychandler.c_to_type(out_str) - print "Access expr:", parsed_expr - print "Access type:", parsed_type + print("Access expr:", parsed_expr) + print("Access type:", parsed_type) ast = parse_access(out_str) access_c = ast_get_c_access_expr(ast, c_context) - print "Generated access:", access_c + print("Generated access:", access_c) parsed_expr_bis, parsed_type_bis = mychandler.exprc2expr.get_expr(access_c, c_context) assert parsed_expr_bis is not None @@ -551,5 +555,5 @@ for (expr, result) in tests: expr_new1 = expr_simp(parsed_expr) expr_new2 = expr_simp(expr) - print "\t", expr_new1 + print("\t", expr_new1) assert expr_new1 == expr_new2 diff --git a/test/expression/expr_pickle.py b/test/expression/expr_pickle.py index 870f761a..16b87db7 100644 --- a/test/expression/expr_pickle.py +++ b/test/expression/expr_pickle.py @@ -1,3 +1,4 @@ +from __future__ import print_function import pickle from miasm2.expression.expression import ExprInt, ExprAssign, ExprId, \ Expr, ExprCompose, ExprMem @@ -12,15 +13,15 @@ f = a[:8] aff = ExprAssign(a, b) -print 'Pickling' +print('Pickling') out = pickle.dumps((a, b, c, d, e, f, aff)) -print 'Unpickling' +print('Unpickling') new_a, new_b, new_c, new_d, new_e, new_f, new_aff = pickle.loads(out) -print 'Result' -print a, b, c, aff -print id(a), id(b), id(c), id(d), id(e), id(f), id(aff) -print new_a, new_b, new_c, new_d, new_e, new_f, new_aff -print id(new_a), id(new_b), id(new_c), id(new_d), id(new_e), id(new_f), id(new_aff) +print('Result') +print(a, b, c, aff) +print(id(a), id(b), id(c), id(d), id(e), id(f), id(aff)) +print(new_a, new_b, new_c, new_d, new_e, new_f, new_aff) +print(id(new_a), id(new_b), id(new_c), id(new_d), id(new_e), id(new_f), id(new_aff)) assert a == new_a assert b == new_b diff --git a/test/expression/expression.py b/test/expression/expression.py index 1b39ab9f..b8a2642a 100644 --- a/test/expression/expression.py +++ b/test/expression/expression.py @@ -1,3 +1,4 @@ +from __future__ import print_function # # Expression regression tests # # @@ -42,15 +43,15 @@ for expr in [ ExprCond(cond2, cst3, cst4)), ExprCond(ExprCond(cond1, cst1, cst2), cst3, cst4), ]: - print "*" * 80 - print expr + print("*" * 80) + print(expr) sol = possible_values(expr) - print sol - print "Resulting constraints:" + print(sol) + print("Resulting constraints:") for consval in sol: - print "For value %s" % consval.value + print("For value %s" % consval.value) for constraint in consval.constraints: - print "\t%s" % constraint.to_constraint() + print("\t%s" % constraint.to_constraint()) # Repr for expr in [ @@ -63,7 +64,7 @@ for expr in [ A.msb(), ExprAssign(A, cst1), ]: - print repr(expr) + print(repr(expr)) assert expr == eval(repr(expr)) diff --git a/test/expression/expression_helper.py b/test/expression/expression_helper.py index 35873ca4..6c6fb2a9 100755 --- a/test/expression/expression_helper.py +++ b/test/expression/expression_helper.py @@ -1,6 +1,9 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from __future__ import print_function + +from future.utils import viewitems import unittest @@ -25,13 +28,13 @@ class TestExpressionExpressionHelper(unittest.TestCase): vi = Variables_Identifier(exprf) # Use __str__ - print vi + print(vi) # Test the result new_expr = vi.equation ## Force replace in the variable dependency order - for var_id, var_value in reversed(vi.vars.items()): + for var_id, var_value in reversed(list(viewitems(vi.vars))): new_expr = new_expr.replace_expr({var_id: var_value}) self.assertEqual(exprf, new_expr) @@ -39,12 +42,12 @@ class TestExpressionExpressionHelper(unittest.TestCase): vi = Variables_Identifier(exprf, var_prefix="prefix_v") ## Use __str__ - print vi + print(vi) ## Test the result new_expr = vi.equation ### Force replace in the variable dependency order - for var_id, var_value in reversed(vi.vars.items()): + for var_id, var_value in reversed(list(viewitems(vi.vars))): new_expr = new_expr.replace_expr({var_id: var_value}) self.assertEqual(exprf, new_expr) @@ -55,7 +58,7 @@ class TestExpressionExpressionHelper(unittest.TestCase): ## Test the result new_expr = vi2.equation ### Force replace in the variable dependency order - for var_id, var_value in reversed(vi2.vars.items()): + for var_id, var_value in reversed(list(viewitems(vi2.vars))): new_expr = new_expr.replace_expr({var_id: var_value}) self.assertEqual(vi.equation, new_expr) @@ -72,7 +75,7 @@ class TestExpressionExpressionHelper(unittest.TestCase): ## Test the result new_expr = vi2.equation ### Force replace in the variable dependency order - for var_id, var_value in reversed(vi2.vars.items()): + for var_id, var_value in reversed(list(viewitems(vi2.vars))): new_expr = new_expr.replace_expr({var_id: var_value}) self.assertEqual(vi.equation, new_expr) diff --git a/test/expression/modint.py b/test/expression/modint.py index 17c12907..a833ee80 100644 --- a/test/expression/modint.py +++ b/test/expression/modint.py @@ -1,3 +1,4 @@ +from __future__ import print_function from miasm2.expression.modint import * a = uint8(0x42) @@ -10,12 +11,12 @@ e = uint1(1) f = uint8(0x1) g = int8(-3) -print a, b, c -print a + b, a + c, b + c -print a == a, a == b, a == 0x42, a == 0x78 -print a != b, a != a -print d, e -print d + e, d + d, e + e, e + e + e, e + 0x11 +print(a, b, c) +print(a + b, a + c, b + c) +print(a == a, a == b, a == 0x42, a == 0x78) +print(a != b, a != a) +print(d, e) +print(d + e, d + d, e + e, e + e + e, e + 0x11) assert(f == 1) assert(f + 1 == 2) @@ -24,10 +25,10 @@ assert(f + 0xff == 0) assert(f & 0 == 0) assert(f & 0xff == f) assert(0xff & f == f) -assert(f / 1 == f) -assert(1 / f == f) +assert(f // 1 == f) +assert(1 // f == f) +assert(int(f) == 1) assert(int(f) == 1) -assert(long(f) == 1) assert(~f == 0xfe) assert(f << 1 == 2) assert(f << 8 == 0) @@ -53,20 +54,20 @@ assert(f ^ f == 0) assert(f ^ 0 == f) assert(0 ^ f == f) assert(1 ^ f == 0) -assert(c / g == -1) -assert(c / -3 == -1) +assert(c // g == -1) +assert(c // -3 == -1) assert(c % g == 1) assert(c % -3 == 1) -print e + c, c + e, c - e, e - c -print 1000 * a -print hex(a) +print(e + c, c + e, c - e, e - c) +print(1000 * a) +print(hex(a)) define_int(128) define_uint(128) h = uint128(0x11223344556677889900AABBCCDDEEFF) i = int128(-0x9900AABBCCDDEEFF1122334455667788) -assert(i / h == 6) +assert(i //h == 6) assert(i % h == 0x3221aa32bb43cd58d9cc54dd65ee7e) diff --git a/test/expression/parser.py b/test/expression/parser.py index ccae49b0..d05f8262 100644 --- a/test/expression/parser.py +++ b/test/expression/parser.py @@ -1,3 +1,4 @@ +from __future__ import print_function from miasm2.expression.parser import str_to_expr from miasm2.expression.expression import ExprInt, ExprId, ExprSlice, ExprMem, \ ExprCond, ExprCompose, ExprOp, ExprAssign, ExprLoc, LocKey @@ -13,5 +14,5 @@ for expr_test in [ExprInt(0x12, 32), ExprAssign(ExprId('EAX', 32), ExprInt(0x12, 32)), ]: - print 'Test: %s' % expr_test + print('Test: %s' % expr_test) assert str_to_expr(repr(expr_test)) == expr_test diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py index cc33fc54..ae9eb1c0 100644 --- a/test/expression/simplifications.py +++ b/test/expression/simplifications.py @@ -1,3 +1,4 @@ +from __future__ import print_function # # Expression simplification regression tests # # @@ -28,18 +29,18 @@ if args.z3: def check(expr_in, expr_out): """Check that expr_in is always equals to expr_out""" - print "Ensure %s = %s" % (expr_in, expr_out) + print("Ensure %s = %s" % (expr_in, expr_out)) solver = z3.Solver() solver.add(trans.from_expr(expr_in) != trans.from_expr(expr_out)) result = solver.check() if result != z3.unsat: - print "ERROR: a counter-example has been founded:" + print("ERROR: a counter-example has been founded:") model = solver.model() - print model + print(model) - print "Reinjecting in the simplifier:" + print("Reinjecting in the simplifier:") to_rep = {} expressions = expr_in.get_r().union(expr_out.get_r()) for expr in expressions: @@ -54,10 +55,10 @@ if args.z3: new_expr_in = expr_in.replace_expr(to_rep) new_expr_out = expr_out.replace_expr(to_rep) - print "Check %s = %s" % (new_expr_in, new_expr_out) + print("Check %s = %s" % (new_expr_in, new_expr_out)) simp_in = expr_simp_explicit(new_expr_in) simp_out = expr_simp_explicit(new_expr_out) - print "[%s] %s = %s" % (simp_in == simp_out, simp_in, simp_out) + print("[%s] %s = %s" % (simp_in == simp_out, simp_in, simp_out)) # Either the simplification does not stand, either the test is wrong raise RuntimeError("Bad simplification") @@ -313,7 +314,7 @@ to_test = [(ExprInt(1, 32) - ExprInt(1, 32), ExprInt(0, 32)), (ExprCompose(a, ExprInt(0, 32)) * ExprInt(0x123, 64))[32:64]), (ExprInt(0x12, 32), - ExprInt(0x12L, 32)), + ExprInt(0x12, 32)), (ExprCompose(a, b, c)[:16], @@ -335,32 +336,32 @@ to_test = [(ExprInt(1, 32) - ExprInt(1, 32), ExprInt(0, 32)), (ExprCompose(a, b, c)[48:80], ExprCompose(b[16:], c[:16])), - (ExprCompose(a[0:8], b[8:16], ExprInt(0x0L, 48))[12:32], + (ExprCompose(a[0:8], b[8:16], ExprInt(0x0, 48))[12:32], ExprCompose(b[12:16], ExprInt(0, 16)) ), - (ExprCompose(ExprCompose(a[:8], ExprInt(0x0L, 56))[8:32] + (ExprCompose(ExprCompose(a[:8], ExprInt(0x0, 56))[8:32] & - ExprInt(0x1L, 24), - ExprInt(0x0L, 40)), + ExprInt(0x1, 24), + ExprInt(0x0, 40)), ExprInt(0, 64)), - (ExprCompose(ExprCompose(a[:8], ExprInt(0x0L, 56))[:8] + (ExprCompose(ExprCompose(a[:8], ExprInt(0x0, 56))[:8] & - ExprInt(0x1L, 8), - (ExprInt(0x0L, 56))), + ExprInt(0x1, 8), + (ExprInt(0x0, 56))), ExprCompose(a[:8]&ExprInt(1, 8), ExprInt(0, 56))), (ExprCompose(ExprCompose(a[:8], - ExprInt(0x0L, 56))[:32] + ExprInt(0x0, 56))[:32] & - ExprInt(0x1L, 32), - ExprInt(0x0L, 32)), + ExprInt(0x1, 32), + ExprInt(0x0, 32)), ExprCompose(ExprCompose(ExprSlice(a, 0, 8), - ExprInt(0x0L, 24)) + ExprInt(0x0, 24)) & - ExprInt(0x1L, 32), - ExprInt(0x0L, 32)) + ExprInt(0x1, 32), + ExprInt(0x0, 32)) ), (ExprCompose(a[:16], b[:16])[8:32], ExprCompose(a[8:16], b[:16])), @@ -472,9 +473,9 @@ to_test = [(ExprInt(1, 32) - ExprInt(1, 32), ExprInt(0, 32)), ] for e_input, e_check in to_test: - print "#" * 80 + print("#" * 80) e_new = expr_simp_explicit(e_input) - print "original: ", str(e_input), "new: ", str(e_new) + print("original: ", str(e_input), "new: ", str(e_new)) rez = e_new == e_check if not rez: raise ValueError( @@ -741,10 +742,10 @@ to_test = [ ] for e_input, e_check in to_test: - print "#" * 80 + print("#" * 80) e_check = expr_simp(e_check) e_new = expr_simp(e_input) - print "original: ", str(e_input), "new: ", str(e_new) + print("original: ", str(e_input), "new: ", str(e_new)) rez = e_new == e_check if not rez: raise ValueError( @@ -780,10 +781,10 @@ expr_simp.enable_passes(ExpressionSimplifier.PASS_COND) for e_input, e_check in to_test: - print "#" * 80 + print("#" * 80) e_check = expr_simp(e_check) e_new = expr_simp(e_input) - print "original: ", str(e_input), "new: ", str(e_new) + print("original: ", str(e_input), "new: ", str(e_new)) rez = e_new == e_check if not rez: raise ValueError( @@ -902,6 +903,6 @@ for x, y in to_test: assert(x == y) assert(str(x) == str(y)) - print x + print(x) -print 'all tests ok' +print('all tests ok') diff --git a/test/expression/stp.py b/test/expression/stp.py index 38bbf9c8..7650bf45 100755 --- a/test/expression/stp.py +++ b/test/expression/stp.py @@ -1,6 +1,7 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from builtins import range import unittest @@ -11,7 +12,7 @@ class TestIrIr2STP(unittest.TestCase): from miasm2.ir.translators.translator import Translator translator_smt2 = Translator.to_language("smt2") - args = [ExprInt(i, 32) for i in xrange(9)] + args = [ExprInt(i, 32) for i in range(9)] self.assertEqual( translator_smt2.from_expr(ExprOp('|', *args[:2])), r'(bvor (_ bv0 32) (_ bv1 32))') @@ -26,7 +27,7 @@ class TestIrIr2STP(unittest.TestCase): from miasm2.ir.translators.translator import Translator translator_smt2 = Translator.to_language("smt2") - args = [ExprInt(i, 32) for i in xrange(9)] + args = [ExprInt(i, 32) for i in range(9)] self.assertEqual( translator_smt2.from_expr(args[0][1:2]), r'((_ extract 1 1) (_ bv0 32))') diff --git a/test/ir/ir.py b/test/ir/ir.py index 072c90f6..3dd95c3e 100644 --- a/test/ir/ir.py +++ b/test/ir/ir.py @@ -1,3 +1,5 @@ +from future.utils import viewitems + from miasm2.expression.expression import * from miasm2.ir.ir import AssignBlock from miasm2.expression.simplifications import expr_simp @@ -34,10 +36,11 @@ else: assert assignblk1.get_r() == set([id_b]) assert assignblk1.get_w() == set([id_a]) assert assignblk1.get_rw() == {id_a: set([id_b])} -assert assignblk1.keys() == [id_a] +assert list(assignblk1) == [id_a] assert dict(assignblk1) == {id_a: id_b} assert assignblk1[id_a] == id_b -assert list(assignblk1.iteritems()) == assignblk1.items() +assert list(viewitems(assignblk1)) == list(viewitems(assignblk1)) +assert set(assignblk1.iteritems()) == set(assignblk1.items()) ## Simplify assignblk3 = AssignBlock({id_a: id_b - id_b}) diff --git a/test/ir/ir2C.py b/test/ir/ir2C.py index 6df439c2..26683468 100755 --- a/test/ir/ir2C.py +++ b/test/ir/ir2C.py @@ -1,6 +1,7 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from builtins import range import unittest from miasm2.expression.expression import TOK_EQUAL @@ -16,7 +17,7 @@ class TestIrIr2C(unittest.TestCase): from miasm2.expression.expression import ExprInt, ExprOp from miasm2.ir.translators.C import Translator - args = [ExprInt(i, 32) for i in xrange(9)] + args = [ExprInt(i, 32) for i in range(9)] translator = Translator.to_language("C") # Unary operators diff --git a/test/ir/reduce_graph.py b/test/ir/reduce_graph.py index 75ff3410..f6ebad24 100644 --- a/test/ir/reduce_graph.py +++ b/test/ir/reduce_graph.py @@ -1,6 +1,10 @@ """Regression test module for DependencyGraph""" +from __future__ import print_function +from builtins import object from pdb import pm +from future.utils import viewitems + from miasm2.expression.expression import ExprId, ExprInt, ExprAssign, ExprCond, \ ExprLoc, LocKey @@ -162,7 +166,7 @@ for irb in [G1_RES_IRB0]: def cmp_ir_graph(g1, g2): - assert g1.blocks.items() == g2.blocks.items() + assert list(viewitems(g1.blocks)) == list(viewitems(g2.blocks)) assert set(g1.edges()) == set(g2.edges()) @@ -664,11 +668,11 @@ for i, (g_test, g_ref) in enumerate( ], 1): heads = g_test.heads() - print '*'*10, 'Test', i, "*"*10 + print('*'*10, 'Test', i, "*"*10) open('test_in_%d.dot' % i, 'w').write(g_test.dot()) open('test_ref_%d.dot' % i, 'w').write(g_ref.dot()) merge_blocks(g_test, heads) open('test_out_%d.dot' % i, 'w').write(g_test.dot()) cmp_ir_graph(g_test, g_ref) - print '\t', 'OK' + print('\t', 'OK') diff --git a/test/ir/symbexec.py b/test/ir/symbexec.py index 4f01ac3c..3ab99c91 100755 --- a/test/ir/symbexec.py +++ b/test/ir/symbexec.py @@ -1,6 +1,10 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from __future__ import print_function + +from future.utils import viewitems + import unittest @@ -184,18 +188,18 @@ class TestSymbExec(unittest.TestCase): del sb.symbols[id_a] sb.dump() del sb.symbols[ExprMem(id_a, 8)] - print "*"*40, 'Orig:' + print("*"*40, 'Orig:') sb.dump() sb_cp = sb.symbols.copy() - print "*"*40, 'Copy:' + print("*"*40, 'Copy:') sb_cp.dump() # Add symbol at address limit sb.apply_change(ExprMem(ExprInt(0xFFFFFFFE, 32), 32), id_c) sb.dump() found = False - for dst, src in sb.symbols.iteritems(): + for dst, src in viewitems(sb.symbols): if dst == ExprMem(ExprInt(0xFFFFFFFE, 32), 32) and src == id_c: found = True assert found @@ -205,7 +209,7 @@ class TestSymbExec(unittest.TestCase): sb.apply_change(ExprMem(ExprInt(0x7FFFFFFE, 32), 32), id_c) sb.dump() found = False - for dst, src in sb.symbols.iteritems(): + for dst, src in viewitems(sb.symbols): if dst == ExprMem(ExprInt(0x7FFFFFFE, 32), 32) and src == id_c: found = True assert found @@ -219,7 +223,7 @@ class TestSymbExec(unittest.TestCase): sb.apply_change(ExprMem(ExprInt(0x2, 32), 16), ExprMem(ExprInt(0x2, 32), 16)) sb.dump() found = False - for dst, src in sb.symbols.iteritems(): + for dst, src in viewitems(sb.symbols): if dst == ExprMem(ExprInt(0xFFFFFFFE, 32), 32) and src == id_e[16:48]: found = True assert found @@ -230,7 +234,7 @@ class TestSymbExec(unittest.TestCase): # Test memory full - print 'full' + print('full') arch_addr8 = ir_x86_32(loc_db) ircfg = arch_addr8.new_ircfg() # Hack to obtain tiny address space @@ -240,18 +244,18 @@ class TestSymbExec(unittest.TestCase): # Fulfill memory sb_addr8.apply_change(ExprMem(ExprInt(0, 5), 256), ExprInt(0, 256)) sb_addr8.dump() - variables = sb_addr8.symbols.items() + variables = list(viewitems(sb_addr8.symbols)) assert variables == [(ExprMem(ExprInt(0, 5), 256), ExprInt(0, 256))] - print sb_addr8.symbols.symbols_mem + print(sb_addr8.symbols.symbols_mem) sb_addr8.apply_change(ExprMem(ExprInt(0x5, 5), 256), ExprInt(0x123, 256)) sb_addr8.dump() - variables = sb_addr8.symbols.items() + variables = list(viewitems(sb_addr8.symbols)) assert variables == [(ExprMem(ExprInt(0x5, 5), 256), ExprInt(0x123, 256))] - print sb_addr8.symbols.symbols_mem + print(sb_addr8.symbols.symbols_mem) - print 'dump' + print('dump') sb_addr8.symbols.symbols_mem.dump() @@ -281,7 +285,7 @@ class TestSymbExec(unittest.TestCase): assert sb.symbols.symbols_mem.contains_partial(ExprMem(ExprInt(0xFFFFFFFE, 32), 32)) assert not sb.symbols.symbols_mem.contains_partial(ExprMem(ExprInt(0xFFFFFFFF, 32), 8)) - assert sb_addr8.symbols.keys() == [ExprMem(ExprInt(0x5, 5), 256)] + assert list(sb_addr8.symbols) == [ExprMem(ExprInt(0x5, 5), 256)] if __name__ == '__main__': diff --git a/test/ir/translators/smt2.py b/test/ir/translators/smt2.py index 2b5c8df3..78472d0a 100644 --- a/test/ir/translators/smt2.py +++ b/test/ir/translators/smt2.py @@ -10,14 +10,26 @@ c = ExprId('c', 16) d = ExprId('d', 8) e = ExprId('e', 1) -left = ExprCond(e + ExprOp('parity', a), - ExprMem(a * a, 64), - ExprMem(a, 64)) - -cond = ExprSlice(ExprSlice(ExprSlice(a, 0, 32) + b, 0, 16) * c, 0, 8) << ExprOp('>>>', d, ExprInt(0x5L, 8)) -right = ExprCond(cond, - a + ExprInt(0x64L, 64), - ExprInt(0x16L, 64)) +left = ExprCond( + e + ExprOp('parity', a), + ExprMem(a * a, 64), + ExprMem(a, 64) +) + +cond = ( + ExprSlice( + ExprSlice( + ExprSlice(a, 0, 32) + b, 0, 16 + ) * c, + 0, + 8 + ) << ExprOp('>>>', d, ExprInt(0x5, 8)) +) +right = ExprCond( + cond, + a + ExprInt(0x64, 64), + ExprInt(0x16, 64) +) e = ExprAssign(left, right) @@ -32,6 +44,7 @@ smt2 = t_smt2.to_smt2([t_smt2.from_expr(e)]) # parse smt2 string with z3 smt2_z3 = parse_smt2_string(smt2) + # initialise SMT solver s = Solver() diff --git a/test/ir/translators/z3_ir.py b/test/ir/translators/z3_ir.py index 4806ad96..68421bea 100644 --- a/test/ir/translators/z3_ir.py +++ b/test/ir/translators/z3_ir.py @@ -1,3 +1,4 @@ +from __future__ import print_function import z3 from miasm2.core.locationdb import LocationDB @@ -174,5 +175,5 @@ cnttrailzeros3 = translator1.from_expr(ExprOp("cnttrailzeros", ExprInt(0x8000, 3 cntleadzeros3 = translator1.from_expr(ExprOp("cntleadzeros", ExprInt(0x8000, 32))) assert(equiv(cnttrailzeros3, cntleadzeros3)) -print "TranslatorZ3 tests are OK." +print("TranslatorZ3 tests are OK.") diff --git a/test/jitter/bad_block.py b/test/jitter/bad_block.py index ae11e696..0756dfd5 100644 --- a/test/jitter/bad_block.py +++ b/test/jitter/bad_block.py @@ -1,4 +1,5 @@ import sys +from miasm2.core.utils import decode_hex from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, EXCEPT_UNK_MNEMO from miasm2.analysis.machine import Machine @@ -15,7 +16,7 @@ jitter.init_stack() # nop # mov eax, 0x42 # XX -data = "90b842000000ffff90909090".decode('hex') +data = decode_hex("90b842000000ffff90909090") # Will raise memory error at 0x40000006 diff --git a/test/jitter/jit_options.py b/test/jitter/jit_options.py index a0ddbc11..91d59edd 100644 --- a/test/jitter/jit_options.py +++ b/test/jitter/jit_options.py @@ -1,5 +1,8 @@ +from __future__ import print_function import os import sys + +from miasm2.core.utils import decode_hex from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE from miasm2.analysis.machine import Machine from pdb import pm @@ -16,7 +19,7 @@ from pdb import pm # RET -data = "b810000000bb0100000083e8010f44cb75f8c3".decode("hex") +data = decode_hex("b810000000bb0100000083e8010f44cb75f8c3") run_addr = 0x40000000 def code_sentinelle(jitter): @@ -40,7 +43,7 @@ def init_jitter(): return myjit # Test 'max_exec_per_call' -print "[+] First run, to jit blocks" +print("[+] First run, to jit blocks") myjit = init_jitter() myjit.init_run(run_addr) myjit.continue_run() @@ -62,7 +65,7 @@ def cb(jitter): return False ## Second run -print "[+] Second run" +print("[+] Second run") myjit.push_uint32_t(0x1337beef) myjit.cpu.EAX = 0 myjit.init_run(run_addr) @@ -74,7 +77,7 @@ assert myjit.run is True assert myjit.cpu.EAX >= 0xA # Test 'jit_maxline' -print "[+] Run instr one by one" +print("[+] Run instr one by one") myjit = init_jitter() myjit.jit.options["jit_maxline"] = 1 myjit.jit.options["max_exec_per_call"] = 1 diff --git a/test/jitter/jitload.py b/test/jitter/jitload.py index 1a56099f..5473b7d2 100644 --- a/test/jitter/jitload.py +++ b/test/jitter/jitload.py @@ -1,12 +1,13 @@ import sys from pdb import pm +from miasm2.core.utils import decode_hex, encode_hex from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE from miasm2.analysis.machine import Machine from miasm2.expression.expression import ExprId, ExprAssign, ExprInt, ExprMem # Initial data: from 'example/samples/x86_32_sc.bin' -data = "8d49048d5b0180f90174058d5bffeb038d5b0189d8c3".decode("hex") +data = decode_hex("8d49048d5b0180f90174058d5bffeb038d5b0189d8c3") # Init jitter myjit = Machine("x86_32").jitter(sys.argv[1]) @@ -46,4 +47,4 @@ assert myjit.eval_expr(eax) == imm4 ## Changes must be passed on myjit.cpu instance assert myjit.cpu.EAX == 4 ## Memory -assert myjit.eval_expr(memdata).arg.arg == int(data[::-1].encode("hex"), 16) +assert myjit.eval_expr(memdata).arg.arg == int(encode_hex(data[::-1]), 16) diff --git a/test/jitter/jmp_out_mem.py b/test/jitter/jmp_out_mem.py index 93ae8304..ff137b84 100644 --- a/test/jitter/jmp_out_mem.py +++ b/test/jitter/jmp_out_mem.py @@ -1,4 +1,5 @@ import sys +from miasm2.core.utils import decode_hex from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, EXCEPT_ACCESS_VIOL from miasm2.analysis.machine import Machine @@ -17,7 +18,7 @@ jitter.init_stack() # mov eax, 0x42 # jmp 0x20 -data = "90b842000000eb20".decode('hex') +data = decode_hex("90b842000000eb20") # Will raise memory error at 0x40000028 diff --git a/test/jitter/test_post_instr.py b/test/jitter/test_post_instr.py index 0aff667e..ab8f8a74 100644 --- a/test/jitter/test_post_instr.py +++ b/test/jitter/test_post_instr.py @@ -1,27 +1,31 @@ +from __future__ import print_function import sys + +from miasm2.core.utils import decode_hex from miasm2.analysis.machine import Machine -from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, EXCEPT_BREAKPOINT_MEMORY, EXCEPT_ACCESS_VIOL +from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, \ + EXCEPT_BREAKPOINT_MEMORY, EXCEPT_ACCESS_VIOL machine = Machine("x86_32") jitter = machine.jitter(sys.argv[1]) # Prepare stack and reset memory accesses to avoid an exception -jitter.vm.add_memory_page(0x10000, PAGE_READ|PAGE_WRITE, "\x00"*0x1000, "stack") -print jitter.vm +jitter.vm.add_memory_page(0x10000, PAGE_READ|PAGE_WRITE, b"\x00"*0x1000, "stack") +print(jitter.vm) jitter.cpu.ESP = 0x10000 + 0x1000 jitter.push_uint32_t(0x0) jitter.push_uint32_t(0x1337beef) jitter.vm.reset_memory_access() -print hex(jitter.vm.get_exception()) +print(hex(jitter.vm.get_exception())) # Add code, and keep memory write pending -jitter.vm.add_memory_page(0x1000, PAGE_READ|PAGE_WRITE, "\x00"*0x1000, "code page") +jitter.vm.add_memory_page(0x1000, PAGE_READ|PAGE_WRITE, b"\x00"*0x1000, "code page") # MOV EAX, 0x11223344 # RET -jitter.vm.set_mem(0x1000, "B844332211C3".decode('hex')) +jitter.vm.set_mem(0x1000, decode_hex("B844332211C3")) jitter.set_trace_log() diff --git a/test/jitter/vm_mngr.py b/test/jitter/vm_mngr.py index 87bc6f8f..3aa4105e 100644 --- a/test/jitter/vm_mngr.py +++ b/test/jitter/vm_mngr.py @@ -6,7 +6,7 @@ myjit = Machine("x86_32").jitter(sys.argv[1]) base_addr = 0x13371337 page_size = 0x1000 -data = "\x00" * page_size +data = b"\x00" * page_size rights = [0, PAGE_READ, PAGE_WRITE, PAGE_READ|PAGE_WRITE] shuffled_rights = [PAGE_READ, 0, PAGE_READ|PAGE_WRITE, PAGE_WRITE] diff --git a/test/os_dep/common.py b/test/os_dep/common.py index 5d525e32..52512075 100755 --- a/test/os_dep/common.py +++ b/test/os_dep/common.py @@ -1,6 +1,7 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from builtins import range import unittest import logging from miasm2.analysis.machine import Machine @@ -25,7 +26,7 @@ class TestCommonAPI(unittest.TestCase): heap.alloc(jit, 60) ptr = heap.alloc(jit, 10) heap.alloc(jit, 80) - for i in xrange(10): + for i in range(10): self.assertEqual(heap.get_size(jit.vm, ptr+i), 10) if __name__ == '__main__': diff --git a/test/os_dep/linux/stdlib.py b/test/os_dep/linux/stdlib.py index ab39a487..80b99969 100755 --- a/test/os_dep/linux/stdlib.py +++ b/test/os_dep/linux/stdlib.py @@ -19,12 +19,12 @@ class TestLinuxStdlib(unittest.TestCase): def test_xxx_sprintf(self): def alloc_str(s): - s += "\x00" + s += b"\x00" ptr = heap.alloc(jit, len(s)) jit.vm.set_mem(ptr, s) return ptr - fmt = alloc_str("'%s' %d") - str_ = alloc_str("coucou") + fmt = alloc_str(b"'%s' %d") + str_ = alloc_str(b"coucou") buf = heap.alloc(jit,1024) jit.push_uint32_t(1111) @@ -34,7 +34,7 @@ class TestLinuxStdlib(unittest.TestCase): jit.push_uint32_t(0) # ret_ad stdlib.xxx_sprintf(jit) ret = jit.get_str_ansi(buf) - self.assertEqual(ret, "'coucou' 1111") + self.assertEqual(ret, b"'coucou' 1111") if __name__ == '__main__': diff --git a/test/os_dep/linux/test_env.py b/test/os_dep/linux/test_env.py index 0c80571f..1e8e7678 100644 --- a/test/os_dep/linux/test_env.py +++ b/test/os_dep/linux/test_env.py @@ -1,3 +1,4 @@ +from __future__ import print_function import os import sys from pdb import pm @@ -6,7 +7,7 @@ from miasm2.analysis.sandbox import Sandbox_Linux_x86_32, Sandbox_Linux_x86_64,\ Sandbox_Linux_arml, Sandbox_Linux_aarch64l if len(sys.argv) < 2: - print "Usage: %s <arch> ..." % sys.argv[0] + print("Usage: %s <arch> ..." % sys.argv[0]) exit(0) arch = sys.argv[1] diff --git a/test/os_dep/win_api_x86_32.py b/test/os_dep/win_api_x86_32.py index f080ba89..2dcac61d 100755 --- a/test/os_dep/win_api_x86_32.py +++ b/test/os_dep/win_api_x86_32.py @@ -1,6 +1,7 @@ #! /usr/bin/env python2 #-*- coding:utf-8 -*- +from builtins import range import unittest import logging from miasm2.analysis.machine import Machine @@ -27,12 +28,12 @@ class TestWinAPI(unittest.TestCase): def test_msvcrt_sprintf(self): def alloc_str(s): - s += "\x00" + s += b"\x00" ptr = heap.alloc(jit, len(s)) jit.vm.set_mem(ptr, s) return ptr - fmt = alloc_str("'%s' %d") - str_ = alloc_str("coucou") + fmt = alloc_str(b"'%s' %d") + str_ = alloc_str(b"coucou") buf = heap.alloc(jit,1024) jit.push_uint32_t(1111) @@ -42,13 +43,13 @@ class TestWinAPI(unittest.TestCase): jit.push_uint32_t(0) # ret_ad winapi.msvcrt_sprintf(jit) ret = jit.get_str_ansi(buf) - self.assertEqual(ret, "'coucou' 1111") + self.assertEqual(ret, b"'coucou' 1111") def test_msvcrt_swprintf(self): def alloc_str(s): s = s.encode("utf-16le") - s += "\x00\x00" + s += b"\x00\x00" ptr = heap.alloc(jit, len(s)) jit.vm.set_mem(ptr, s) return ptr @@ -63,7 +64,7 @@ class TestWinAPI(unittest.TestCase): jit.push_uint32_t(0) # ret_ad winapi.msvcrt_swprintf(jit) ret = jit.get_str_unic(buf) - self.assertEqual(ret, "'coucou' 1111") + self.assertEqual(ret, u"'coucou' 1111") def test_msvcrt_realloc(self): @@ -88,7 +89,7 @@ class TestWinAPI(unittest.TestCase): # Test with a buffer long enough addr = 0x80000 size = len(winapi.winobjs.cur_dir)+1 - jit.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, "\x00" * (size), "") + jit.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, b"\x00" * (size), "") jit.push_uint32_t(addr) # buf jit.push_uint32_t(size) # size jit.push_uint32_t(0) # @return @@ -98,7 +99,7 @@ class TestWinAPI(unittest.TestCase): self.assertEqual(len(dir_), size_ret) # Test with a buffer too small - jit.vm.set_mem(addr, "\xFF"*size) + jit.vm.set_mem(addr, b"\xFF"*size) jit.push_uint32_t(addr) # buf jit.push_uint32_t(5) # size jit.push_uint32_t(0) # @return @@ -215,7 +216,7 @@ class TestWinAPI(unittest.TestCase): self.assertTrue(vBool) # BOOL WINAPI Process32Next(_In_ HANDLE hSnapshot, _Out_ LPPROCESSENTRY32 lppe); - for i in xrange(3, -1, -1): + for i in range(3, -1, -1): jit.push_uint32_t(jit.stack_base) # lppe jit.push_uint32_t(hSnap) # hSnapshot jit.push_uint32_t(0) # @return diff --git a/test/test_all.py b/test/test_all.py index 008d837f..a8a0d599 100755 --- a/test/test_all.py +++ b/test/test_all.py @@ -1,5 +1,8 @@ #! /usr/bin/env python2 +from __future__ import print_function +from builtins import map +from builtins import range import argparse from distutils.spawn import find_executable import os @@ -52,6 +55,12 @@ testset += RegressionTest(["x86/arch.py"], base_dir="arch", "regression_test32_ia32.bin", "regression_test64_ia32.bin"]) +testset += RegressionTest(["arm/arch.py"], base_dir="arch") +testset += RegressionTest(["aarch64/arch.py"], base_dir="arch") +testset += RegressionTest(["sh4/arch.py"], base_dir="arch") +testset += RegressionTest(["msp430/arch.py"], base_dir="arch") +testset += RegressionTest(["mips32/arch.py"], base_dir="arch") + ### ArchUnit regression tests @@ -92,14 +101,9 @@ for script in ["x86/sem.py", "x86/unit/mn_getset128.py", "x86/unit/mn_cmov.py", "x86/unit/mn_rotsh.py", - "arm/arch.py", "arm/sem.py", "aarch64/unit/mn_ubfm.py", - "aarch64/arch.py", - "msp430/arch.py", "msp430/sem.py", - "sh4/arch.py", - "mips32/arch.py", "mips32/unit/mn_bcc.py", ]: for jitter in ArchUnitTest.jitter_engines: @@ -359,7 +363,7 @@ testset += RegressionTest(["depgraph.py"], base_dir="analysis", products=[fname for fnames in ( ["graph_test_%02d_00.dot" % test_nb, "graph_%02d.dot" % test_nb] - for test_nb in xrange(1, 18)) + for test_nb in range(1, 18)) for fname in fnames] + ["graph_test_%02d_%02d.dot" % (test_nb, res_nb) for (test_nb, res_nb) in ((3, 1), (5, 1), (8, 1), @@ -382,11 +386,11 @@ testset += RegressionTest(["range.py"], base_dir="analysis", testset += RegressionTest(["data_flow.py"], base_dir="analysis", products=[fname for fnames in ( ["simp_graph_%02d.dot" % test_nb, "graph_%02d.dot" % test_nb] - for test_nb in xrange(1, 18)) + for test_nb in range(1, 18)) for fname in fnames]) testset += RegressionTest(["unssa.py"], base_dir="analysis") -for i in xrange(1, 21): +for i in range(1, 21): input_name = "cst_propag/x86_32_sc_%d" % i bin_name = "samples/x86_32/%s.bin" % input_name test_x86_32_cst = SemanticTestAsm("x86_32", None, [input_name]) @@ -410,7 +414,7 @@ class TestDepgraph(RegressionTest): super(TestDepgraph, self).__init__([self.launcher], *args, **kwargs) self.base_dir = os.path.join(self.base_dir, "analysis") - self.products = ["sol_%d.dot" % i for i in xrange(nb_sol)] + self.products = ["sol_%d.dot" % i for i in range(nb_sol)] if implicit: expected_fname = "dg_test_%.2d_implicit_expected.json" self.tags.append(TAGS["z3"]) @@ -507,7 +511,7 @@ class ExampleShellcode(ExampleAssembler): super(ExampleShellcode, self).__init__(*args, **kwargs) self.command_line = ["shellcode.py", self.command_line[0]] + \ - map(Example.get_sample, self.command_line[1:3]) + \ + list(map(Example.get_sample, self.command_line[1:3])) + \ self.command_line[3:] self.products = [self.command_line[3], "graph.dot"] @@ -709,7 +713,7 @@ for options, nb_sol, tag in [([], 8, []), "-m", "x86_32", "0x0", "0x8b", "EAX"] + options, products=["sol_%d.dot" % nb - for nb in xrange(nb_sol)], + for nb in range(nb_sol)], tags=tag) for options, nb_sol, tag in [([], 4, []), @@ -719,7 +723,7 @@ for options, nb_sol, tag in [([], 4, []), "-m", "x86_32", "0x0", "0x19", "EAX"] + options, products=["sol_%d.dot" % nb - for nb in xrange(nb_sol)], + for nb in range(nb_sol)], depends=[test_x86_32_if_reg], tags=tag) @@ -761,17 +765,6 @@ for jitter in ExampleJitter.jitter_engines: ["--jitter", jitter], products=[Example.get_sample("box_upx_exe_unupx.bin")], tags=tags.get(jitter, [])) - if jitter != "python": - tags = tags.get(jitter, []) + [TAGS["long"], TAGS["linux"]] - ls_path = find_executable("ls") - file_path = find_executable("file") - # Launch simulation of "file /bin/ls", with access to libs and ld info - testset += ExampleJitter(["run_with_linuxenv.py", "-v", "-p", - '/(.*lib.*\.so(\.\d+)?)|(/etc/ld.so.*)|(.*magic.*)|(%s)' % ls_path, - ] + ["--jitter", jitter] + [ - file_path, ls_path, - ], - tags=tags) for script, dep in [(["x86_32.py", Example.get_sample("x86_32_sc.bin")], []), @@ -826,10 +819,10 @@ if __name__ == "__main__": action="store_true") parser.add_argument("-t", "--omit-tags", help="Omit tests based on tags \ (tag1,tag2). Available tags are %s. \ -By default, no tag is omitted." % ", ".join(TAGS.keys()), default="") +By default, no tag is omitted." % ", ".join(list(TAGS)), default="") parser.add_argument("-o", "--only-tags", help="Restrict to tests based on tags \ (tag1,tag2). Available tags are %s. \ -By default, all tag are considered." % ", ".join(TAGS.keys()), default="") +By default, all tag are considered." % ", ".join(list(TAGS)), default="") parser.add_argument("-n", "--do-not-clean", help="Do not clean tests products", action="store_true") args = parser.parse_args() @@ -848,14 +841,14 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="") if not tag: continue if tag not in TAGS: - print "%(red)s[TAG]%(end)s" % cosmetics.colors, \ - "Unknown tag '%s'" % tag + print("%(red)s[TAG]%(end)s" % cosmetics.colors, \ + "Unknown tag '%s'" % tag) exit(-1) dest.append(TAGS[tag]) if exclude_tags and include_tags: - print "%(red)s[TAG]%(end)s" % cosmetics.colors, \ - "Omit and Only used together: whitelist mode" + print("%(red)s[TAG]%(end)s" % cosmetics.colors, \ + "Omit and Only used together: whitelist mode") # Handle coverage coveragerc = None @@ -863,8 +856,8 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="") try: import coverage except ImportError: - print "%(red)s[Coverage]%(end)s " % cosmetics.colors + \ - "Python 'coverage' module is required" + print("%(red)s[Coverage]%(end)s " % cosmetics.colors + \ + "Python 'coverage' module is required") exit(-1) # Create directory @@ -875,7 +868,7 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="") coveragerc = os.path.join(cov_dir, ".coveragerc") coverage = os.path.join(cov_dir, ".coverage") - from ConfigParser import ConfigParser + from configparser import ConfigParser from os.path import expanduser config = ConfigParser() @@ -894,7 +887,7 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="") d = {"blue": cosmetics.colors['blue'], "end": cosmetics.colors['end'], "cov_dir": cov_dir} - print "[%(blue)sCoverage%(end)s] Report will be written in %(cov_dir)s" % d + print("[%(blue)sCoverage%(end)s] Report will be written in %(cov_dir)s" % d) # Handle llvm modularity llvm = True @@ -904,8 +897,8 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="") llvm = False if llvm is False: - print "%(red)s[LLVM]%(end)s Python" % cosmetics.colors + \ - "'llvmlite' module is required for llvm tests" + print("%(red)s[LLVM]%(end)s Python" % cosmetics.colors + \ + "'llvmlite' module is required for llvm tests") # Remove llvm tests if TAGS["llvm"] not in exclude_tags: @@ -915,8 +908,8 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="") try: import z3 except ImportError: - print "%(red)s[Z3]%(end)s " % cosmetics.colors + \ - "Z3 and its python binding are necessary for TranslatorZ3." + print("%(red)s[Z3]%(end)s " % cosmetics.colors + \ + "Z3 and its python binding are necessary for TranslatorZ3.") if TAGS["z3"] not in exclude_tags: exclude_tags.append(TAGS["z3"]) @@ -924,8 +917,8 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="") try: import pycparser except ImportError: - print "%(red)s[PYCPARSER]%(end)s " % cosmetics.colors + \ - "pycparser are necessary for Objc." + print("%(red)s[PYCPARSER]%(end)s " % cosmetics.colors + \ + "pycparser are necessary for Objc.") if TAGS["cparser"] not in exclude_tags: exclude_tags.append(TAGS["cparser"]) @@ -952,13 +945,13 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="") # Finalize testset.end(clean=not args.do_not_clean) - print + print() print (cosmetics.colors["green"] + "Result: %d/%d pass" % (len(test_ok), len(test_ok) + len(test_ko)) + cosmetics.colors["end"]) for test, error in test_ko: command_line = " ".join(test.command_line) - print cosmetics.colors["red"] + 'ERROR', cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"] - print error + print(cosmetics.colors["red"] + 'ERROR', cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"]) + print(error) # Exit with an error if at least a test failed exit(testset.tests_passed()) diff --git a/test/utils/cosmetics.py b/test/utils/cosmetics.py index e80e1f09..da7a6bc5 100644 --- a/test/utils/cosmetics.py +++ b/test/utils/cosmetics.py @@ -1,3 +1,4 @@ +from __future__ import print_function import os import platform @@ -33,23 +34,27 @@ def getTerminalSize(): WIDTH = getTerminalSize()[0] -colors = {"red": "\033[91;1m", - "end": "\033[0m", - "green": "\033[92;1m", - "lightcyan": "\033[96m", - "blue": "\033[94;1m"} +colors = { + "red": "\033[91;1m", + "end": "\033[0m", + "green": "\033[92;1m", + "lightcyan": "\033[96m", + "blue": "\033[94;1m" +} if is_win: - colors = {"red": "", - "end": "", - "green": "", - "lightcyan": "", - "blue": ""} + colors = { + "red": "", + "end": "", + "green": "", + "lightcyan": "", + "blue": "" + } def write_colored(text, color, already_printed=0): text_colored = colors[color] + text + colors["end"] - print " " * (WIDTH - already_printed - len(text)) + text_colored + print(" " * (WIDTH - already_printed - len(text)) + text_colored) def write_underline(text): - print "\033[4m" + text + colors["end"] + print("\033[4m" + text + colors["end"]) diff --git a/test/utils/multithread.py b/test/utils/multithread.py index 287b5ebd..d0874dd1 100644 --- a/test/utils/multithread.py +++ b/test/utils/multithread.py @@ -1,24 +1,25 @@ +from __future__ import print_function import sys -import cosmetics +from . import cosmetics import time def task_done(test, error, test_ok, test_ko): command_line = " ".join(test.command_line) if error is not None: - print cosmetics.colors["red"] + 'ERROR', - print cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"] - print error + print(cosmetics.colors["red"] + 'ERROR', end=' ') + print(cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"]) + print(error) test_ko.append((test, error)) else: - print cosmetics.colors["green"] + 'DONE', - print cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"], - print "%ds" % (time.time() - test.start_time) + print(cosmetics.colors["green"] + 'DONE', end=' ') + print(cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"], end=' ') + print("%ds" % (time.time() - test.start_time)) test_ok.append((test, error)) def task_new(test): command_line = " ".join(test.command_line) - print cosmetics.colors["lightcyan"], - print test.base_dir.upper(), command_line, - print cosmetics.colors["end"] + print(cosmetics.colors["lightcyan"], end=' ') + print(test.base_dir.upper(), command_line, end=' ') + print(cosmetics.colors["end"]) diff --git a/test/utils/testset.py b/test/utils/testset.py index 7b60e836..eee0e6f7 100644 --- a/test/utils/testset.py +++ b/test/utils/testset.py @@ -1,10 +1,12 @@ +from __future__ import print_function +from builtins import range import os import subprocess import sys import time from multiprocessing import cpu_count, Queue, Process -from test import Test +from .test import Test class Message(object): @@ -136,7 +138,7 @@ class TestSet(object): if len(self.tests) == 0: # Poison pills - for _ in xrange(self.cpu_c): + for _ in range(self.cpu_c): self.todo_queue.put(None) # All tasks done @@ -201,7 +203,7 @@ class TestSet(object): try: os.remove(product) except OSError: - print "Cleanning error: Unable to remove %s" % product + print("Cleanning error: Unable to remove %s" % product) def add_additional_args(self, args): """Add arguments to used on the test command line @@ -218,7 +220,7 @@ class TestSet(object): # Launch workers processes = [] - for _ in xrange(self.cpu_c): + for _ in range(self.cpu_c): p = Process(target=TestSet.worker, args=(self.todo_queue, self.message_queue, self.additional_args)) |