about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <devnull@localhost>2011-09-23 13:50:19 +0200
committerserpilliere <devnull@localhost>2011-09-23 13:50:19 +0200
commit3f6e88545d556a5a5958659521efc622e4eaa56d (patch)
tree2f39207fdde5b90396c5ebe7196c486cc9eb36c2
parent7c3c41dbbc1b673aa8e2e5633863dc93d8fedd34 (diff)
downloadmiasm-3f6e88545d556a5a5958659521efc622e4eaa56d.tar.gz
miasm-3f6e88545d556a5a5958659521efc622e4eaa56d.zip
add virt() instead of virt[] for binstream
-rwxr-xr-xexample/disas_and_graph.py81
-rw-r--r--miasm/arch/arm_arch.py4
-rw-r--r--miasm/core/bin_stream.py35
3 files changed, 90 insertions, 30 deletions
diff --git a/example/disas_and_graph.py b/example/disas_and_graph.py
index ba68c44f..57ea3f90 100755
--- a/example/disas_and_graph.py
+++ b/example/disas_and_graph.py
@@ -9,6 +9,9 @@ from miasm.core import asmbloc
 from miasm.core import parse_asm
 from elfesteem import pe
 from miasm.arch import ia32_arch
+from miasm.arch import arm_arch
+from optparse import OptionParser
+
 try:
     from miasm.arch.java_arch import java_mn
 except ImportError:
@@ -18,23 +21,46 @@ import pickle
 import sys
 
 
+
+
 print sys.argv
 
-fname = sys.argv[1]
-ad_to_dis = None
-if len(sys.argv) >2:
-    ad_to_dis = sys.argv[2]
 
+parser = OptionParser()
+parser.add_option('-a', "--address", dest="address", metavar="ADDRESS",
+                  help="address to disasemble")
+parser.add_option('-m', "--architecture", dest="machine",metavar="MACHINE",
+                  help="architecture to use for disasm: arm, x86, ppc, java")
+parser.add_option('-M', "--architecture-options", dest="machine-options",
+                  metavar="MACHINEOPTS",
+                  help="architecture options (16/32/64 bits, ...)")
+parser.add_option('-r', "--rawfile", dest="rawfile", action="store_true",
+                  default=False, metavar=None,
+                  help="dont use PE/ELF/CLASS autodetect, disasm raw file")
+
+(options, args) = parser.parse_args(sys.argv[1:])
+print options, args
+
+fname = args[0]
+ad_to_dis = options.address
 
 
 dll_dyn_funcs = {}
 data = open(fname, 'rb').read()
-if data.startswith("MZ"):
+
+if options.rawfile:
+    in_str = bin_stream.bin_stream(data)
+    if ad_to_dis == None:
+        ad_to_dis = 0
+    else:
+        ad_to_dis = int(ad_to_dis, 16)
+    mnemo = ia32_arch.x86_mn
+elif data.startswith("MZ"):
     e = pe_init.PE(open(fname, 'rb').read())
-    if len(sys.argv) <=2:
+    if ad_to_dis == None:
         ad_to_dis = e.rva2virt(e.Opthdr.AddressOfEntryPoint)
     else:
-        ad_to_dis = int(sys.argv[2], 16)
+        ad_to_dis = int(ad_to_dis, 16)
     in_str = bin_stream.bin_stream(e.virt)
     try:
         dll_dyn_funcs = get_import_address(e)
@@ -44,10 +70,10 @@ if data.startswith("MZ"):
 
 elif data.startswith("\x7fELF") :
     e = elf_init.ELF(open(fname, 'rb').read())
-    if len(sys.argv) <=2:
+    if ad_to_dis == None:
         ad_to_dis = e.Ehdr.entry
     else:
-        ad_to_dis = int(sys.argv[2], 16)
+        ad_to_dis = int(ad_to_dis, 16)
     in_str = bin_stream.bin_stream(e.virt)
     try:
         dll_dyn_funcs = get_import_address_elf(e)
@@ -59,13 +85,13 @@ elif data.startswith("\xca\xfe\xba\xbe"):
     def java_usage():
         print 'usage:'
         print '%s methodname methodtype'%sys.argv[0]
-        print 'possible methods:'
-        for i, (c_name, c_type) in enumerate(methods):
-            print i, str(c_name), str(c_type)
+        print 'possible methods: (use -a N)'
+        for i, ((c_name, c_type), code) in enumerate(methods):
+            print i, "->", str(c_name), str(c_type)
         sys.exit(-1)
 
     e = jclass_init.JCLASS(data)
-    methods = {}
+    methods = []
     for m in e.description.methods:
         name = m.name
         descr = m.descriptor
@@ -73,12 +99,13 @@ elif data.startswith("\xca\xfe\xba\xbe"):
         if not c:
             continue
         code = c[0].code
-        methods[(name, descr)] = code
-    if len(sys.argv) != 4:
+        methods.append(((name, descr), code))
+    if ad_to_dis == None:
         java_usage()
