예제 #1
0
 def __init__(self,b=None,**kargs):
     if b is None:
         Bits.__init__(self,0,128)
         for k,v in kargs.iteritems():
             if hasattr(self,k): setattr(self,k,v)
     else:
         Bits.__init__(self,b)
예제 #2
0
파일: core.py 프로젝트: xorpse/amoco
 def decode(self, istr, endian=1, i=None, iclass=instruction):
     # check spec :
     blen = self.fix.size // 8
     if len(istr) < blen:
         raise DecodeError
     bs = istr[0:blen]
     # Bits object created with LSB to MSB byte string:
     ival = bs[::endian]
     b = Bits(ival, self.fix.size, bitorder=1)
     if b & self.mask != self.fix:
         raise DecodeError
     if self.size == 0:  # variable length spec:
         if endian != 1:
             logger.error("invalid endianess")
         b = b // Bits(istr[blen:], bitorder=1)
     # create & update instruction object:
     if i is None:
         i = iclass(bs)
     else:
         i.bytes += bs
     i.spec = self
     # set instruction attributes from directives, and then
     # call hook function with instruction as first parameter
     # and fargs (note that hook can thus overwrite previous attributes)
     for k, v in iter(self.iattr.items()):
         if isinstance(v, FunctionType):
             v = v(b)
         setattr(i, k, v)
     kargs = {}
     for k, v in iter(self.fargs.items()):
         if isinstance(v, FunctionType):
             v = v(b)
         kargs[k] = v
     # and finally call the hook:
     try:
         # check any precondition on i:
         if self.precond and (not self.precond(i)):
             raise InstructionError(i)
         # ok, lets call the spec hook...
         self.hook(obj=i, **kargs)
     except InstructionError:
         # clean up:
         i.bytes = i.bytes[:-len(bs)]
         for k in iter(self.iattr.keys()):
             delattr(i, k)
         raise InstructionError(i)
     return i
예제 #3
0
def test_des_wb():
    K = codecs.decode(b"0123456789ABCDEF", 'hex')
    bK = Bits(K, 64)
    b1 = b"Now is t"
    b2 = b"he time "
    b3 = b"for" + b"\5" * 5
    KT = []
    for r in range(16):
        s, t = table_rKT(r, bK)
        KT.append(t)
    E = DES(K)
    WT = ECB(WhiteDES(KT, table_M1(), table_M2()[0], table_M3()))
    c = WT.enc(b"Now is the time for")
    assert c == E.enc(b1) + E.enc(b2) + E.enc(b3)
