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
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
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