about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--example/disasm/callback.py15
-rw-r--r--example/disasm/dis_binary.py29
-rw-r--r--example/disasm/dis_binary_ir.py35
-rw-r--r--example/disasm/dis_binary_ira.py37
-rw-r--r--example/disasm/dis_x86_string.py22
-rw-r--r--example/disasm/file.py18
-rw-r--r--example/disasm/function.py16
-rw-r--r--example/expression/constant_propagation.py6
-rw-r--r--example/expression/graph_dataflow.py24
-rw-r--r--example/expression/solve_condition_stp.py9
-rw-r--r--example/samples/test_x86_32_dis.S12
-rw-r--r--example/symbol_exec/single_instr.py8
-rw-r--r--test/core/asmblock.py9
-rwxr-xr-xtest/test_all.py29
14 files changed, 189 insertions, 80 deletions
diff --git a/example/disasm/callback.py b/example/disasm/callback.py
index b9a09c09..02416b38 100644
--- a/example/disasm/callback.py
+++ b/example/disasm/callback.py
@@ -1,6 +1,6 @@
-from miasm2.core.bin_stream import bin_stream_str
+from miasm2.analysis.binary import Container
+from miasm2.analysis.machine import Machine
 from miasm2.core.asmblock import AsmConstraint
-from miasm2.arch.x86.disasm import dis_x86_32, cb_x86_funcs
 
 
 def cb_x86_callpop(cur_bloc, loc_db, *args, **kwargs):
@@ -45,17 +45,18 @@ shellcode = ''.join(["\xe8\x00\x00\x00\x00", # CALL $
                      "X",                    # POP EAX
                      "\xc3",                 # RET
                      ])
-bin_stream = bin_stream_str(shellcode)
-mdis = dis_x86_32(bin_stream)
+
+# 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"
 asmcfg = mdis.dis_multiblock(0)
 print "\n".join(str(block) for block in asmcfg.blocks)
 
 # Enable callback
-cb_x86_funcs.append(cb_x86_callpop)
-## Other method:
-## mdis.dis_block_callback = cb_x86_callpop
+mdis.dis_block_callback = cb_x86_callpop
 
 print "=" * 40
 print "With callback:\n"
