Trees | Indices | Help |
---|
|
1 """ 2 x86 Support Module 3 """ 4 # Copyright (C) 2007 Invisigoth - See LICENSE file for details 5 import vtrace 6 import struct 7 import traceback 8 import types 9 import vtrace.breakpoints as breakpoints 10 11 import envi.archs.i386 as e_i386 12 13 # Pre-populating these saves a little processing 14 # time (important in tight watchpoint loops) 15 drnames = ["debug%d" % d for d in range(8)] 16 17 dbg_status = "debug6" 18 dbg_ctrl = "debug7" 19 20 dbg_execute = 0 21 dbg_write = 1 22 dbg_read_write = 3 23 24 dbg_types = { 25 "x":dbg_execute, 26 "w":dbg_write, 27 "rw":dbg_read_write, 28 } 2934 # FIXME change this to storing debug0 index and using setRegister() 35113 11437 38 idx = None 39 for i in range(4): 40 if not self.hwdebug[i]: 41 idx = i 42 break 43 44 if idx == None: 45 raise Exception("ERROR: there... are... 4... debug registers!") 46 47 pbits = dbg_types.get(perms) 48 if pbits == None: 49 raise Exception("Unsupported watchpoint perms %s (x86 supports x,w,rw)" % perms) 50 51 if pbits == dbg_execute and size != 1: 52 raise Exception("Watchpoint for execute *must* be 1 byte long!") 53 54 if size not in [1,2,4]: 55 raise Exception("Unsupported watchpoint size %d (x86 supports 1,2,4)" % size) 56 57 ctrl = 0 58 59 self.hwdebug[idx] = address 60 61 ctrl |= 1 << (2*idx) # Enabled 62 mask = ((size-1) << 2) + pbits # perms and size 63 ctrl |= (mask << (16+(4*idx))) 64 #ctrl |= 0x100 # Local exact (ignored by p6+ for read) 65 66 for tid in self.getThreads().keys(): 67 ctx = self.getRegisterContext(tid) 68 ctrl_orig = ctx.getRegister(e_i386.REG_DEBUG7) 69 #print "debug%d: %.8x debug7: %.8x" % (idx,address,ctrl|ctrl_orig) 70 ctx.setRegister(e_i386.REG_DEBUG7, ctrl_orig | ctrl) 71 ctx.setRegister(e_i386.REG_DEBUG0 + idx, address) 72 return7375 idx = None 76 for i in range(4): 77 if self.hwdebug[i] == address: 78 idx = i 79 break 80 81 if idx == None: 82 raise Exception("Watchpoint not found at 0x%.8x" % address) 83 84 self.hwdebug[idx] = 0 85 86 ctrl_disable = ~(1 << (2*idx)) # we are not enabled 87 ctrl_disperm = ~(0xf << (16+(4*idx))) # mask off the rwx stuff 88 ctrl_mask = ctrl_disable & ctrl_disperm 89 90 for tid in self.getThreads().keys(): 91 ctx = self.getRegisterContext(tid) 92 ctrl = ctx.getRegister(e_i386.REG_DEBUG7) 93 ctrl &= ctrl_mask 94 #print "debug%d: %.8x debug7: %.8x" % (idx,address,ctrl|ctrl_orig) 95 ctx.setRegister(e_i386.REG_DEBUG7, ctrl) 96 ctx.setRegister(e_i386.REG_DEBUG0 + idx, 0) 97 return98100 regs = self.getRegisters() 101 status = regs.get(dbg_status) 102 #print "STATUS %.8x" % status 103 if status == None: 104 return None 105 x = status & 0x0f 106 if not x: 107 return None 108 109 for i in range(4): 110 if (x >> i) & 1: 111 return self.hwdebug[i] 112 return None116189118 # Mixin our i386 envi architecture module and register context 119 e_i386.i386Module.__init__(self) 120 # FIXME tracer base should inherit from RegisterContext and we should 121 # just have to load a register definition! 122 e_i386.i386RegisterContext.__init__(self) 123 i386WatchMixin.__init__(self) 124 125 self.setMeta('Architecture', 'i386')126128 self.requireAttached() 129 current = 0 130 sanity = 1000 131 frames = [] 132 133 #FIXME make these by register index 134 #FIXME make these GPREG stuff! (then both are the same) 135 ebp = self.getRegisterByName("ebp") 136 eip = self.getRegisterByName("eip") 137 frames.append((eip,ebp)) 138 139 while ebp != 0 and current < sanity: 140 try: 141 buf = self.readMemory(ebp, 8) 142 ebp,eip = struct.unpack("<LL",buf) 143 frames.append((eip,ebp)) 144 current += 1 145 except: 146 break 147 148 return frames149151 buf = "" 152 finalargs = [] 153 saved_regs = self.getRegisters() 154 sp = self.getStackCounter() 155 pc = self.getProgramCounter() 156 157 for arg in args: 158 if type(arg) == types.StringType: # Nicly map strings into mem 159 buf = arg+"\x00\x00"+buf # Pad with a null for convenience 160 finalargs.append(sp - len(buf)) 161 else: 162 finalargs.append(arg) 163 164 m = len(buf) % 4 165 if m: 166 buf = ("\x00" * (4-m)) + buf 167 168 # Args are 169 #finalargs.reverse() 170 buf = struct.pack("<%dI" % len(finalargs), *finalargs) + buf 171 172 # Saved EIP is target addr so when we hit the break... 173 buf = struct.pack("<I", address) + buf 174 # Calc the new stack pointer 175 newsp = sp-len(buf) 176 # Write the stack buffer in 177 self.writeMemory(newsp, buf) 178 # Setup the stack pointer 179 self.setStackCounter(newsp) 180 # Setup the instruction pointer 181 self.setProgramCounter(address) 182 # Add the magical call-break 183 callbreak = breakpoints.CallBreak(address, saved_regs) 184 self.addBreakpoint(callbreak) 185 # Continue until the CallBreak has been hit 186 while not callbreak.endregs: 187 self.run() 188 return callbreak.endregs
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 on Fri Nov 16 18:22:29 2012 | http://epydoc.sourceforge.net |