Пример #1
0
def getModRM(obj,Mod,RM,data):
    opdsz = obj.misc['opdsz'] or 32
    adrsz = obj.misc['adrsz'] or 32
    seg   = obj.misc['segreg']
    if seg is None: seg=''
    # r/16/32 case:
    if Mod==0b11:
        op1 = env.getreg(RM,opdsz)
        return op1,data
    # m/16/32 case:
    if adrsz==32 and RM==0b100:
        # read SIB byte in data:
        if data.size<8: raise InstructionError(obj)
        sib,data = data[0:8],data[8:data.size]
        # add sib byte:
        obj.bytes += pack(sib)
        # decode base & scaled index
        b = env.getreg(sib[0:3].int(),adrsz)
        i = env.getreg(sib[3:6].int(),adrsz)
        ss = 1<<(sib[6:8].int())
        s = i*ss if not i.ref in ('esp','sp') else 0
    else:
        s = 0
        if adrsz==32:
            b = env.getreg(RM,adrsz)
        else:
            b =  (env.bx+env.si,
                  env.bx+env.di,
                  env.bp+env.si,
                  env.bp+env.di,
                  env.si,
                  env.di,
                  env.bp,
                  env.bx)[RM]

    # check [disp16/32] case:
    if (b is env.ebp or b is env.bp) and Mod==0:
        b=env.cst(0,adrsz)
        Mod = 0b10
    # now read displacement bytes:
    if Mod==0b00:
        d = 0
    elif Mod==0b01:
        if data.size<8: raise InstructionError(obj)
        d = data[0:8]
        data = data[8:data.size]
        obj.bytes += pack(d)
        d = d.signextend(adrsz).int(-1)
    elif Mod==0b10:
        if data.size<adrsz: raise InstructionError(obj)
        d = data[0:adrsz]
        obj.bytes += pack(d)
        data = data[adrsz:data.size]
        d = d.int(-1)
    bs = b+s
    if bs._is_cst and bs.v==0x0:
        bs.v = d
        bs.size = adrsz
        d = 0
    return env.mem(bs,opdsz,seg,d),data
Пример #2
0
def getModRM(obj,Mod,RM,data):
    opdsz = obj.misc['opdsz'] or 32
    adrsz = obj.misc['adrsz'] or 32
    seg   = obj.misc['segreg']
    if seg is None: seg=''
    # r/16/32 case:
    if Mod==0b11:
        op1 = env.getreg(RM,opdsz)
        return op1,data
    # m/16/32 case:
    if adrsz==32 and RM==0b100:
        # read SIB byte in data:
        if data.size<8: raise InstructionError(obj)
        sib,data = data[0:8],data[8:data.size]
        # add sib byte:
        obj.bytes += pack(sib)
        # decode base & scaled index
        b = env.getreg(sib[0:3].int(),adrsz)
        i = env.getreg(sib[3:6].int(),adrsz)
        ss = 1<<(sib[6:8].int())
        s = i*ss if not i.ref in ('esp','sp') else 0
    else:
        s = 0
        if adrsz==32:
            b = env.getreg(RM,adrsz)
        else:
            b =  (env.bx+env.si,
                  env.bx+env.di,
                  env.bp+env.si,
                  env.bp+env.di,
                  env.si,
                  env.di,
                  env.bp,
                  env.bx)[RM]

    # check [disp16/32] case:
    if (b is env.ebp or b is env.bp) and Mod==0:
        b=env.cst(0,adrsz)
        Mod = 0b10
    # now read displacement bytes:
    if Mod==0b00:
        d = 0
    elif Mod==0b01:
        if data.size<8: raise InstructionError(obj)
        d = data[0:8]
        data = data[8:data.size]
        obj.bytes += pack(d)
        d = d.signextend(adrsz).int(-1)
    elif Mod==0b10:
        if data.size<adrsz: raise InstructionError(obj)
        d = data[0:adrsz]
        obj.bytes += pack(d)
        data = data[adrsz:data.size]
        d = d.int(-1)
    bs = b+s
    if bs._is_cst and bs.v==0x0:
        bs.size = adrsz
        bs.v = d & bs.mask
        d = 0
    return env.mem(bs,opdsz,seg,d),data
Пример #3
0
def getModRM(obj, Mod, RM, data):
    opdsz = obj.misc['opdsz'] or env.internals['mode']
    adrsz = obj.misc['adrsz'] or env.internals['mode']
    seg = obj.misc['segreg']
    if seg is None: seg = ''
    # r/16/32 case:
    if Mod == 0b11:
        op1 = env.getreg(RM, opdsz)
        return op1, data
    # 32-bit SIB cases:
    if adrsz == 32 and RM == 0b100:
        # read SIB byte in data:
        if data.size < 8: raise InstructionError(obj)
        sib, data = data[0:8], data[8:data.size]
        # add sib byte:
        obj.bytes += pack(sib)
        # decode base & scaled index
        b = env.getreg(sib[0:3].int(), adrsz)
        i = env.getreg(sib[3:6].int(), adrsz)
        ss = 1 << (sib[6:8].int())
        s = i * ss if not i.ref in ('esp', 'sp') else 0
    else:
        s = 0
        if adrsz == 32:
            b = env.getreg(RM, adrsz)
        else:
            b = (env.bx + env.si, env.bx + env.di, env.bp + env.si,
                 env.bp + env.di, env.si, env.di, env.bp, env.bx)[RM]
    # check [disp16/32] case:
    if (b is env.ebp or b is env.bp) and Mod == 0:
        Mod = 0b10
        bs = s + env.cst(0, adrsz)
    elif s is 0:
        bs = b
    elif env.internals.get('keep_order'):
        # Instead of doing bs = b+s, which will reorder arguments, we do
        # the addition manually, and change 'prop' so the many future calls
        # to 'simplify' does not reorder the arguments
        from amoco.cas import expressions
        bs = expressions.op('+', b, s)
        bs.prop |= 16
    else:
        bs = b + s
    # now read displacement bytes:
    if Mod == 0b00:
        d = 0
    elif Mod == 0b01:
        if data.size < 8: raise InstructionError(obj)
        d = data[0:8]
        data = data[8:data.size]
        obj.bytes += pack(d)
        d = d.signextend(adrsz).int(-1)
    elif Mod == 0b10:
        if data.size < adrsz: raise InstructionError(obj)
        d = data[0:adrsz]
        obj.bytes += pack(d)
        data = data[adrsz:data.size]
        d = d.int(-1)
    if bs._is_cst and bs.v == 0x0:
        bs.size = adrsz
        bs.v = d & bs.mask
        d = 0
    return env.mem(bs, opdsz, seg, d), data