diff --git a/example/disasm/dis_binary.py b/example/disasm/dis_binary.py
new file mode 100644
index 00000000..3e12ca91
--- /dev/null
+++ b/example/disasm/dis_binary.py
@@ -0,0 +1,29 @@
+import sys
+from miasm2.analysis.binary import Container
+from miasm2.analysis.machine import Machine
+
+fdesc = open(sys.argv[1], 'rb')
+
+# The Container will provide a *bin_stream*, bytes source for the disasm engine
+# It will prodive a view from a PE or an ELF.
+cont = Container.from_stream(fdesc)
+
+# The Machine, instantiated with the detected architecture, will provide tools
+# (disassembler, etc.) to work with this architecture
+machine = Machine(cont.arch)
+
+# Instantiate a disassembler engine, using the previous bin_stream and its
+# associated location DB. The assembly listing will use the binary symbols
+mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
+
+# Run a recursive traversal disassembling from the entry point
+# (do not follow sub functions by default)
+addr = cont.entry_point
+asmcfg = mdis.dis_multiblock(addr)
+
+# Display each basic blocks
+for block in asmcfg.blocks:
+    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
new file mode 100644
index 00000000..6d98d692
--- /dev/null
+++ b/example/disasm/dis_binary_ir.py
@@ -0,0 +1,35 @@
+import sys
+from miasm2.analysis.binary import Container
+from miasm2.analysis.machine import Machine
+
+#####################################
+# Common section from dis_binary.py #
+#####################################
+
+fdesc = open(sys.argv[1], 'rb')
+
+cont = Container.from_stream(fdesc)
+
+machine = Machine(cont.arch)
+
+mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
+
+addr = cont.entry_point
+asmcfg = mdis.dis_multiblock(addr)
+
+#####################################
+#    End common section             #
+#####################################
+
+# Get an IR convertor
+ir_arch = machine.ir(mdis.loc_db)
+
+# Get the IR of the asmcfg
+ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)
+
+# Display each IR basic blocks
+for irblock in ircfg.blocks.values():
+    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
new file mode 100644
index 00000000..c1bd5dc0
--- /dev/null
+++ b/example/disasm/dis_binary_ira.py
@@ -0,0 +1,37 @@
+import sys
+from miasm2.analysis.binary import Container
+from miasm2.analysis.machine import Machine
+
+#####################################
+# Common section from dis_binary.py #
+#####################################
+
+fdesc = open(sys.argv[1], 'rb')
+
+cont = Container.from_stream(fdesc)
+
+machine = Machine(cont.arch)
+
+mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
+
+addr = cont.entry_point
+asmcfg = mdis.dis_multiblock(addr)
+
+#####################################
+#    End common section             #
+#####################################
+
+# Get an IRA convertor
+# The sub call are modelised by default operators
+# call_func_ret and call_func_stack
+ir_arch_analysis = machine.ira(mdis.loc_db)
+
+# Get the IR of the asmcfg
+ircfg_analysis = ir_arch_analysis.new_ircfg_from_asmcfg(asmcfg)
+
+# Display each IR basic blocks
+for irblock in ircfg_analysis.blocks.values():
+    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
new file mode 100644
index 00000000..8f919e4e
--- /dev/null
+++ b/example/disasm/dis_x86_string.py
@@ -0,0 +1,22 @@
+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")
+
+# Instantiate a x86 32 bit architecture
+machine = Machine("x86_32")
+
+# Instantiate a disassembler engine, using the previous bin_stream and its
+# associated location DB.
+mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
+
+# Run a recursive traversal disassembling from address 0
+asmcfg = mdis.dis_multiblock(0)
+
+# Display each basic blocks
+for block in asmcfg.blocks:
+    print block
+
+# Output control flow graph in a dot file
+open('str_cfg.dot', 'w').write(asmcfg.dot())
diff --git a/example/disasm/file.py b/example/disasm/file.py
deleted file mode 100644
index 196e1b1a..00000000
--- a/example/disasm/file.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import sys
-from miasm2.arch.x86.disasm import dis_x86_32
-from miasm2.analysis.binary import Container
-from pdb import pm
-
-if len(sys.argv) != 3:
-    print 'Example:'
-    print "%s samples/box_upx.exe 0x407570" % sys.argv[0]
-    sys.exit(0)
-
-addr = int(sys.argv[2], 0)
-cont = Container.from_stream(open(sys.argv[1]))
-mdis = dis_x86_32(cont.bin_stream)
-# Inform the engine to avoid disassembling null instructions
-mdis.dont_dis_nulstart_bloc = True
-asmcfg = mdis.dis_multiblock(addr)
-
-open('graph.dot', 'w').write(asmcfg.dot())
diff --git a/example/disasm/function.py b/example/disasm/function.py
deleted file mode 100644
index 10495dbc..00000000
--- a/example/disasm/function.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from miasm2.arch.x86.disasm import dis_x86_32
-
-# MOV        EAX, 0x1337BEEF
-# MOV        ECX, 0x4
-# loop:
-# ROL        EAX, 0x8
-# LOOP       loop
-# RET
-shellcode = '\xb8\xef\xbe7\x13\xb9\x04\x00\x00\x00\xc1\xc0\x08\xe2\xfb\xc3'
-mdis = dis_x86_32(shellcode)
-asmcfg = mdis.dis_multiblock(0)
-
-for block in asmcfg.blocks:
-    print block
-
-open('graph.dot', 'w').write(asmcfg.dot())
diff --git a/example/expression/constant_propagation.py b/example/expression/constant_propagation.py
index 0798c404..e70f8163 100644
--- a/example/expression/constant_propagation.py
+++ b/example/expression/constant_propagation.py
@@ -6,7 +6,6 @@ A "constant expression" is an expression based on constants or init regs.
 
 from argparse import ArgumentParser
 
-from miasm2.arch.x86.disasm import dis_x86_32 as dis_engine
 from miasm2.analysis.machine import Machine
 from miasm2.analysis.binary import Container
 from miasm2.analysis.cst_propag import propagate_cst_expr
@@ -27,9 +26,8 @@ args = parser.parse_args()
 machine = Machine("x86_32")
 
 cont = Container.from_stream(open(args.filename))
-ira, dis_engine = machine.ira, machine.dis_engine
-mdis = dis_engine(cont.bin_stream)
-ir_arch = ira(mdis.loc_db)
+mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
+ir_arch = machine.ira(mdis.loc_db)
 addr = int(args.address, 0)
 
 asmcfg = mdis.dis_multiblock(addr)
diff --git a/example/expression/graph_dataflow.py b/example/expression/graph_dataflow.py
index 0951cc1e..92bcf249 100644
--- a/example/expression/graph_dataflow.py
+++ b/example/expression/graph_dataflow.py
@@ -1,10 +1,8 @@
 from argparse import ArgumentParser
-from pdb import pm
-from pprint import pprint
 
+from miasm2.analysis.binary import Container
+from miasm2.analysis.machine import Machine
 from miasm2.expression.expression import get_expr_mem
-from miasm2.arch.x86.ira import ir_a_x86_32
-from miasm2.arch.x86.disasm import dis_x86_32
 from miasm2.analysis.data_analysis import intra_block_flow_raw, inter_block_flow
 from miasm2.core.graph import DiGraph
 from miasm2.ir.symbexec import SymbolicExecutionEngine
