def signalClient(self, norev=False): start_eip = idaversion.get_reg_value(self.PC) #print('signalClient eip was at 0x%x, then after rev 1 0x%x call setAndDisable string is %s' % (start_eip, eip, simicsString)) if norev: idaapi.step_into() idaversion.wait_for_next_event(idc.WFNE_SUSP, -1) simicsString = gdbProt.Evalx('SendGDBMonitor("@cgc.printRegJson()");') try: regs = json.loads(simicsString) except: print('failed to get regs from %s' % simicsString) return for reg in regs: r = str(reg.upper()) if r == 'EFLAGS': r = 'EFL' elif r == 'CPSR': r = 'PSR' #print('set %s to 0x%x' % (r, regs[reg])) idaversion.set_reg_value(regs[reg], r) idaversion.refresh_debugger_memory() new_eip = idaversion.get_reg_value(self.PC) #print('signalClient back from cont new_eip is 0x%x' % new_eip) if new_eip >= self.kernel_base: print('in kernel, run to user') self.updateStackTrace()
def registerMath(self): retval = None if regFu.isHighlightedEffective(): retval = regFu.getOffset() else: #regs =['eax', 'ebx', 'ecx', 'edx', 'esi', 'edi', 'ebp'] highlighted = idaversion.getHighlight() retval = None if highlighted is not None: print 'highlighted is %s' % highlighted if self.isReg(highlighted): retval = idaversion.get_reg_value(highlighted) else: try: retval = int(highlighted, 16) except: pass if retval is None: ''' TBD this is broken, manually manage register list? ''' for reg in self.reg_list: if highlighted.startswith(reg): rest = highlighted[len(reg):] value = None try: value = int(rest[1:]) except: pass if value is not None: if rest.startswith('+'): regvalue = idaversion.get_reg_value(reg) retval = regvalue + value elif rest.startswith('-'): regvalue = idaversion.get_reg_value(reg) retval = regvalue - value return retval
def revBlock(self): cur_addr = idaversion.get_reg_value(self.PC) f = idaapi.get_func(cur_addr) if f is None: print('Ida analysis sees no function, cannot perform this function') return fc = idaapi.FlowChart(f) block_start = None prev_addr = None prev_block = None for block in fc: block_start = block.startEA #print('block_start 0x%x, cur_addr is 0x%x' % (block_start, cur_addr)) if block_start > cur_addr: break prev_addr = block_start prev_block = block if prev_addr == cur_addr: self.doRevStepInto() elif prev_addr is not None: next_addr = idc.NextHead(prev_addr) if next_addr == cur_addr: ''' reverse two to get there? ''' print('revBlock rev two?') self.doRevStepInto() self.doRevStepInto() else: print('revBlock rev to 0x%x' % prev_addr) self.doRevToAddr(prev_addr, extra_back=0) else: print('must have been top, uncall') self.doRevFinish()
def XXXXXXXXXXXXXXXsignalClient(self, norev=False): start_eip = idaversion.get_reg_value(self.PC) if not norev: simicsString = gdbProt.Evalx('SendGDBMonitor("@cgc.rev1()");') eip = gdbProt.getEIPWhenStopped() if eip is None or not (type(eip) is int or type(eip) is long): print('signalClient got wrong stuff? %s from getEIP' % str(eip)) return #print('signalClient eip was at 0x%x, then after rev 1 0x%x call setAndDisable string is %s' % (start_eip, eip, simicsString)) idaapi.step_into() idaversion.wait_for_next_event(idc.WFNE_SUSP, -1) new_eip = idaversion.get_reg_value(self.PC) #print('signalClient back from cont new_eip is 0x%x' % new_eip) if new_eip >= self.kernel_base: print('in kernel, run to user') self.updateStackTrace()
def doReverse(self, extra_back=None): print 'in doReverse' curAddr = idaversion.get_reg_value(self.PC) #goNowhere() #print('doReverse, back from goNowhere curAddr is %x' % curAddr) isBpt = idc.CheckBpt(curAddr) # if currently at a breakpoint, we need to back an instruction to so we don't break # here if isBpt > 0: print 'curAddr is %x, it is a breakpoint, do a rev step over' % curAddr addr = self.doRevStepOver() if addr is None: return None print 'in doReverse, did RevStepOver got addr of %x' % addr isBpt = idc.CheckBpt(addr) if isBpt > 0: # back up onto a breakpoint, we are done print('doReverse backed to breakpoint, we are done') return addr #print 'do reverse' param = '' if extra_back is not None: param = extra_back command = '@cgc.doReverse(%s)' % param simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) addr = None if self.checkNoRev(simicsString): addr = gdbProt.getEIPWhenStopped() self.signalClient() return addr
def doStepInto(self): #print('in doInto') idaapi.step_into() idaversion.wait_for_next_event(idc.WFNE_SUSP, -1) cur_addr = idaversion.get_reg_value(self.PC) if cur_addr > self.kernel_base: self.runToUserSpace()
def trackRegister(self): highlighted = idaversion.getHighlight() if highlighted is None or not self.isReg(highlighted): print('%s not in reg list' % highlighted) print('%s' % str(self.reg_list)) return c=idaapi.Choose([], "back track to source of selected register", 1) c.width=50 c.list = self.reg_list chose = c.choose() if chose == 0: print('user canceled') return else: highlighted = self.reg_list[chose-1] print 'backtrack to source of to %s...' % highlighted command = "@cgc.revTaintReg('%s')" % highlighted simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) print('trackRegister got simicsString %s' % simicsString) eip = None if self.checkNoRev(simicsString): eip = gdbProt.getEIPWhenStopped() self.signalClient() else: return curAddr = idaversion.get_reg_value(self.PC) print('Current instruction (0x%x) is as far back as we can trace reg %s' % (curAddr, highlighted)) self.showSimicsMessage() bookmark_list = self.bookmark_view.updateBookmarkView() return eip
def wroteToRegister(self): highlighted = idaversion.getHighlight() ''' if highlighted is None or highlighted not in self.reg_list: print('%s not in reg list' % highlighted) c=idaapi.Choose([], "Run backward until selected register modified", 1) c.width=50 c.list = self.reg_list chose = c.choose() if chose == 0: print('user canceled') return else: highlighted = self.reg_list[chose-1] ''' print 'Looking for a write to %s...' % highlighted command = "@cgc.revToModReg('%s')" % highlighted simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) eip = None if self.checkNoRev(simicsString): eip = gdbProt.getEIPWhenStopped() self.signalClient() else: return curAddr = idaversion.get_reg_value(self.PC) print('Current instruction (0x%x) wrote to reg %s' % (curAddr, highlighted)) return eip
def doStepOver(self): #print('in doStepOver') idaapi.step_over() #print('back from step over') idaversion.wait_for_next_event(idc.WFNE_SUSP, -1) #print('back getDebuggerEvent') cur_addr = idaversion.get_reg_value(self.PC) #print('cur_addr is 0x%x' % cur_addr) if cur_addr > self.kernel_base: print('run to user space') self.runToUserSpace()
def doRevToCursor(self): cursor = idaversion.get_screen_ea() curAddr = idaversion.get_reg_value(self.PC) if cursor == curAddr: print 'attempt to go back to where you are ignored' return #doRevToAddr(cursor) command = '@cgc.revToAddr(0x%x, extra_back=%d)' % (cursor, 0) simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) #print('simicsString <%s>' % simicsString) if self.checkNoRev(simicsString): eip = gdbProt.getEIPWhenStopped() self.signalClient()
def doRevFinish(self): #print 'doRevFinish' #doRevCommand('uncall-function') cur_addr = idaversion.get_reg_value(self.PC) f = idc.GetFunctionAttr(cur_addr, idc.FUNCATTR_START) if f != idaapi.BADADDR: print('doRevFinish got function start at 0x%x, go there, and further back 1' % f) self.doRevToAddr(f, extra_back=1) else: print('use monitor uncall function') simicsString = gdbProt.Evalx('SendGDBMonitor("@cgc.uncall()");') if self.checkNoRev(simicsString): eip = gdbProt.getEIPWhenStopped() self.signalClient()
def getOffset(): ''' Assuming an offset, e.g., "var_11" is highlighted, and assuming bp is proper, get the calculated address. ''' retval = None ip = idaversion.get_screen_ea() print('ip is 0x%x' % ip) highlighted = idaversion.getHighlight() print('highlighted is %s' % highlighted) ov0 = idc.print_operand(ip, 0) ov1 = idc.print_operand(ip, 1) print('op0 %s op1 %s' % (ov0, ov1)) if highlighted in ov0: index = 0 want = ov0 else: index = 1 want = ov1 ''' Convert to numberic from symbol ''' idc.op_seg(ip, index) if '[' in want and '+' in want or '-' in want: op = idc.print_operand(ip, index) print('op is %s' % op) val = op.split('[', 1)[1].split(']')[0] print('val %s' % val) if '+' in val: reg, value = val.split('+') else: reg, value = val.split('-') reg_val = idaversion.get_reg_value(reg) try: value = value.strip('h') value = int(value, 16) except: print('unable to parse int from %s' % value) idc.op_stkvar(ip, 0) return retval if '+' in val: retval = reg_val + value else: retval = reg_val - value print('effective addr is 0x%x' % retval) ''' Convert back to symbol, e.g., var_11''' idc.op_stkvar(ip, index) return retval
def trackAddress(self, target_addr): disabledSet = bpUtils.disableAllBpts(None) command = '@cgc.revTaintAddr(0x%x)' % target_addr simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) if self.checkNoRev(simicsString): eip = gdbProt.getEIPWhenStopped() self.signalClient() else: return bpUtils.enableBpts(disabledSet) if eip >= self.kernel_base: print('previous is as far back as we can trace content of address 0x%x' % target_addr) else: curAddr = idaversion.get_reg_value(self.PC) print('Current instruction (0x%x) is as far back as we can trace 0x%x' % (curAddr, target_addr))
def doRevStepOver(self): #print 'in doRevStepOver' curAddr = idaversion.get_reg_value(self.PC) prev_eip = idaversion.prev_head(curAddr) eip = None if prev_eip == idaapi.BADADDR: prev_eip = None simicsString = gdbProt.Evalx('SendGDBMonitor("@cgc.reverseToCallInstruction(False)");') else: #print('cur is 0x%x prev is 0x%x' % (curAddr, prev_eip)) simicsString = gdbProt.Evalx('SendGDBMonitor("@cgc.reverseToCallInstruction(False, prev=0x%x)");' % prev_eip) if self.checkNoRev(simicsString): eip = gdbProt.getEIPWhenStopped() self.signalClient() return eip
def satisfyCondition(self): cursor = idaversion.get_screen_ea() print('Satisfy condition at instruction 0x%x' % cursor) command = "@cgc.satisfyCondition(0x%x)" % cursor simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) print('satisfyCondition got simicsString %s' % simicsString) eip = None if self.checkNoRev(simicsString): eip = gdbProt.getEIPWhenStopped() self.signalClient() else: return curAddr = idaversion.get_reg_value(self.PC) self.showSimicsMessage() bookmark_list = self.bookmark_view.updateBookmarkView() return eip
def wroteToAddress(self, target_addr): disabledSet = bpUtils.disableAllBpts(None) command = '@cgc.stopAtKernelWrite(0x%x)' % target_addr simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) if self.checkNoRev(simicsString): eip = gdbProt.getEIPWhenStopped() self.signalClient() else: return bpUtils.enableBpts(disabledSet) if eip >= self.kernel_base: print('previous syscall wrote to address 0x%x' % target_addr) else: curAddr = idaversion.get_reg_value(self.PC) #print('Current instruction (0x%x) wrote to 0x%x' % (curAddr, target_addr)) print('Previous instruction wrote to 0x%x' % (target_addr))
def askSetBookmark(self): print('askSetBookmark') addr = idaversion.get_reg_value(self.isim.PC) instruct = idc.GetDisasm(addr) if ';' in instruct: instruct, dumb = instruct.rsplit(';', 1) #print('instruct is %s' % instruct) instruct = instruct.strip() #print('eip %x instruct: %s' % (addr, instruct)) default = '0x%x: %s' % (addr, instruct) mark = idaversion.ask_str(default, 'Name of new bookmark:') print('got mark of %s' % mark) if mark != 0 and mark != 'None': self.setBookmark(mark) print('do update of bookmark, go mark of %s' % mark) self.updateBookmarkView()
def runToSyscall(self): value = idaversion.ask_long(0, "Syscall number?") print('run to syscall of %d' % value) if value == 0: simicsString = gdbProt.Evalx('SendGDBMonitor("@cgc.runToSyscall()");') else: simicsString = gdbProt.Evalx('SendGDBMonitor("@cgc.runToSyscall(%s)");' % value) eip = gdbProt.getEIPWhenStopped(kernel_ok=True) #print('runtoSyscall, stopped at eip 0x%x, now run to user space.' % eip) self.showSimicsMessage() simicsString = gdbProt.Evalx('SendGDBMonitor("@cgc.runToUserSpace()");') eip = gdbProt.getEIPWhenStopped() #print('runtoSyscall, stopped at eip 0x%x, then stepwait.' % eip) #gdbProt.stepWait() self.signalClient(norev=True) eax = idaversion.get_reg_value("EAX") print('Syscall result: %d' % int(eax))
def wroteToRegister(self): highlighted = idaversion.getHighlight() if highlighted is None or highlighted not in self.reg_list: print('%s not in reg list' % highlighted) highlighted = idaversion.ask_str('Wrote to register:', 'Which register?') print 'Looking for a write to %s...' % highlighted command = "@cgc.revToModReg('%s')" % highlighted simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) eip = None if self.checkNoRev(simicsString): eip = gdbProt.getEIPWhenStopped() self.signalClient() else: return curAddr = idaversion.get_reg_value(self.PC) print('Current instruction (0x%x) wrote to reg %s' % (curAddr, highlighted)) return eip
def trackRegister(self): highlighted = idaversion.getHighlight() if highlighted is None or not self.isReg(highlighted) or highlighted not in self.reg_list: print('%s not in reg list' % highlighted) print('%s' % str(self.reg_list)) highlighted = idaversion.ask_str('Track register:', 'Which register?') print 'backtrack to source of to %s...' % highlighted command = "@cgc.revTaintReg('%s')" % highlighted simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) print('trackRegister got simicsString %s' % simicsString) eip = None if self.checkNoRev(simicsString): eip = gdbProt.getEIPWhenStopped() self.signalClient() else: return curAddr = idaversion.get_reg_value(self.PC) print('Current instruction (0x%x) is as far back as we can trace reg %s' % (curAddr, highlighted)) self.showSimicsMessage() bookmark_list = self.bookmark_view.updateBookmarkView() return eip
def getCPL(): cs = idaversion.get_reg_value("CS") return cs & 3
def wroteToSP(self): sp = idaversion.get_reg_value(self.SP) print 'Running backwards to previous write to ESP:0x%x' % sp self.wroteToAddress(sp)
def getUIAddress(self, prompt): value = self.registerMath() if value is None: value = idaversion.get_reg_value(self.SP) target_addr = idaversion.ask_addr(value, prompt) return target_addr