def notify(self, event, trace): if self.impapi != None: # cached return self.impapi = viv_impapi.getImportApi(trace.getMeta('Platform'), trace.getMeta('Architecture')) cc = self.impapi.getImpApiCallConv(self.vte) emu = vtrace.getEmu(trace) self.cc = emu.getCallingConvention(cc) self.argc = len(self.impapi.getImpApiArgs(self.vte))
def notify(self, event, trace): if self.impapi is not None: # cached return self.impapi = viv_impapi.getImportApi(trace.getMeta('Platform'), trace.getMeta('Architecture')) cc = self.impapi.getImpApiCallConv(self.vte) emu = vtrace.getEmu(trace) self.cc = emu.getCallingConvention(cc) self.argc = len(self.impapi.getImpApiArgs(self.vte))
def render(self, mcanv, va): trace = mcanv.mem if va != trace.getStackCounter(): return DerefRenderer.render(self, mcanv, va) pc = trace.getProgramCounter() sym, is_thunk = trace.getSymByAddrThunkAware(pc) if sym is None: return DerefRenderer.render(self, mcanv, va) # TODO: this code also exists in win32stealth and in hookbreakpoint # we should put this somewhere common platform = trace.getMeta('Platform') arch = trace.getMeta('Architecture') impapi = viv_impapi.getImportApi(platform, arch) cc_name = impapi.getImpApiCallConv(sym) emu = vtrace.getEmu(trace) cc = emu.getCallingConvention(cc_name) args_def = impapi.getImpApiArgs(sym) if args_def is None: # sym did not exist in impapi :( logger.warning('sym but no impapi match: {}'.format(sym)) return DerefRenderer.render(self, mcanv, va) argc = len(args_def) curop = trace.parseOpcode(trace.getProgramCounter()) # use the calling convention to retrieve the args args = None if curop.isCall() or is_thunk: args = cc.getPreCallArgs(trace, argc) else: args = cc.getCallArgs(trace, argc) # since we are 'normalizing' the calls by visualizing all calling # conventions in a stdcall fashion, some args (like the ones in # registers don't have a stack va. mcanv.addText('%s :\n' % sym) fmt = ' arg%%d (%%s) 0x%%0%dx %%s\n' % (trace.getPointerSize() * 2, ) for index, arg in enumerate(args): argtype = args_def[index][0] argva = arg if trace.isValidPointer(arg): argva = trace.readMemoryFormat(arg, 'P')[0] smc = e_canvas.StringMemoryCanvas(trace) e_canvas_rend.AutoBytesRenderer(maxrend=64).render(smc, argva) desc = str(smc) mcanv.addText(fmt % (index, argtype, arg, desc)) mcanv.addText('-' * 5) mcanv.addText('\n') return DerefRenderer.render(self, mcanv, va)
def render(self, mcanv, va): trace = mcanv.mem if va != trace.getStackCounter(): return DerefRenderer.render(self, mcanv, va) pc = trace.getProgramCounter() sym, is_thunk = trace.getSymByAddrThunkAware(pc) if sym == None: return DerefRenderer.render(self, mcanv, va) # TODO: this code also exists in win32stealth and in hookbreakpoint # we should put this somewhere common platform = trace.getMeta('Platform') arch = trace.getMeta('Architecture') impapi = viv_impapi.getImportApi(platform, arch) cc_name = impapi.getImpApiCallConv(sym) emu = vtrace.getEmu(trace) cc = emu.getCallingConvention(cc_name) args_def = impapi.getImpApiArgs(sym) if args_def == None: # sym did not exist in impapi :( print(('sym but no impapi match: {}'.format(sym))) return DerefRenderer.render(self, mcanv, va) argc = len(args_def) curop = trace.parseOpcode(trace.getProgramCounter()) # use the calling convention to retrieve the args args = None if curop.isCall() or is_thunk: args = cc.getPreCallArgs(trace, argc) else: args = cc.getCallArgs(trace, argc) # since we are 'normalizing' the calls by visualizing all calling # conventions in a stdcall fashion, some args (like the ones in # registers don't have a stack va. mcanv.addText('%s :\n' % sym) fmt = ' arg%%d (%%s) 0x%%0%dx %%s\n' % (trace.getPointerSize()*2,) for index, arg in enumerate(args): argtype = args_def[index][0] argva = arg if trace.isValidPointer(arg): argva = trace.readMemoryFormat(arg, 'P')[0] smc = e_canvas.StringMemoryCanvas(trace) e_canvas_rend.AutoBytesRenderer(maxrend=64).render(smc, argva) desc = str(smc) mcanv.addText(fmt % (index, argtype, arg, desc)) mcanv.addText('-' * 5) mcanv.addText('\n') return DerefRenderer.render(self, mcanv, va)
def _getOpcodeSuffix(self, trace, va, op): pc = trace.getProgramCounter() if va != pc: return '' ovals = [] for o in op.opers: if o.isDeref(): ova = o.getOperAddr(op, trace) else: ova = o.getOperValue(op, trace) sym = None if trace.isValidPointer(ova): rova = trace.readMemoryFormat(ova, '<P')[0] sym = trace.getSymByAddr(rova) if sym is None: sym = trace.getSymByAddr(ova) if sym: ovals.append(repr(sym)) elif o.isDeref(): ovals.append('[0x%.8x]' % ova) else: ovals.append('0x%.8x' % ova) if [ branch for branch, flag in op.getBranches() if flag & envi.BR_COND ]: emu = self.emu_cache.get(self.arch, vtrace.getEmu(trace)) emu.setRegisters(trace.getRegisters()) emu.setProgramCounter(va) emu.executeOpcode(op) nextpc = emu.getProgramCounter() if va + len(op) != nextpc: ovals.append('Branch taken: 0x%08x' % nextpc) else: ovals.append('Branch not taken: 0x%08x' % nextpc) return ','.join(ovals)
def _getOpcodeSuffix(self, trace, va, op): pc = trace.getProgramCounter() if va != pc: return '' ovals = [] for o in op.opers: if o.isDeref(): ova = o.getOperAddr(op, trace) else: ova = o.getOperValue(op, trace) sym = None if trace.isValidPointer(ova): rova = trace.readMemoryFormat(ova, '<P')[0] sym = trace.getSymByAddr(rova) if sym == None: sym = trace.getSymByAddr(ova) if sym: ovals.append(repr(sym)) elif o.isDeref(): ovals.append('[0x%.8x]' % ova) else: ovals.append('0x%.8x' % ova) if [branch for branch, flag in op.getBranches() if flag & envi.BR_COND]: emu = self.emu_cache.get(self.arch, vtrace.getEmu(trace)) emu.setRegisters(trace.getRegisters()) emu.setProgramCounter(va) emu.executeOpcode(op) nextpc = emu.getProgramCounter() if va + len(op) != nextpc: ovals.append('Branch taken: 0x%08x' % nextpc) else: ovals.append('Branch not taken: 0x%08x' % nextpc) return ','.join(ovals)
def resolvedaddr(self, trace, addr): ''' When we get resolved, lookup in impapi the calling convention and other details about the function. Do not do this if we were explicitly told what to do. ''' # told explicitly what to do, don't go look anything up if self.cc != None and self.argc != None: return # TODO: move this out of here after we move impapi to a top-level # package. import vivisect.impapi as viv_impapi # this code also exists in win32stealth, we should put this somewhere # common platform = trace.getMeta('Platform') arch = trace.getMeta('Architecture') self.impapi = viv_impapi.getImportApi(platform, arch) cc = self.impapi.getImpApiCallConv(self.vte) emu = vtrace.getEmu(trace) self.cc = emu.getCallingConvention(cc) apiargs = self.impapi.getImpApiArgs(self.vte) if apiargs != None: self.argc = len(apiargs)