def grep(self, command, regex_string, a='', b=''): """ Grep regex_string in the result of command Args: - command(string) - regex_string (string) - after_context(int) (optional) - before_context(int) (optional) """ try: a = to_int(a) b = to_int(b) except: return self._error_args() result = pykd.dbgCommand(command) lines = result.splitlines() for idx,line in enumerate(lines): if regex_string in line: print("="*50) if a: print('\n'.join(lines[idx-a:idx])) wprint(lines[idx]+"\n", "lightred") if b: print('\n'.join(lines[idx+1:idx+b+1]))
def telescope(self, address, count=10): """ Display memory content at an address with smart dereferences Usage: MYNAME [linecount] (analyze at current $SP) MYNAME address [linecount] """ step = self._target()['addr_size'] if not self.is_address(address): # cannot determine address wprint("Invalid address: 0x%x"%address, "lightred", "black", 1) return result = [] for i in range(count): value = address + i*step if self.is_address(value): result += [self.examine_mem_reference(value)] else: result += [None] idx = 0 text = "" for chain in result: text += "%04d| " % (idx) text += format_reference_chain(chain) text += "\n" idx += step pager(text) return
def context_stack(self,count=10): wprint("[%s]" % "stack".center(200, "-"),"lightblue","black",1) text = "" nowsp = self.sp()[1] if self.is_address(nowsp): self.telescope(nowsp, count) else: wprint("Invalid $SP address: 0x%x"%nowsp, "lightred", "black", 1) return
def test(self, tname1="RedBoy", tname2="KeGua"): """ Test for command and args. Args: - tname1(string): test name 1 - tname2(string): test name 2 """ wprint("Mutepig say hello to %s and %s!" % (tname1, tname2), "lightred") print("")
def help(self, command=None): """ Get the help of command. """ if command: print(getattr(self, command).__doc__) else: print("Name".ljust(16)+"Description") print(("-"*10).ljust(16)+"-"*10) for cmd in self.commands: if cmd not in ["run"]: wprint(cmd.ljust(16), "lightred") print(getattr(self, cmd).__doc__.strip().splitlines()[0])
def cdbinit(self, opt='', arg=''): """ add/edit/delete command in cdbinit. Args: - option(char): l(list), a(add), e(enable), d(disable), c(delete) - command(string)/linenumber(int): add command/enable or disable or delete command in the number of line """ if not opt or opt=='l': content = self._get_init() for idx,line in enumerate(content): if line.startswith('#'): wprint("%d [d]%s"%(idx, line.strip()[1:]), "lightred") else: wprint("%d [e]%s"%(idx, line.strip()), "green") print("") elif opt == 'a' and arg: f = self._open_init('a+') try: last = f.readlines()[-1] if not last.endswith("\n"): f.write("\n") except: pass f.write(arg + '\n') f.close() elif opt in ['e','d','c'] and arg: content = self._get_init() f = self._open_init('w') if arg!='*': try: linenumber = int(arg) except: return self._error_args() result = "" for idx,line in enumerate(content): if arg=='*' or idx == linenumber: if opt == 'e' and line.startswith('#'): result += line[1:] elif opt == 'd' and not line.startswith('#'): result += '#'+line elif opt == 'c': continue else: result += line else: result += line f.write(result) f.close()
def context_register(self,target_id=0): wprint("[%s]" % "registers".center(200, "-"),"lightblue","black",1) #text = "" def get_reg_text(r, v): text = green("%s" % r.upper().ljust(3)) + ": " chain = self.examine_mem_reference(v) text += format_reference_chain(chain) text += "\n" return text regs = self.registers() bits = self._target()['bits'] text = '' for r in self.REGISTERS[bits]: if r in regs: text += (get_reg_text(r, regs[r])) cprint(text) return
def watch(self): """ Show the memory by watch_command. """ self.watch_command = get_alias("watch_command") if watch_command: wprint("[%s]" % "memory".center(200, "-"),"lightblue") print("") if 'last_watch' not in dir(self): self.last_watch = '' (dc, addr, num) = watch_command.strip().split() if dc not in ['db','dd','dq','dp','dw']: error_msg("%s is not supported!"%dc) return [] now_watch = self.dumpmem(to_int(addr), int(num), dc) self.watch_show(to_int(addr), now_watch, self.last_watch, dc[1]) self.last_watch = now_watch
def context_code(self, pc='', count = 14): """ Display nearby disassembly at $PC of current execution context Usage: MYNAME [linecount] """ if not pc: pc = self.pc()[1] if self.is_address(pc): (func,inst) = self.get_disasm(pc) else: (func,inst) = (None, None) wprint("[%s]" % "disassemble".center(200, "-"),"lightblue","black",1) if inst: # valid $PC text = [] opcode = inst.split("\t")[-1].split()[0].strip() # stopped at function call if "call" in opcode: text += self.disassemble_around(pc, count) cprint(format_disasm_code(text, pc)) self.dumpargs() # stopped at jump elif "j" in opcode: jumpto = self.testjump(inst) if jumpto: # JUMP is taken text += self.disassemble_around(pc, count, 1) for i,k in enumerate(text): if k[0] == pc: break cprint(format_disasm_code(text[:i+1], pc)) jtext = self.disassemble_around(jumpto, count-1, 0, 0) wprint("===> jump to\n","red") if not jtext: wprint(" Cannot evaluate jump destination\n","red") else: cprint(format_disasm_code(jtext, jumpto)) else: # JUMP is NOT taken text += self.disassemble_around(pc, count, -1) cprint(format_disasm_code(text, pc)) # stopped at other instructions else: text += self.disassemble_around(pc, count) cprint(format_disasm_code(text, pc)) else: # invalid $PC wprint("Invalid $PC address: 0x%x" % pc, "red", "black", 1) return
def logo(self): logo_color = ['lightmagenta','lightblue','lightred','green','yellow'] auth_color = ['darkgray','brown','blue','cyan','red'] try: wprint(logos[random.randint(0, len(logos) - 1)].decode("base64"), logo_color[random.randint(0, len(logo_color) - 1)]) wprint(('mutepig-%s'%VERSION).rjust(random.randint(10, len(logos) + 10)), auth_color[random.randint(0, len(auth_color) - 1)]) print('') except: wprint(('CDB-PIG mutepig-%s'%VERSION).rjust(random.randint(10, 50)), 'red') print('')
def watch_show(self, base_addr, now, last='', c='', count=0x8): line = 0 n = 0 if not c or c =='p': step = self._target()['addr_size']<<1 else: step = 2<<['b','w','d','q'].index(c) for idx,n in enumerate(now): if idx%count == 0 : print("") wprint(to_hex(base_addr+line*count)+" ","cyan") if idx<len(last) and last[idx]!=n: wprint(just_hex(n, step), "lightred") else: wprint(just_hex(n, step)) wprint(" ") line+=1 print("")
def context(self,target_id=0): wprint("[%s]" % "CDB-PIG".center(200, "-"),"lightred","black",1) self.context_register() self.context_code() self.context_stack()
def search(self, aim, length, search, is_re=False): """ Search for all instances of a pattern in memory from start to end Args: - address(hex)/register(string): start address - length(int): search length - search(string): hexstring(start with '0x') or string or python regex pattern - re(int): use regex pattern or not """ result = [] start = self._get_aim(aim) length = to_int(length) end = start + length debugger = DebuggerAdaptor() mem = [] for i in xrange(start, end, 0x10000): if i > end: i = end mem += debugger.dumpmem(i, min(0x10000, end-i), 'db') mem_str = ''.join([chr(i) for i in mem]) print("Search from %x to %x" % (start, end)) # unicode search string usearch = '' # hex search string hsearch = '' if not mem: return result if isinstance(search, six.string_types) and search.startswith("0x"): # hex number search = search[2:] if len(search) %2 != 0: search = "0" + search search = search.decode('hex') hsearch = search[::-1] elif not is_re: usearch = ''.join([(i+'\x00') for i in search]) # Convert search to bytes if is not already if not isinstance(search, bytes): search = search.encode('utf-8') if not is_re: search = re.escape(search) try: p = re.compile(search) except: search = re.escape(search) if usearch: search += "|" + usearch if hsearch: search += "|" + hsearch p = re.compile(search) found = list(p.finditer(mem_str)) for m in found: index = 1 if m.start() == m.end() and m.lastindex: index = m.lastindex+1 for i in range(0,index): if m.start(i) != m.end(i): result += [(start + m.start(i), ''.join(["%02x"%i for i in mem[m.start(i):m.end(i)]]))] if not result: error_msg("Nothing Found!") return for i in result: (addr, hex) = i wprint(" %s "%to_hex(addr), "cyan") str = hex.decode("hex") if is_printable(str): print("%s(\"%s\")" % (hex, str)) else: print(hex)
def success_msg(text): wprint("[SUCCESS] %s" % text, "green") print("")
def error_msg(text): wprint("[ERROR] %s" % text, "lightred") print("")