diff options
Diffstat (limited to 'miasm2/core')
| -rw-r--r-- | miasm2/core/asmblock.py | 8 | ||||
| -rw-r--r-- | miasm2/core/bin_stream.py | 81 | ||||
| -rw-r--r-- | miasm2/core/graph.py | 12 | ||||
| -rw-r--r-- | miasm2/core/objc.py | 8 | ||||
| -rw-r--r-- | miasm2/core/utils.py | 24 |
5 files changed, 117 insertions, 16 deletions
diff --git a/miasm2/core/asmblock.py b/miasm2/core/asmblock.py index 97113be1..8d6456e0 100644 --- a/miasm2/core/asmblock.py +++ b/miasm2/core/asmblock.py @@ -600,8 +600,12 @@ class AsmCFG(DiGraph): return self._pendings def label2block(self, loc_key): - """Return the block corresponding to loc_key @loc_key - @loc_key: LocKey instance""" + """ + DEPRECATED: Use "loc_key_to_block" instead of "label2block" + + Return the block corresponding to loc_key @loc_key + @loc_key: LocKey instance + """ warnings.warn('DEPRECATION WARNING: use "loc_key_to_block" instead of "label2block"') return self.loc_key_to_block(loc_key) diff --git a/miasm2/core/bin_stream.py b/miasm2/core/bin_stream.py index f8d491d2..8bd59467 100644 --- a/miasm2/core/bin_stream.py +++ b/miasm2/core/bin_stream.py @@ -16,6 +16,10 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # +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 + class bin_stream(object): @@ -26,7 +30,7 @@ class bin_stream(object): _atomic_mode = False def __init__(self, *args, **kargs): - pass + self.endianness = LITTLE_ENDIAN def __repr__(self): return "<%s !!>" % self.__class__.__name__ @@ -104,6 +108,55 @@ class bin_stream(object): start += cur_len return out + def get_u8(self, addr, endianness=None): + """ + Return u8 from address @addr + endianness: Optional: LITTLE_ENDIAN/BIG_ENDIAN + """ + if endianness is None: + endianness = self.endianness + data = self.getbytes(addr, 1) + return data + + def get_u16(self, addr, endianness=None): + """ + Return u16 from address @addr + endianness: Optional: LITTLE_ENDIAN/BIG_ENDIAN + """ + if endianness is None: + endianness = self.endianness + data = self.getbytes(addr, 2) + if endianness == LITTLE_ENDIAN: + return upck16le(data) + else: + return upck32be(data) + + def get_u32(self, addr, endianness=None): + """ + Return u32 from address @addr + endianness: Optional: LITTLE_ENDIAN/BIG_ENDIAN + """ + if endianness is None: + endianness = self.endianness + data = self.getbytes(addr, 4) + if endianness == LITTLE_ENDIAN: + return upck32le(data) + else: + return upck32be(data) + + def get_u64(self, addr, endianness=None): + """ + Return u64 from address @addr + endianness: Optional: LITTLE_ENDIAN/BIG_ENDIAN + """ + if endianness is None: + endianness = self.endianness + data = self.getbytes(addr, 8) + if endianness == LITTLE_ENDIAN: + return upck64le(data) + else: + return upck64be(data) + class bin_stream_str(bin_stream): @@ -168,14 +221,14 @@ class bin_stream_file(bin_stream): class bin_stream_container(bin_stream): - def __init__(self, virt_view, offset=0L): + def __init__(self, binary, offset=0L): bin_stream.__init__(self) - self.bin = virt_view - self.l = virt_view.max_addr() + self.bin = binary + self.l = binary.virt.max_addr() self.offset = offset def is_addr_in(self, ad): - return self.bin.is_addr_in(ad) + return self.bin.virt.is_addr_in(ad) def getlen(self): return self.l @@ -184,16 +237,16 @@ class bin_stream_container(bin_stream): if self.offset + l > self.l: raise IOError("not enough bytes") self.offset += l - return self.bin.get(self.offset - l, self.offset) + return self.bin.virt.get(self.offset - l, self.offset) def _getbytes(self, start, l=1): try: - return self.bin.get(start, start + l) + return self.bin.virt.get(start, start + l) except ValueError: raise IOError("cannot get bytes") def __str__(self): - out = self.bin.get(self.offset, self.offset + self.l) + out = self.bin.virt.get(self.offset, self.offset + self.l) return out def setoffset(self, val): @@ -201,11 +254,15 @@ class bin_stream_container(bin_stream): class bin_stream_pe(bin_stream_container): - pass + def __init__(self, binary, *args, **kwargs): + super(bin_stream_pe, self).__init__(binary, *args, **kwargs) + self.endianness = binary._sex class bin_stream_elf(bin_stream_container): - pass + def __init__(self, binary, *args, **kwargs): + super(bin_stream_elf, self).__init__(binary, *args, **kwargs) + self.endianness = binary.sex class bin_stream_vm(bin_stream): @@ -214,6 +271,10 @@ class bin_stream_vm(bin_stream): self.offset = offset self.base_offset = base_offset self.vm = vm + if self.vm.is_little_endian(): + self.endianness = LITTLE_ENDIAN + else: + self.endianness = BIG_ENDIAN def getlen(self): return 0xFFFFFFFFFFFFFFFF diff --git a/miasm2/core/graph.py b/miasm2/core/graph.py index a817c024..35bcf01d 100644 --- a/miasm2/core/graph.py +++ b/miasm2/core/graph.py @@ -456,6 +456,18 @@ class DiGraph(object): break return idoms + def compute_immediate_postdominators(self,tail): + """Compute the immediate postdominators of the graph""" + postdominators = self.compute_postdominators(tail) + ipdoms = {} + + for node in postdominators: + for successor in self.walk_postdominators(node, postdominators): + if successor in postdominators[node] and node != successor: + ipdoms[node] = successor + break + return ipdoms + def compute_dominance_frontier(self, head): """ Compute the dominance frontier of the graph diff --git a/miasm2/core/objc.py b/miasm2/core/objc.py index 9649514d..0e5e8cf4 100644 --- a/miasm2/core/objc.py +++ b/miasm2/core/objc.py @@ -1012,12 +1012,12 @@ class ExprToAccessC(ExprReducer): if not isinstance(node.expr, ExprMem): return None - if node.arg.info is None: + if node.ptr.info is None: return None - assert isinstance(node.arg.info, set) + assert isinstance(node.ptr.info, set) void_type = self.types_mngr.void_ptr found = set() - for subcgenobj in node.arg.info: + for subcgenobj in node.ptr.info: if isinstance(subcgenobj.ctype, ObjCArray): nobj = CGenArray(subcgenobj, 0, void_type.align, @@ -1285,7 +1285,7 @@ class ExprCToExpr(ExprReducer): out = (src.arg, ObjCPtr(src_type.objtype, void_type.align, void_type.size)) elif isinstance(src, ExprMem): - out = (src.arg, ObjCPtr(src_type, + out = (src.ptr, ObjCPtr(src_type, void_type.align, void_type.size)) elif isinstance(src_type, ObjCStruct): out = (src, ObjCPtr(src_type, diff --git a/miasm2/core/utils.py b/miasm2/core/utils.py index 35ddbb82..c1f48418 100644 --- a/miasm2/core/utils.py +++ b/miasm2/core/utils.py @@ -12,6 +12,30 @@ pck16 = lambda x: struct.pack('H', x) pck32 = lambda x: struct.pack('I', x) pck64 = lambda x: struct.pack('Q', x) +# Little endian +upck8le = lambda x: struct.unpack('<B', x)[0] +upck16le = lambda x: struct.unpack('<H', x)[0] +upck32le = lambda x: struct.unpack('<I', x)[0] +upck64le = lambda x: struct.unpack('<Q', x)[0] +pck8le = lambda x: struct.pack('<B', x) +pck16le = lambda x: struct.pack('<H', x) +pck32le = lambda x: struct.pack('<I', x) +pck64le = lambda x: struct.pack('<Q', x) + +# Big endian +upck8be = lambda x: struct.unpack('>B', x)[0] +upck16be = lambda x: struct.unpack('>H', x)[0] +upck32be = lambda x: struct.unpack('>I', x)[0] +upck64be = lambda x: struct.unpack('>Q', x)[0] +pck8be = lambda x: struct.pack('>B', x) +pck16be = lambda x: struct.pack('>H', x) +pck32be = lambda x: struct.pack('>I', x) +pck64be = lambda x: struct.pack('>Q', x) + + +LITTLE_ENDIAN = 1 +BIG_ENDIAN = 2 + pck = {8: pck8, 16: pck16, |