def addProcess(self, pid, is_attached, parent=None, is_thread=False): """ Add a new process using its identifier. Use is_attached=False to attach an existing (running) process, and is_attached=True to trace a new (stopped) process. """ if pid in self.dict: raise KeyError("The process %s is already registered!" % pid) process = PtraceProcess(self, pid, is_attached, parent=parent, is_thread=is_thread) info("Attach %s to debugger" % process) self.dict[pid] = process self.list.append(process) try: process.waitSignals(SIGTRAP, SIGSTOP) except KeyboardInterrupt: error("User interrupt! Force the process %s attach " "(don't wait for signals)." % pid) except ProcessSignal as event: event.display() except: # noqa: E722 process.is_attached = False process.detach() raise if HAS_PTRACE_EVENTS and self.options: process.setoptions(self.options) return process
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 detach(self): if not self.is_attached: return self.is_attached = False if self.running: info("Detach %s" % self) ptrace_detach(self.pid) self.debugger.deleteProcess(process=self)
def analyseurl(urls): """ 功能:分析urls,返回列表格式的字典 字典格式:{'name':names,'urls':url} 这里将符合要求的页面信息插入数据库,还包括日志信息 还包括 key的判断???? """ returns = [] print urls html = urllib2.urlopen(urls, timeout=50) try: conn = sqlite3.connect(options.dbfile) cor = conn.cursor() cor.execute( 'create table if not exists keyofhtml( id integer primary key,urls text,key text,htmls text)' ) data = html.read() rr = re.compile(r"""content\=["|']text\/html\;charset\=(\w*?)["|']""") m = rr.search(data) if m: code = m.group(1) if code: data = data.decode(code) rekey = re.compile(keyinsys) good = rekey.search(data) if good: data = data.replace("'", '"') #纠结的单引号怎么处理? sqls = "insert into keyofhtml(urls,key,htmls) values('%s','%s','%s')" cor.execute(sqls % (urls, keyinsys, data)) conn.commit() conn.close() logging2.debug('reading ' + urls) logging2.info('what should i write here') logging2.warning('a warning here') logging2.error('a error test here') logging2.critical('what is a critical??') #print 'reading' except: print 'error' logging2.error('error ong reading ' + urls) soup = BeautifulSoup.BeautifulSoup(data) temp = soup.findAll('a', href=re.compile(r'http.*')) #为什么不直接用re匹配a标签 logging2.debug('analysing ' + urls) #print 'analysing' for tt in temp: hrefs = tt['href'] #have? if hrefs.startswith('http'): if tt.string: #span????? returns.append({'name': tt.string, 'urls': hrefs}) else: returns.append({'name': 'NoName', 'urls': hrefs}) else: continue return returns
def callFunction(self, funcname, *args, tillResult=False): """ Redirect control flow to call the specified function with given arguments. Registers will be restored as soon as function returns. If you dont see a result immediately, continue till you have stepped through all breakpoints/syscalls Does nothing if the process just entered syscall If you want to do something right after this syscall, singlestep over it. If its a read(stdin) syscall, you need to "trace write" or disable auto-continue for write in Constants.py use: call libc:memset $rbp 0x41 0x10 """ """How does this work: call mmap to map a page where we can inject code. the injected code will call the specified function. After the specified function is called, it runs into an interrupt. The "continue" logic will check for each received trap if we have reached this certain interrupt. Once that is the case, _afterCallFunction will be called""" func_ad = self.programinfo.getAddrOf(funcname) if func_ad is None: return "function %s not found" % funcname proc = self.ptraceProcess if proc.syscall_state.next_event == "exit": return "about to call syscall, returning" if self.inserted_function_data: return "already in an inserted function, returning" oldregs = proc.getregs() inject_at = self.get_own_segment().functioncall argregs = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"] # set new args (depends on calling convention) if len(args) > len(argregs): raise ValueError("too many arguments supplied" ) # TODO add push(var) functionality for (val, reg) in zip(args, argregs): proc.setreg(reg, val) ip = proc.getInstrPointer() finish = inject_at + 3 # if ip==finish, call afterCalen(pwn.asm("call rax\nint3", arch="amd64")) llFunction debug(proc.readBytes(inject_at + 2, 1)) info("inject_at= %x" % inject_at) proc.setInstrPointer(inject_at) proc.setreg("rax", func_ad) self.inserted_function_data = (ip, finish, oldregs, funcname) res = self.cont( ) # if you want to debug the injected function, change this to cont(singlestep=True) return res if res else "none"
def attach(self, seize=False): if self.is_attached: return info("Attach process %s" % self.pid) if not seize: #add by jasper ptrace_attach(self.pid) else: self.is_seized = True ptrace_seize(self.pid) self.is_attached = True
def traceFork(self): """ Enable fork() tracing. Do nothing if it's not supported. """ if not HAS_PTRACE_EVENTS: raise DebuggerError( "Tracing fork events is not supported on this architecture or operating system" ) self.options |= PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK self.trace_fork = True info("Debugger trace forks (options=%s)" % self.options)
def quit(self): """ Quit the debugger: terminate all processes in reverse order. """ info("Quit debugger") # Terminate processes in reverse order # to kill children before parents processes = list(self.list) for process in reversed(processes): process.terminate() process.detach()
def analyseurl(urls): """ 功能:分析urls,返回列表格式的字典 字典格式:{'name':names,'urls':url} 这里将符合要求的页面信息插入数据库,还包括日志信息 还包括 key的判断???? """ returns=[] print urls html = urllib2.urlopen(urls,timeout=50) try: conn = sqlite3.connect(options.dbfile) cor = conn.cursor() cor.execute('create table if not exists keyofhtml( id integer primary key,urls text,key text,htmls text)') data = html.read() rr = re.compile(r"""content\=["|']text\/html\;charset\=(\w*?)["|']""") m = rr.search(data) if m: code = m.group(1) if code: data = data.decode(code) rekey = re.compile(keyinsys) good = rekey.search(data) if good: data = data.replace("'",'"')#纠结的单引号怎么处理? sqls = "insert into keyofhtml(urls,key,htmls) values('%s','%s','%s')" cor.execute(sqls%(urls,keyinsys,data)) conn.commit() conn.close() logging2.debug('reading '+urls) logging2.info('what should i write here') logging2.warning('a warning here') logging2.error('a error test here') logging2.critical('what is a critical??') #print 'reading' except: print 'error' logging2.error('error ong reading '+urls) soup = BeautifulSoup.BeautifulSoup(data) temp = soup.findAll('a',href=re.compile(r'http.*'))#为什么不直接用re匹配a标签 logging2.debug('analysing '+urls) #print 'analysing' for tt in temp: hrefs = tt['href']#have? if hrefs.startswith('http'): if tt.string:#span????? returns.append({'name':tt.string,'urls':hrefs}) else: returns.append({'name':'NoName','urls':hrefs}) else: continue return returns
def desinstall(self, set_ip=False): """ Remove the breakpoint from the associated process. If set_ip is True, restore the instruction pointer to the address of the breakpoint. """ if not self._installed: return self._installed = False info("Desinstall %s" % self) process = self.process() if not process: return if process.running: process.writeBytes(self.address, self.old_bytes) if set_ip: process.setInstrPointer(self.address) process.removeBreakpoint(self)
def __init__(self, process, address, size=None): self._installed = False self.process = ref(process) self.address = address if CPU_POWERPC: size = CPU_WORD_SIZE elif size is None: size = 1 self.size = size # Store instruction bytes info("Install %s" % self) self.old_bytes = process.readBytes(address, size) if CPU_POWERPC: # Replace instruction with "TRAP" new_bytes = word2bytes(0x0cc00000) else: # Replace instruction with "INT 3" new_bytes = b("\xCC") * size process.writeBytes(address, new_bytes) self._installed = True
def inputLoop(self): print("type ? for help") while True: skip_hyx_update = False poll_result = self.inputPoll.poll() assert len(poll_result) > 0 if len(poll_result) == 1: name, fd, event = poll_result[0] if name == "hyx": skip_hyx_update = self.handle_hyx(event) elif name == "userinput": self.handle_stdin() elif "-out" in name: self.handle_procout(name, fd, event) elif "-err" in name: self.handle_stderr(event) else: # this happens when two sockets are written to at the "same" time for name, fd, event in poll_result: if "-out" in name: self.handle_procout(name, fd, event) break elif "-err" in name: self.handle_stderr(name) break info(poll_result) if self.hyxTalker: try: self.hyxTalker.updateHyx() except ValueError as e: warning("encountered %s when updating hyx" % e) self._switch_hyxtalker()
def setoptions(self, options): if not HAS_PTRACE_EVENTS: self.notImplementedError() info("Set %s options to %s" % (self, options)) ptrace_setoptions(self.pid, options)
good = rekey.search(data) if good: #print 'good' data = data.replace("'",'"')#纠结的单引号怎么处理? sqls = "insert into keyofhtml(urls,key,htmls) values('%s','%s','%s')" try: cor.execute(sqls%(urls,keyinsys,data)) except UnicodeDecodeError,e: #print e cor.execute(sqls%(urls,keyinsys,'decode error')) logging2.error('reading '+urls+' decode error') conn.commit() #print 'donessss' conn.close() logging2.debug('reading '+urls) logging2.info('what should i write here') logging2.warning('a warning here') logging2.error('a error test here') logging2.critical('what is a critical??') #print 'reading' #except: #print 'error' #logging2.error('error ong reading '+urls) return returns def main(): i = 0 th = threading2.ThreadPool(workQueue,resultQueue,options.number) td = threading2.MyThread2(workQueue,resultQueue,i,10)#屏幕打印进程
good = rekey.search(data) if good: #print 'good' data = data.replace("'", '"') #纠结的单引号怎么处理? sqls = "insert into keyofhtml(urls,key,htmls) values('%s','%s','%s')" try: cor.execute(sqls % (urls, keyinsys, data)) except UnicodeDecodeError, e: #print e cor.execute(sqls % (urls, keyinsys, 'decode error')) logging2.error('reading ' + urls + ' decode error') conn.commit() #print 'donessss' conn.close() logging2.debug('reading ' + urls) logging2.info('what should i write here') logging2.warning('a warning here') logging2.error('a error test here') logging2.critical('what is a critical??') return returns def main(): """ 执行入口,层次判断,任务转移. >>> main() 时间 深度 当前完成 待完成 """ i = 0
def attach(self): if self.is_attached: return info("Attach process %s" % self.pid) ptrace_attach(self.pid) self.is_attached = True