@@ -82,7 +80,7 @@ def intra_block_flow_symb(ir_arch, _, flow_graph, irblock, in_nodes, out_nodes):
                 flow_graph.add_uniq_edge(node_n_r, node_n_w)
 
 
-def node2str(self, node):
+def node2str(node):
     out = "%s,%s\\l\\\n%s" % node
     return out
 
@@ -101,9 +99,9 @@ def gen_block_data_flow_graph(ir_arch, ircfg, ad, block_flow_cb):
         if offset == ad:
             irblock_0 = irblock
             break
-    assert(irblock_0 is not None)
+    assert irblock_0 is not None
     flow_graph = DiGraph()
-    flow_graph.node2str = lambda n: node2str(flow_graph, n)
+    flow_graph.node2str = node2str
 
 
     irb_in_nodes = {}
@@ -128,19 +126,21 @@ def gen_block_data_flow_graph(ir_arch, ircfg, ad, block_flow_cb):
     open('data.dot', 'w').write(flow_graph.dot())
 
 
-data = open(args.filename).read()
 ad = int(args.addr, 16)
 
 print 'disasm...'
-mdis = dis_x86_32(data)
+cont = Container.from_stream(open(args.filename))
+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 'generating dataflow graph for:'
-ir_arch = ir_a_x86_32(mdis.loc_db)
-ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)
+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
@@ -151,7 +151,7 @@ if args.symb:
 else:
     block_flow_cb = intra_block_flow_raw
 
-gen_block_data_flow_graph(ir_arch, ircfg, ad, block_flow_cb)
+gen_block_data_flow_graph(ir_arch_analysis, ircfg, ad, block_flow_cb)
 
 print '*' * 40
 print """
diff --git a/example/expression/solve_condition_stp.py b/example/expression/solve_condition_stp.py
index 6962e2ef..c79dd0b8 100644
--- a/example/expression/solve_condition_stp.py
+++ b/example/expression/solve_condition_stp.py
@@ -4,13 +4,13 @@ from optparse import OptionParser
 from pdb import pm
 
 from miasm2.analysis.machine import Machine
+from miasm2.analysis.binary import Container
 from miasm2.expression.expression import ExprInt, ExprCond, ExprId, \
     get_expr_ids, ExprAssign, ExprLoc
 from miasm2.core.bin_stream import bin_stream_str
 from miasm2.ir.symbexec import SymbolicExecutionEngine, get_block
 from miasm2.expression.simplifications import expr_simp
 from miasm2.core import parse_asm
-from miasm2.arch.x86.disasm import dis_x86_32 as dis_engine
 from miasm2.ir.translators.translator  import Translator
 
 machine = Machine("x86_32")
@@ -78,14 +78,11 @@ def emul_symb(ir_arch, ircfg, mdis, states_todo, states_done):
 if __name__ == '__main__':
 
     translator_smt2 = Translator.to_language("smt2")
-    data = open(args[0]).read()
-    bs = bin_stream_str(data)
-
-    mdis = dis_engine(bs)
 
     addr = int(options.address, 16)
 
-
+    cont = Container.from_stream(open(args[0]))
+    mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
     ir_arch = machine.ir(mdis.loc_db)
     ircfg = ir_arch.new_ircfg()
     symbexec = SymbolicExecutionEngine(ir_arch)
diff --git a/example/samples/test_x86_32_dis.S b/example/samples/test_x86_32_dis.S
new file mode 100644
index 00000000..d2e77bf9
--- /dev/null
+++ b/example/samples/test_x86_32_dis.S
@@ -0,0 +1,12 @@
+main:
+	CMP    EAX, 0x10
+	JZ     lbl2
+	MOV    ESI, EAX
+	CMOVA  EAX, EBX
+	JMP    end
+lbl2:
+	MOV    EAX, ECX
+	CALL   0x11223344
+	INC    EAX
+end:
+	RET
diff --git a/example/symbol_exec/single_instr.py b/example/symbol_exec/single_instr.py
index c78f1f7f..2de2a72e 100644
--- a/example/symbol_exec/single_instr.py
+++ b/example/symbol_exec/single_instr.py
@@ -1,7 +1,7 @@
 # Minimalist Symbol Exec example
-from miasm2.core.bin_stream import bin_stream_str
-from miasm2.ir.symbexec import SymbolicExecutionEngine
+from miasm2.analysis.binary import Container
 from miasm2.analysis.machine import Machine
+from miasm2.ir.symbexec import SymbolicExecutionEngine
 from miasm2.core.locationdb import LocationDB
 
 START_ADDR = 0
@@ -14,8 +14,8 @@ line = machine.mn.fromstring("MOV EAX, EBX", loc_db, 32)
 asm = machine.mn.asm(line)[0]
 
 # Get back block
-bin_stream = bin_stream_str(asm)
-mdis = machine.dis_engine(bin_stream, loc_db=loc_db)
+cont = Container.from_string(asm, loc_db = loc_db)
+mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db)
 mdis.lines_wd = 1
 asm_block = mdis.dis_block(START_ADDR)
 
diff --git a/test/core/asmblock.py b/test/core/asmblock.py
index cd1d262a..c3e1d11d 100644
--- a/test/core/asmblock.py
+++ b/test/core/asmblock.py
@@ -1,6 +1,6 @@
 from pdb import pm
 
-from miasm2.arch.x86.disasm import dis_x86_32
+from miasm2.analysis.machine import Machine
 from miasm2.analysis.binary import Container
 from miasm2.core.asmblock import AsmCFG, AsmConstraint, AsmBlock, \
     AsmBlockBad, AsmConstraintTo, AsmConstraintNext, \
@@ -13,7 +13,8 @@ data = "5589e583ec10837d08007509c745fc01100000eb73837d08017709c745fc02100000eb64
 cont = Container.from_string(data)
 
 # Test Disasm engine
-mdis = dis_x86_32(cont.bin_stream)
+machine = Machine("x86_32")
+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
@@ -215,7 +216,7 @@ asmcfg.sanity_check()
 # Test block_merge
 data2 = "31c0eb0c31c9750c31d2eb0c31ffebf831dbebf031edebfc31f6ebf031e4c3".decode("hex")
 cont2 = Container.from_string(data2)
-mdis = dis_x86_32(cont2.bin_stream)
+mdis = machine.dis_engine(cont2.bin_stream, loc_db=cont2.loc_db)
 ## Elements to merge
 asmcfg = mdis.dis_multiblock(0)
 ## Block alone
@@ -301,7 +302,7 @@ assert asmcfg.edges2constraint[(tob.loc_key, lbl_newb)] == AsmConstraint.c_to
 # Check double block split
 data = "74097405b8020000007405b803000000b804000000c3".decode('hex')
 cont = Container.from_string(data)
-mdis = dis_x86_32(cont.bin_stream)
+mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
 asmcfg = mdis.dis_multiblock(0)
 ## Check resulting disasm
 assert len(asmcfg.nodes()) == 6
diff --git a/test/test_all.py b/test/test_all.py
index 42843e90..459d529e 100755
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -538,6 +538,11 @@ test_x86_32_if_reg = ExampleShellcode(['x86_32', 'x86_32_if_reg.S', "x86_32_if_r
 test_x86_32_seh = ExampleShellcode(["x86_32", "x86_32_seh.S", "x86_32_seh.bin",
                                     "--PE"])
 test_x86_32_dead = ExampleShellcode(['x86_32', 'x86_32_dead.S', "x86_32_dead.bin"])
+test_x86_32_dis = ExampleShellcode(
+    [
+        "x86_32", "test_x86_32_dis.S", "test_x86_32_dis.bin", "--PE"
+    ]
+)
 
 test_human = ExampleShellcode(["x86_64", "human.S", "human.bin"])
 
@@ -557,6 +562,7 @@ testset += test_x86_32_if_reg
 testset += test_x86_32_seh
 testset += test_x86_32_dead
 testset += test_human
+testset += test_x86_32_dis
 
 class ExampleDisassembler(Example):
     """Disassembler examples specificities:
