def getregB(obj,REG,size): REX = obj.misc['REX'] if REX is None: W=R=X=B=0 else: W,R,X,B=REX return env.getreg(REG+(B<<3),size)
def getregRB(obj, REG, size): if size == 8 and obj.misc["REX"] is None: return getreg8_legacy(REG) W, R, X, B = getREX(obj) if W == 1: size = 64 return env.getreg(REG + (B << 3), size)
def getregRW(obj,REG,size): REX = obj.misc['REX'] if REX is None: W=R=X=B=0 else: W,R,X,B=REX if W==1: size=64 return env.getreg(REG+(R<<3),size)
def getModRM(obj, Mod, RM, data, REX=None): opdsz = obj.misc['opdsz'] or 32 adrsz = obj.misc['adrsz'] or 64 seg = obj.misc['segreg'] if seg is None: seg = '' W, R, X, B = REX or getREX(obj) if opdsz != 8 and W == 1: opdsz = 64 # r/16/32/64 case: if Mod == 0b11: op1 = getregB(obj, RM, opdsz) return op1, data # SIB cases : if adrsz != 16 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((B << 3) + sib[0:3].int(), adrsz) i = env.getreg((X << 3) + sib[3:6].int(), adrsz) ss = 1 << (sib[6:8].int()) s = i * ss if not i.ref in ('rsp', 'esp', 'sp') else 0 else: s = 0 if adrsz != 16: b = env.getreg((B << 3) + 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 special disp32 case (RIP-relative addressing): if Mod == 0: if RM == 0b101: b = env.rip if seg is '': seg = env.cs Mod = 0b10 elif b.ref in ('rbp', 'r13'): b = s + env.cst(0, adrsz) s = 0 Mod = 0b10 if 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 bs = env.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: immsz = adrsz if immsz == 64: immsz = 32 if data.size < immsz: raise InstructionError(obj) d = data[0:immsz] obj.bytes += pack(d) data = data[immsz:data.size] d = d.int(-1) if bs._is_cst and bs.v == 0x0: bs.v = d bs.size = adrsz d = 0 if opdsz is 'mm': opdsz = 64 return env.mem(bs, opdsz, seg, d), data
def getregB(obj, REG, size): if size == 8 and obj.misc['REX'] is None: return getreg8_legacy(REG) W, R, X, B = getREX(obj) return env.getreg(REG + (B << 3), size)
def getModRM(obj,Mod,RM,data): opdsz = obj.misc['opdsz'] or 32 adrsz = obj.misc['adrsz'] or 64 seg = obj.misc['segreg'] if seg is None: seg='' REX = obj.misc['REX'] if REX is None: W=R=X=B=0 else: W,R,X,B = REX if W==1: opdsz = 64 # r/16/32 case: if Mod==0b11: op1 = env.getreg((B<<3)+RM,opdsz) return op1,data # m/16/32 case: if adrsz!=16 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((B<<3)+sib[0:3].int(),adrsz) i = env.getreg((X<<3)+sib[3:6].int(),adrsz) ss = 1<<(sib[6:8].int()) s = i*ss if not i.ref in ('rsp','esp','sp') else 0 else: s = 0 if adrsz!=16: b = env.getreg((B<<3)+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.rbp or b is env.r13) and Mod==0: b=env.rip if seg is '': seg = env.cs Mod = 0b10 if (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: immsz = adrsz if immsz==64: immsz=32 if data.size<immsz: raise InstructionError(obj) d = data[0:immsz] obj.bytes += pack(d) data = data[immsz: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