예제 #4
0
 def __call__(self, bytestring, **kargs):
     e = self.endian(**kargs)
     adjust = lambda x: x.ival
     if e == -1:
         maxsize = self.maxlen * 8
         adjust = lambda x: x.ival << (maxsize - x.size)
     b = adjust(Bits(bytestring[::e], bitorder=1))
     # get organized/optimized tree of specs:
     fl = self.specs[self.iset(**kargs)]
     while True:
         f, l = fl
         if f == 0:  # we are on a leaf...
             for s in l:  # lets search linearly over this branch
                 try:
                     i = s.decode(bytestring,
                                  e,
                                  i=self.__i,
                                  iclass=self.iclass)
                 except (DecodeError, InstructionError):
                     # logger.debug(u'exception raised by disassembler:'
                     #             u'decoding %s with spec %s'%(codecs.encode(bytestring,'hex'),s.format))
                     continue
                 # we found the instruction (or prefix)
                 if i.spec.pfx is True:
                     if self.__i is None:
                         self.__i = i
                     return self(bytestring[s.mask.size // 8:], **kargs)
                 elif i.spec.pfx > 0:
                     i.misc["xsz"] = i.spec.pfx
                 self.__i = None
                 if "address" in kargs:
                     i.address = kargs["address"]
                 return i
             logger.debug("no instruction spec matching '%s'" %
                          (codecs.encode(bytestring, "hex")))
             break
         else:  # go deeper in the tree according to submask value of b
             fl = l.get(b & f, None)
             if fl is None:
                 break
     self.__i = None
     return None
예제 #5
0
 def buildspec(self):
     ast = specdecode.parseString(self.format, True)
     size, direction = ast[0]
     self.size = size
     fmt = ast[1]
     self.pfx = ast[2]
     xsz = ast[3]
     if self.pfx and xsz:
         self.pfx = xsz
     go = +1
     chklen = True
     if direction == "<":  # format goes from high bits to low bits
         fmt = list(reversed(fmt))
         go = -1
     if size == "*":
         self.size = 0
         chklen = False
         size = 0
         for d in fmt:
             if d in ("-", "0", "1"):
                 size += 1
             elif isinstance(d, Bits):
                 size += d.size
             else:
                 loc = d[2]
                 if loc == "*":
                     break
                 size += loc
     if size % 8 != 0:
         logger.error("ispec length not a multiple of 8 %s" % self.format)
     self.fix = Bits(0, size)  # values of fixed bits
     self.mask = Bits(0, size)  # location of fixed bits
     i = 0
     count = 0
     for d in fmt:
         if chklen and not i < size:
             logger.error("ispec format too wide %s" % self.format)
         # unknown bit (skipped)
         if d == "-":
             i += 1
             count += 1
             continue
         # fixed bit:
         if d in ("0", "1"):
             self.fix[i] = int(d)
             self.mask[i] = 1
             i += 1
             count += 1
             continue
         # fixed byte:
         if isinstance(d, Bits):
             self.fix[i:i + d.size] = d
             self.mask[i:i + d.size] = d.mask
             i += d.size
             count += d.size
             continue
         # directive:
         opt, symbol, loc = d
         if loc != "*":
             if opt == "=" and go > 0:
                 i = i - loc
             sta = i
             sto = i + loc
             if sta < 0 or sto > size:
                 logger.error("ispec directive out of bound in %s" %
                              self.format)
             if opt != "=":
                 count += loc
             i = sto
             if opt == "=" and go < 0:
                 i = i - loc
         else:
             if opt == "=":
                 logger.error("ispec directive invalid length in %s" %
                              self.format)
             sta = i
             sto = None
             i = size
             if count < size:
                 count = size
             chklen = True
         # now set D (fargs or iattr) to corresponding extractor lambdas which
         # will be called when decode is called by the disassembler:
         D = self.fargs
         if "." in opt:
             D = self.iattr
         if symbol in D:
             raise logger.error("ispec symbol %s redefined" % symbol)
         if "~" in opt:
             f = lambda b, p=sta, q=sto: b[p:q]
         elif "#" in opt:
             f = lambda b, p=sta, q=sto, x=go: str(b[p:q])[::x]
         else:
             f = lambda b, p=sta, q=sto: b[p:q].ival
         D[symbol] = f
     if count != size:
         logger.error("ispec size mismatch (%s)" % self.format)
     return ast
예제 #6
0
        return s if toks else highlight(s)


# ispec format parser:
# ---------------------

integer = pp.Regex(r"[1-9][0-9]*")
indxdir = pp.oneOf(["<", ">"])
fixbit = pp.oneOf(["0", "1"])
number = integer | fixbit
number.setParseAction(lambda r: int(r[0]))
unklen = pp.Literal("*")
length = number | unklen
unkbit = pp.oneOf(["-"])
fixbyte = pp.Regex(r"{[0-9a-fA-F][0-9a-fA-F]}").setParseAction(
    lambda r: Bits(int(r[0][1:3], 16), 8))
fixed = fixbyte | fixbit | unkbit
option = pp.oneOf([".", "~", "#", "="])
symbol = pp.Regex(r"[A-Za-z_][A-Za-z0-9_]*")
location = pp.Suppress("(") + length + pp.Suppress(")")
directive = pp.Group(
    pp.Optional(option, default="") + symbol +
    pp.Optional(location, default=1))
speclen = pp.Group(length + pp.Optional(indxdir, default="<"))
specformat = pp.Group(
    pp.Suppress("[") + pp.OneOrMore(directive | fixed) + pp.Suppress("]"))
specoption = pp.Optional(pp.Literal("+").setParseAction(lambda r: True),
                         default=False)
specmore = pp.Optional(pp.Suppress("&") + number, default=0)
specdecode = speclen + specformat + specoption + specmore