@@ -565,15 +571,20 @@ class ExampleDisassembler(Example):
     example_dir = "disasm"
 
 
-for script, prods in [(["single_instr.py"], []),
-                      (["callback.py"], []),
-                      (["function.py"], ["graph.dot"]),
-                      (["file.py", Example.get_sample("box_upx.exe"),
-                        "0x407570"], ["graph.dot"]),
-                      (["full.py", Example.get_sample("box_upx.exe")],
-                       ["graph_execflow.dot", "lines.dot"]),
-                      ]:
-    testset += ExampleDisassembler(script, products=prods)
+for script, prods, depends in [
+        (["single_instr.py"], [], []),
+        (["callback.py"], [], []),
+        (["dis_x86_string.py"], ["str_cfg.dot"], []),
+        (["dis_binary.py", Example.get_sample("test_x86_32_dis.bin"),
+        ], ["bin_cfg.dot"], [test_x86_32_dis]),
+        (["dis_binary_ir.py", Example.get_sample("test_x86_32_dis.bin"),
+        ], ["bin_ir_cfg.dot"], [test_x86_32_dis]),
+        (["dis_binary_ira.py", Example.get_sample("test_x86_32_dis.bin"),
+        ], ["bin_ira_cfg.dot"], [test_x86_32_dis]),
+        (["full.py", Example.get_sample("box_upx.exe")],
+         ["graph_execflow.dot", "lines.dot"], []),
+]:
+    testset += ExampleDisassembler(script, products=prods, depends=depends)
 
 
 class ExampleDisasmFull(ExampleDisassembler):