diff options
| author | Camille Mougey <commial@gmail.com> | 2015-02-11 13:37:19 +0100 |
|---|---|---|
| committer | Camille Mougey <commial@gmail.com> | 2015-02-11 13:37:19 +0100 |
| commit | 5d0d3e5675005d38bfc926a3fe025182ade50720 (patch) | |
| tree | f5bdc465d5d31a1013e88061dd3f0145f123b987 | |
| parent | dc916d52815feee22cc81a29fe1272278d4caefc (diff) | |
| parent | f68d21f7d8ec32d1378a403c4ccb0345f1d5ef56 (diff) | |
| download | miasm-5d0d3e5675005d38bfc926a3fe025182ade50720.tar.gz miasm-5d0d3e5675005d38bfc926a3fe025182ade50720.zip | |
Merge pull request #64 from serpilliere/bin_stream_no_len
Bin stream no len
| -rw-r--r-- | miasm2/core/bin_stream.py | 81 | ||||
| -rw-r--r-- | miasm2/core/bin_stream_ida.py | 14 | ||||
| -rw-r--r-- | miasm2/core/cpu.py | 8 |
3 files changed, 42 insertions, 61 deletions
diff --git a/miasm2/core/bin_stream.py b/miasm2/core/bin_stream.py index 48471b2f..19614661 100644 --- a/miasm2/core/bin_stream.py +++ b/miasm2/core/bin_stream.py @@ -32,17 +32,21 @@ class bin_stream(object): return self.bin[start:start + l] def getbits(self, start, n): + """Return the bits from the bit stream + @start: the offset in bits + @n: number of bits to read + """ if not n: return 0 o = 0 if n > self.getlen() * 8: - raise ValueError('not enought bits %r %r' % (n, len(self.bin) * 8)) + raise IOError('not enough bits %r %r' % (n, len(self.bin) * 8)) while n: # print 'xxx', n, start i = start / 8 c = self.getbytes(i) if not c: - raise IOError + raise IOError('cannot get bytes') c = ord(c) # print 'o', hex(c) r = 8 - start % 8 @@ -60,30 +64,25 @@ class bin_stream(object): class bin_stream_str(bin_stream): - def __init__(self, bin="", offset=0L, shift=0): + def __init__(self, input_str="", offset=0L, shift=0): bin_stream.__init__(self) - if offset > len(bin): - raise IOError - self.bin = bin + self.bin = input_str self.offset = offset self.shift = shift - self.l = len(bin) + self.l = len(input_str) def getbytes(self, start, l=1): if start + l + self.shift > self.l: - raise IOError + raise IOError("not enough bytes in str") return super(bin_stream_str, self).getbytes(start + self.shift, l) def readbs(self, l=1): if self.offset + l + self.shift > self.l: - raise IOError + raise IOError("not enough bytes in str") self.offset += l return self.bin[self.offset - l + self.shift:self.offset + self.shift] - def writebs(self, l=1): - raise ValueError('writebs unsupported') - def __str__(self): out = self.bin[self.offset + self.shift:] return out @@ -91,85 +90,76 @@ class bin_stream_str(bin_stream): def setoffset(self, val): self.offset = val - def __len__(self): - return len(self.bin) - (self.offset + self.shift) - def getlen(self): - return len(self.bin) - (self.offset + self.shift) + return self.l - (self.offset + self.shift) class bin_stream_file(bin_stream): - def __init__(self, bin, offset=0L): + def __init__(self, bin, offset=0L, shift=0): bin_stream.__init__(self) self.bin = bin self.bin.seek(0, 2) + self.shift = shift self.l = self.bin.tell() self.offset = offset def getoffset(self): - return self.bin.tell() + return self.bin.tell() - self.shift def setoffset(self, val): - self.bin.seek(val) + self.bin.seek(val + self.shift) offset = property(getoffset, setoffset) def readbs(self, l=1): - if self.offset + l > self.l: - raise IOError + if self.offset + l + self.shift > self.l: + raise IOError("not enough bytes in file") return self.bin.read(l) - def writebs(self, l=1): - if self.offset + l > self.l: - raise IOError - return self.bin.write(l) - def __str__(self): return str(self.bin) + def getlen(self): + return self.l - (self.offset + self.shift) -class bin_stream_pe(bin_stream): - def __init__(self, bin="", offset=0L): + +class bin_stream_container(bin_stream): + + def __init__(self, virt_view, offset=0L): bin_stream.__init__(self) - # print 'ELF/PE' - self.mylen = len(bin) - if offset > bin.__len__(): - raise IOError - self.bin = bin + self.bin = virt_view + self.l = virt_view.max_addr() self.offset = offset - self.l = bin.__len__() def is_addr_in(self, ad): return self.bin.is_addr_in(ad) def getlen(self): - return self.mylen - # s = self.bin.parent.SHList[-1] - # l = self.bin.parent.rva2virt(s.addr+s.size) - # return l + return self.l def readbs(self, l=1): if self.offset + l > self.l: - raise IOError + raise IOError("not enough bytes") self.offset += l return self.bin(self.offset - l, self.offset) - def writebs(self, l=1): - raise ValueError('writebs unsupported') - def getbytes(self, start, l=1): return self.bin(start, start + l) def __str__(self): - out = self.bin[self.offset:] + out = self.bin(self.offset, self.l) return out def setoffset(self, val): self.offset = val -class bin_stream_elf(bin_stream_pe): +class bin_stream_pe(bin_stream_container): + pass + + +class bin_stream_elf(bin_stream_container): pass @@ -198,8 +188,5 @@ class bin_stream_vm(bin_stream): self.offset += l return s - def writebs(self, l=1): - raise ValueError('writebs unsupported') - def setoffset(self, val): self.offset = val diff --git a/miasm2/core/bin_stream_ida.py b/miasm2/core/bin_stream_ida.py index ff88f03e..62c06c9e 100644 --- a/miasm2/core/bin_stream_ida.py +++ b/miasm2/core/bin_stream_ida.py @@ -1,4 +1,4 @@ -from idc import Byte +from idc import Byte, SegEnd from miasm2.core.bin_stream import bin_stream_str @@ -7,8 +7,6 @@ class bin_stream_ida(bin_stream_str): """ bin_stream implementation for IDA - IDA should provide Byte function - Don't generate xrange using address computation: It can raise error on overflow 7FFFFFFF with 32 bit python """ @@ -20,22 +18,16 @@ class bin_stream_ida(bin_stream_str): def readbs(self, l=1): if self.offset + l > self.l: - raise IOError + raise IOError("not enough bytes") o = self.getbytes(self.offset) self.offset += l return p - def writebs(self, l=1): - raise ValueError('writebs unsupported') - def __str__(self): raise NotImplementedError('Not fully functional') def setoffset(self, val): self.offset = val - def __len__(self): - return 0x7FFFFFFF - def getlen(self): - return 0x7FFFFFFF - self.offset - self.shift + return SegEnd(0) - (self.offset + self.shift) diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py index d5464305..3fbe1e22 100644 --- a/miasm2/core/cpu.py +++ b/miasm2/core/cpu.py @@ -1044,10 +1044,12 @@ class cls_mn(object): # print 'len', fname, l if l is not None: # print fname, hex(bs_l), l - if bs_l * 8 - offset_b < l: - continue # print hex(offset_b) - v = cls.getbits(bs, attrib, offset_b, l) + try: + v = cls.getbits(bs, attrib, offset_b, l) + except IOError: + # Raised if offset is out of bound + continue # print 'TEST', bval, fname, offset_b, cpt, (l, fmask, fbits), # hex(v), hex(v & fmask), hex(fbits), v & fmask == fbits offset_b += l |