-    if not (sys.argv[2], sys.argv[3]) in methods:
+    ad_to_dis = int(ad_to_dis)
+    if not (0<=ad_to_dis<len(methods)):
         java_usage()
-    in_str = bin_stream.bin_stream(methods[(sys.argv[2], sys.argv[3])])
+    in_str = bin_stream.bin_stream(methods[ad_to_dis][1])
     ad_to_dis = 0
     mnemo = java_mn
     try:
@@ -89,11 +116,22 @@ elif data.startswith("\xca\xfe\xba\xbe"):
 
 
 else:
-    in_str = bin_stream.bin_stream(data)
-    ad_to_dis = 0
-    mnemo = ia32_arch.x86_mn
+    raise ValueError('cannot autodetect file type')
+
+
+if options.machine:
+    machine_dct = {"ia32":ia32_arch.x86_mn,
+                   "arm":arm_arch.arm_mn,
+                   "java":java_mn,
+                   }
+    if not options.machine in machine_dct:
+        raise ValueError('unknown machine', options.machine)
+    if mnemo:
+        print "WARNING forcing machine disasm to ", options.machine
+
+    mnemo = machine_dct[options.machine]
 
-print 'dis', fname, 'at', "0x%.8X"%ad_to_dis
+print 'dis', fname, 'at', "0x%.8X"%ad_to_dis, 'using', mnemo
 
 
 
@@ -106,7 +144,6 @@ from miasm.graph.graph_qt import graph_blocs
 #test symbols from ida
 for (n,f), ad in dll_dyn_funcs.items():
     l = asmbloc.asm_label("%s_%s"%(n, f), ad)
-    print l
     symbol_pool.add(l)
 
 
diff --git a/miasm/arch/arm_arch.py b/miasm/arch/arm_arch.py
index a8c47502..d575d16f 100644
--- a/miasm/arch/arm_arch.py
+++ b/miasm/arch/arm_arch.py
@@ -1957,7 +1957,6 @@ class arm_swi(arm_mn):
 
     def parse_args(self, args):
         self.swint = str2imm(args.pop())
-        
     def breakflow(self):
         return True
     def splitflow(self):
@@ -1965,6 +1964,9 @@ class arm_swi(arm_mn):
     def dstflow(self):
         return False
 
+    def is_subcall(self):
+        return False
+
 
 class arm_szext(arm_mn):
     mask_list = [bm_int01101, bm_opsz, bm_szext, bm_rn, bm_rd, bm_rot, bm_int00, bm_int0111, bm_rm]
diff --git a/miasm/core/bin_stream.py b/miasm/core/bin_stream.py
index c8e64c8d..5db15bcc 100644
--- a/miasm/core/bin_stream.py
+++ b/miasm/core/bin_stream.py
@@ -22,7 +22,7 @@ class bin_stream_mother(type):
         elif arg and type(arg[0]) is file:
             cls = bin_stream_file
         else:
-            cls = bin_stream_str
+            cls = bin_stream_x
 
         i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__)
         i.__init__(*arg)
@@ -39,8 +39,6 @@ class bin_stream(object):
     def hexdump(self, offset, l):
         return
 
-    
-        
 class bin_stream_str(bin_stream):
     def __init__(self, bin ="", offset = 0L):
         if offset>len(bin):
@@ -50,7 +48,6 @@ class bin_stream_str(bin_stream):
         self.l = len(bin)
         if "is_addr_in" in self.bin.__class__.__dict__:
             self.is_addr_in = lambda ad:self.bin.is_addr_in(ad)
-            
 
     def readbs(self, l=1):
         if self.offset+l>self.l:
@@ -75,15 +72,12 @@ class bin_stream_file(bin_stream):
         self.l = self.bin.tell()
         self.offset = offset
 
-        
-                
     def getoffset(self):
         return self.bin.tell()
 
     def setoffset(self, val):
         val = val & 0xFFFFFFFF
         self.bin.seek(val)
-        
     offset = property(getoffset, setoffset)
 
     def readbs(self, l=1):
@@ -99,3 +93,30 @@ class bin_stream_file(bin_stream):
     def __str__(self):
         return str(self.bin)
 
+
+
+class bin_stream_x(bin_stream):
+    def __init__(self, bin ="", offset = 0L):
+        if offset>bin.__len__():
+            raise IOError
+        self.bin = bin
+        self.offset = offset
+        self.l = bin.__len__()
+        if "is_addr_in" in self.bin.__class__.__dict__:
+            self.is_addr_in = lambda ad:self.bin.is_addr_in(ad)
+
+    def readbs(self, l=1):
+        if self.offset+l>self.l:
+            raise IOError
+        self.offset+=l
+        return self.bin(self.offset-l,self.offset)
+
+    def writebs(self, l=1):
+        raise ValueError('writebs unsupported')
+
+    def __str__(self):
+        out =  self.bin[self.offset:]
+        return out
+    def setoffset(self, val):
+        val = val & 0xFFFFFFFF
+        self.offset = val