def readProcessMappings(process): """ Read all memory mappings of the specified process. Return a list of MemoryMapping objects, or empty list if it's not possible to read the mappings. May raise a ProcessError. """ maps = [] if not HAS_PROC: return maps try: mapsfile = openProc("%s/maps" % process.pid) except ProcError as err: raise ProcessError(process, "Unable to read process maps: %s" % err) try: for line in mapsfile: line = line.rstrip() match = PROC_MAP_REGEX.match(line) if not match: raise ProcessError(process, "Unable to parse memoy mapping: %r" % line) map = MemoryMapping(process, int(match.group(1), 16), int(match.group(2), 16), match.group(3), int(match.group(4), 16), int(match.group(5), 16), int(match.group(6), 16), int(match.group(7)), match.group(8)) maps.append(map) finally: mapsfile.close() return maps
def createBreakpoint(self, address, size=1): bp = self.findBreakpoint(address) if bp: raise ProcessError(self, "A breakpoint is already set: %s" % bp) bp = Breakpoint(self, address, size) self.breakpoints[address] = bp return bp
def readBytes(self, address, size): if not self.read_mem_file: filename = '/proc/%u/mem' % self.pid try: self.read_mem_file = open(filename, 'rb', 0) except IOError as err: message = "Unable to open %s: fallback to ptrace implementation" % filename if err.errno != EACCES: warning(message) else: info(message) self.readBytes = self._readBytes return self.readBytes(address, size) try: mem = self.read_mem_file mem.seek(address) data = mem.read(size) except (IOError, ValueError) as err: raise ProcessError( self, "readBytes(%s, %s) error: %s" % (formatAddress(address), size, err)) if len(data) == 0 and size: # Issue #10: If the process was not created by the debugger # (ex: fork), the kernel may deny reading private mappings of # /proc/pid/mem to the debugger, depending on the kernel # version and kernel config (ex: SELinux enabled or not). # # Fallback to PTRACE_PEEKTEXT. It is slower but a debugger # tracing the process is always allowed to use it. self.readBytes = self._readBytes return self.readBytes(address, size) return data
def setreg(self, name, value): regs = self.getregs() if name in CPU_SUB_REGISTERS: full_name, shift, mask = CPU_SUB_REGISTERS[name] full_value = getattr(regs, full_name) full_value &= ~mask full_value |= ((value & mask) << shift) value = full_value name = full_name if name not in REGISTER_NAMES: raise ProcessError(self, "Unknown register: %r" % name) setattr(regs, name, value) self.setregs(regs)
def ptraceEvent(self, event): if not HAS_PTRACE_EVENTS: self.notImplementedError() if event in NEW_PROCESS_EVENT: new_pid = ptrace_geteventmsg(self.pid) new_process = self.debugger.addProcess(new_pid, is_attached=True, parent=self) return NewProcessEvent(new_process) elif event == PTRACE_EVENT_EXEC: return ProcessExecution(self) else: raise ProcessError(self, "Unknown ptrace event: %r" % event)
def getreg(self, name): try: name, shift, mask = CPU_SUB_REGISTERS[name] except KeyError: shift = 0 mask = None if name not in REGISTER_NAMES: raise ProcessError(self, "Unknown register: %r" % name) regs = self.getregs() value = getattr(regs, name) value >>= shift if mask: value &= mask return value
def readProcessMappings(process): """ Read all memory mappings of the specified process. Return a list of MemoryMapping objects, or empty list if it's not possible to read the mappings. May raise a ProcessError. """ maps = [] if not HAS_PROC: return maps try: mapsfile = openProc("%s/maps" % process.pid) except ProcError, err: raise ProcessError(process, "Unable to read process maps: %s" % err)
def processStatus(self, status): # Process exited? if WIFEXITED(status): code = WEXITSTATUS(status) event = self.processExited(code) # Process killed by a signal? elif WIFSIGNALED(status): signum = WTERMSIG(status) event = self.processKilled(signum) # Invalid process status? elif not WIFSTOPPED(status): raise ProcessError(self, "Unknown process status: %r" % status) # Ptrace event? elif HAS_PTRACE_EVENTS and WPTRACEEVENT(status): event = WPTRACEEVENT(status) event = self.ptraceEvent(event) else: signum = WSTOPSIG(status) event = self.processSignal(signum) return event
def getFramePointer(self): if CPU_FRAME_POINTER: return self.getreg(CPU_FRAME_POINTER) else: raise ProcessError(self, "Stack pointer register is not defined")
def getStackPointer(self): if CPU_STACK_POINTER: return self.getreg(CPU_STACK_POINTER) else: raise ProcessError(self, "Stack pointer register is not defined")
def getInstrPointer(self): if CPU_INSTR_POINTER: return self.getreg(CPU_INSTR_POINTER) else: raise ProcessError(self, "Instruction pointer register is not defined")
def setInstrPointer(self, ip): if CPU_INSTR_POINTER: self.setreg(CPU_INSTR_POINTER, ip) else: raise ProcessError(self, "Instruction pointer register is not defined")
def getFramePointer(self): if CPU_FRAME_POINTER: return self.getreg(CPU_FRAME_POINTER) else: raise ProcessError(self, "Instruction pointer is not defined")
except IOError, err: message = "Unable to open %s: fallback to ptrace implementation" % filename if err.errno != EACCES: error(message) else: info(message) self.readBytes = self._readBytes return self.readBytes(address, size) try: mem = self.read_mem_file mem.seek(address) return mem.read(size) except (IOError, ValueError), err: raise ProcessError( self, "readBytes(%s, %s) error: %s" % (formatAddress(address), size, err)) else: readBytes = _readBytes def getsiginfo(self): if not HAS_PTRACE_SIGINFO: self.notImplementedError() return ptrace_getsiginfo(self.pid) def writeBytes(self, address, bytes): if HAS_PTRACE_IO: size = len(bytes) bytes = create_string_buffer(bytes) io_desc = ptrace_io_desc(piod_op=PIOD_WRITE_D, piod_offs=address,
Return a list of MemoryMapping objects, or empty list if it's not possible to read the mappings. May raise a ProcessError. """ maps = [] if not HAS_PROC: return maps try: mapsfile = openProc("%s/maps" % process.pid) except ProcError, err: raise ProcessError(process, "Unable to read process maps: %s" % err) try: for line in mapsfile: line = line.rstrip() match = PROC_MAP_REGEX.match(line) if not match: raise ProcessError(process, "Unable to parse memoy mapping: %r" % line) map = MemoryMapping(process, int(match.group(1), 16), int(match.group(2), 16), match.group(3), int(match.group(4), 16), int(match.group(5), 16), int(match.group(6), 16), int(match.group(7)), match.group(8)) maps.append(map) finally: mapsfile.close() return maps