Trees | Indices | Help |
---|
|
1 import envi 2 import envi.bits as e_bits 3 import envi.archs.i386 as e_i386 4 import envi.archs.i386.opcode86 as opcode86 5 6 from envi.archs.amd64.regs import * 7 8 # Pre generate these for fast lookup. Because our REX prefixes have the same relative 9 # bit relationship to eachother, we can cheat a little... 10 amd64_prefixes = list(e_i386.i386_prefixes) 11 amd64_prefixes[0x40] = (0x10 << 16) 12 amd64_prefixes[0x41] = (0x11 << 16) 13 amd64_prefixes[0x42] = (0x12 << 16) 14 amd64_prefixes[0x43] = (0x13 << 16) 15 amd64_prefixes[0x44] = (0x14 << 16) 16 amd64_prefixes[0x45] = (0x15 << 16) 17 amd64_prefixes[0x46] = (0x16 << 16) 18 amd64_prefixes[0x47] = (0x17 << 16) 19 amd64_prefixes[0x48] = (0x18 << 16) 20 amd64_prefixes[0x49] = (0x19 << 16) 21 amd64_prefixes[0x4a] = (0x1a << 16) 22 amd64_prefixes[0x4b] = (0x1b << 16) 23 amd64_prefixes[0x4c] = (0x1c << 16) 24 amd64_prefixes[0x4d] = (0x1d << 16) 25 amd64_prefixes[0x4e] = (0x1e << 16) 26 amd64_prefixes[0x4f] = (0x1f << 16) 27 28 # NOTE: some notes from the intel manual... 29 # REX.W overrides 66, but alternate registers (via REX.B etc..) can have 66 to be 16 bit.. 30 # REX.R only modifies reg for GPR/SSE(SIMD)/ctrl/debug addressing modes. 31 # REX.X only modifies the SIB index value 32 # REX.B modifies modrm r/m field, or SIB base (if SIB present), or opcode reg. 33 # We inherit all the regular intel prefixes... 34 PREFIX_REX = 0x100000 # Shows that the rex prefix is present 35 PREFIX_REX_B = 0x010000 # Bit 0 in REX prefix (0x41) means ModR/M r/m field, SIB base, or opcode reg 36 PREFIX_REX_X = 0x020000 # Bit 1 in REX prefix (0x42) means SIB index extension 37 PREFIX_REX_R = 0x040000 # Bit 2 in REX prefix (0x44) means ModR/M reg extention 38 PREFIX_REX_W = 0x080000 # Bit 3 in REX prefix (0x48) means 64 bit operand 39 40 REX_BUMP = 8 41 MODE_16 = 0 42 MODE_32 = 1 43 MODE_64 = 2 44509152 if self._is_deref == False: # Special lea behavior 53 return self.getOperAddr(op) 54 if emu == None: return None 55 return emu.readMemValue(self.getOperAddr(op, emu), self.tsize)56 59 62 6668 destva = op.va + op.size + self.imm 69 sym = mcanv.syms.getSymByAddr(destva) 70 71 mcanv.addNameText(e_i386.sizenames[self.tsize]) 72 mcanv.addText(" [") 73 mcanv.addNameText("rip", typename="registers") 74 75 if self.imm > 0: 76 mcanv.addText(" + ") 77 if sym != None: 78 mcanv.addVaText("$%s" % repr(sym), destva) 79 else: 80 mcanv.addNameText(str(self.imm)) 81 elif self.imm < 0: 82 mcanv.addText(" - ") 83 if sym != None: 84 mcanv.addVaText("$%s" % repr(sym), destva) 85 else: 86 mcanv.addNameText(str(abs(self.imm))) 87 mcanv.addText("]")8893216 217 218 219 if __name__ == '__main__': 220 import sys 221 d = Amd64Disasm() 222 b = file(sys.argv[1], 'rb').read() 223 offset = 0 224 va = 0x41414141 225 while offset < len(b): 226 op = d.disasm(b, offset, va+offset) 227 print '0x%.8x %s %s' % (va+offset, b[offset:offset+len(op)].encode('hex').ljust(16), repr(op)) 228 offset += len(op) 22995 e_i386.i386Disasm.__init__(self) 96 self._dis_prefixes = amd64_prefixes 97 self._dis_regctx = Amd64RegisterContext() 98 99 # Over-ride these which are in use by the i386 version of the ASM 100 self.ROFFSET_MMX = e_i386.getRegOffset(amd64regs, "mm0") 101 self.ROFFSET_SIMD = e_i386.getRegOffset(amd64regs, "xmm0") 102 self.ROFFSET_DEBUG = e_i386.getRegOffset(amd64regs, "debug0") 103 self.ROFFSET_CTRL = e_i386.getRegOffset(amd64regs, "ctrl0") 104 self.ROFFSET_TEST = e_i386.getRegOffset(amd64regs, "test0") 105 self.ROFFSET_SEG = e_i386.getRegOffset(amd64regs, "es") 106 self.ROFFSET_FPU = e_i386.getRegOffset(amd64regs, "st0")107 108 # NOTE: Technically, the REX must be the *last* prefix specified 109111 """ 112 Use the oper type and prefixes to decide on the tsize for 113 the operand. 114 """ 115 116 mode = MODE_32 117 118 sizelist = opcode86.OPERSIZE.get(opertype, None) 119 if sizelist == None: 120 raise "OPERSIZE FAIL" 121 122 # NOTE: REX takes precedence over 66 123 # (see section 2.2.1.2 in Intel 2a) 124 if prefixes & PREFIX_REX_W: 125 126 mode = MODE_64 127 128 elif prefixes & e_i386.PREFIX_OP_SIZE: 129 130 mode = MODE_16 131 132 return sizelist[mode]133135 # NOTE: Override this because there is no AH etc in 64 bit mode 136 return val + e_i386.RMETA_LOW8137139 """ 140 Return a tuple of (size, Operand) 141 """ 142 size = 1 143 # FIXME this would be best to not parse_modrm twice. tweak it. 144 mod,reg,rm = self.parse_modrm(ord(bytes[offset])) 145 if mod == 0 and rm == 5: 146 imm = e_bits.parsebytes(bytes, offset + size, 4, sign=True) 147 size += 4 148 return(size, Amd64RipRelOper(imm, 4)) 149 150 return e_i386.i386Disasm.extended_parse_modrm(self, bytes, offset, opersize, regbase)151 152 # NOTE: Override a bunch of the address modes to account for REX154 o = e_i386.i386Disasm.ameth_0(self, operflags, operval, tsize, prefixes) 155 # If it has a builtin register, we need to check for bump prefix 156 if prefixes & PREFIX_REX_B and isinstance(o, e_i386.i386RegOper): 157 o.reg += REX_BUMP 158 return o159161 osize, oper = e_i386.i386Disasm.ameth_g(self, bytes, offset, tsize, prefixes) 162 if oper.tsize == 4 and oper.reg != REG_RIP: 163 oper.reg += RMETA_LOW32 164 if prefixes & PREFIX_REX_R: 165 oper.reg += REX_BUMP 166 return osize, oper167169 osize, oper = e_i386.i386Disasm.ameth_c(self, bytes, offset, tsize, prefixes) 170 if prefixes & PREFIX_REX_R: 171 oper.reg += REX_BUMP 172 return osize,oper173175 osize, oper = e_i386.i386Disasm.ameth_d(self, bytes, offset, tsize, prefixes) 176 if prefixes & PREFIX_REX_R: 177 oper.reg += REX_BUMP 178 return osize,oper179181 osize, oper = e_i386.i386Disasm.ameth_v(self, bytes, offset, tsize, prefixes) 182 if prefixes & PREFIX_REX_R: 183 oper.reg += REX_BUMP 184 return osize,oper185 186 # NOTE: The ones below are the only ones to which REX.X or REX.B can apply (besides ameth_0)188 # REMEMBER: all extended mod RM reg fields come from the r/m part. If it 189 # were actually just the reg part, it'd be in one of the above 190 # addressing modes... 191 if getattr(oper, "index", None) != None: 192 if oper.tsize == 4: 193 oper.index += RMETA_LOW32 194 if prefixes & PREFIX_REX_X: 195 oper.index += REX_BUMP 196 # Adjust the size if needed 197 198 # oper.reg will be r/m or SIB base 199 if getattr(oper, "reg", None) != None: 200 # Adjust the size if needed 201 if oper.tsize == 4: 202 oper.reg += RMETA_LOW32 203 204 if prefixes & PREFIX_REX_B: 205 oper.reg += REX_BUMP206208 osize, oper = e_i386.i386Disasm.ameth_e(self, bytes, offset, tsize, prefixes) 209 self._dis_rex_exmodrm(oper, prefixes) 210 return osize, oper211213 osize, oper = e_i386.i386Disasm.ameth_w(self, bytes, offset, tsize, prefixes) 214 self._dis_rex_exmodrm(oper, prefixes) 215 return osize,oper
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 on Fri Nov 16 18:22:18 2012 | http://epydoc.sourceforge.net |