Пример #1
0
 def stoppedReverseModReg(self, my_args, one, exception, error_string):
     '''
     Invoked when the simulation stops while looking for a modified register
     '''
     cmd = 'reverse'
     self.lgr.debug('stoppedReverseModReg, entered looking for %s' % self.reg)
     dum_cpu, cur_addr, comm, pid = self.task_utils.currentProcessInfo(self.cpu)
     cpl = memUtils.getCPL(self.cpu)
     if pid == self.pid and cpl != 0:
         reg_mod_type = self.cycleRegisterMod()
         if reg_mod_type is None:
             if not self.tooFarBack():
                 ''' stepped back into kernel, rev '''
                 self.lgr.debug('stoppedReverseModReg must have entered kernel, continue to previous place where this process ran')
                 SIM_run_alone(SIM_run_command, cmd)
             else:
                 self.lgr.debug('stoppedReverseModReg must have backed to first cycle 0x%x' % self.start_cycles)
         else:
             ''' current eip modifies self.reg, done, or continue taint '''
             if not self.taint:
                 self.cleanup(self.cpu)
             else:
                 if not self.tooFarBack():
                     self.followTaint(reg_mod_type)
                 else:
                     self.lgr.debug('stoppedReverseModReg must backed to first cycle 0x%x' % self.start_cycles)
     else:
         self.lgr.error('stoppedReverseModReg wrong process or in kernel pid is %d expected %d' % (pid, self.pid))
         SIM_run_alone(SIM_run_command, cmd)
Пример #2
0
 def modeChanged(self, cpu, one, old, new):
     self.lgr.debug('returnToUserHap mode changed')
     if len(self.the_hap) == 0 or self.pid is None:
         self.lgr.error('returnToUserHap modeChanged, %s stop hap is gone, but here we are!' % (self.cell_name))
         return
     if cpu != self.cpu:
         self.lgr.debug('cpu in modeChange hap not same as starting cpu: %s %s' % (cpu.name, self.cpu.name))
     cpl = memUtils.getCPL(cpu)
     if cpl == 0:
         self.lgr.error('modeChanged says new but cpl is zero')
         return
     dumcpu, cur_addr, comm, pid = self.os_p_utils.getPinfo(cpu)
     if pid == self.pid:
         reg_num = cpu.iface.int_register.get_number("rip")
         eip = cpu.iface.int_register.read(reg_num)
         current = SIM_cycle_count(cpu)
         self.lgr.debug('returnToUserHap modeChanged %s:%d (%s) eip  %x cycle: 0x%x' % (self.cell_name, 
             pid, comm, eip, current))
         pinfo = procInfo.procInfo(self.comm, cpu, self.pid, cur_addr=cur_addr)
         self.pid = None
         SIM_run_alone(self.runAlone, pinfo)
     else:
         self.lgr.debug('returnToUserHap, modeChanged, expected pid %d got %d' % (self.pid, pid))
         status = SIM_simics_is_running()
         if not status:
             self.lgr.debug('modeChanged, simics not running, continue it')
             SIM_run_command('continue')
Пример #3
0
    def frameFromRegs(self, cpu, compat32=False):
        frame = {}
        if cpu.architecture == 'arm':
            for p in memUtils.param_map['arm']:
                frame[p] = self.mem_utils.getRegValue(
                    cpu, memUtils.param_map['arm'][p])
            cpl = memUtils.getCPL(cpu)
            if cpl == 0:
                frame['sp'] = self.mem_utils.getRegValue(cpu, 'sp_usr')
                frame['pc'] = self.mem_utils.getRegValue(cpu, 'lr')
                frame['lr'] = self.mem_utils.getRegValue(cpu, 'lr_usr')
            else:
                frame['sp'] = self.mem_utils.getRegValue(cpu, 'sp')
                frame['pc'] = self.mem_utils.getRegValue(cpu, 'pc')
                frame['lr'] = self.mem_utils.getRegValue(cpu, 'lr')
        else:
            frame['sp'] = self.mem_utils.getRegValue(cpu, 'sp')
            frame['pc'] = self.mem_utils.getRegValue(cpu, 'pc')
            if self.mem_utils.WORD_SIZE == 8 and not compat32:
                for p in memUtils.param_map['x86_64']:
                    frame[p] = self.mem_utils.getRegValue(
                        cpu, memUtils.param_map['x86_64'][p])
            else:
                for p in memUtils.param_map['x86_32']:
                    frame[p] = self.mem_utils.getRegValue(
                        cpu, memUtils.param_map['x86_32'][p])

        return frame
Пример #4
0
    def setDebugBookmark(self,
                         mark,
                         cpu=None,
                         cycles=None,
                         eip=None,
                         steps=None,
                         msg=None):
        self.lgr.debug('setDebugBookmark mark: %s' % mark)
        if cpu is None:
            dum, cpu = self.context_mgr.getDebugPid()
        cell_name = self.top.getTopComponentName(cpu)
        steps = None
        if cycles is None:
            #current = SIM_cycle_count(cpu)
            #steps = SIM_step_count(cpu)
            current = cpu.cycles
            steps = cpu.steps
        else:
            current = cycles
            steps = steps
        #SIM_run_command('set-bookmark %s' % mark)
        #if not mark.startswith('protected_memory') and not mark.startswith('_start+1'):
        if not mark.startswith('origin'):
            start_cycle = self.getCycle('origin')
            if start_cycle is None:
                self.lgr.debug('setDebugBookmark no origin')
                return
            delta = current - start_cycle
            if mark.startswith('protected_memory:') and self.hasBookmarkDelta(
                    delta):
                self.lgr.debug('setDebugBookmark protected memory, return')
                return
            mark = mark + " cycle:%x" % delta
        cpl = memUtils.getCPL(cpu)
        if cpl == 0:
            self.__kernel_marks.append(mark)
            self.lgr.debug('setDebugBookmark, cpl0 for mark %s' % mark)
        elif mark in self.__kernel_marks:
            ''' replace kernel protected memory mark with one at syscall '''
            if mark.startswith('protected_memory'):
                self.__kernel_marks.remove(mark)
                del self.__bookmarks[mark]
            else:
                self.lgr.debug(
                    'setDebugBookmark %s already exists, do nothing' % mark)
                return

        if eip is None:
            eip = self.top.getEIP(cpu)
        self.__bookmarks[mark] = self.top.cycleRecord(current, steps, eip)
        self.__mark_msg[mark] = msg
        instruct = SIM_disassemble_address(cpu, eip, 1, 0)
        if not mark.startswith('protected_memory'):
            self.lgr.debug(
                'setDebugBookmark %s cycle on %s is %x step:0x%x eip: %x %s' %
                (mark, cell_name, current, steps, eip, instruct[1]))
        self.lgr.debug('setDebugBookmark return')
        return mark
Пример #5
0
 def go(self, force=False): 
     ''' Initial method for gathering kernel parameters.  Will chain a number of functions, the first being runUntilSwapper '''
     cpl = memUtils.getCPL(self.cpu)
     if cpl != 0:
         print('not in kernel, please run forward until in kernel')
         return
     if self.cpu.architecture != 'arm':
         self.fs_base = self.cpu.ia32_fs_base
         if self.fs_base == 0 and not force:
             print('fs_base is zero, maybe just entered kernel?  consider running ahead a bit, or use gkp.go(True)')
             return
     self.runUntilSwapper()
Пример #6
0
 def stoppedReverseToCall(self, my_args, one, exception, error_string):
     '''
     Invoked when the simulation stops while looking for a previous call
     '''
     if self.stop_hap is None:
         self.lgr.error('stoppedReverseToCall invoked though hap is none')
         return
     #cmd = 'reverse-step-instruction'
     cmd = 'reverse'
     cpu, cur_addr, comm, pid = self.task_utils.currentProcessInfo(self.cpu)
     current = SIM_cycle_count(cpu)
     self.lgr.debug('stoppedReverseToCall, entered %d (%s) cycle: 0x%x' % (pid, comm, current))
     #if current < self.top.getFirstCycle():
     if current <= self.start_cycles:
         self.lgr.debug('stoppedReverseToCall found cycle 0x%x prior to first, stop here' %(current))
         self.cleanup(cpu)
     #elif pid == my_args.pid and SIM_processor_privilege_level(cpu) != 0:
     elif pid == self.pid and memUtils.getCPL(cpu) != 0:
         eip = self.top.getEIP(cpu)
         instruct = SIM_disassemble_address(cpu, eip, 1, 0)
         if self.first_back and self.isSyscall(instruct[1]):
             self.lgr.debug('stoppedReverseToCall first back is syscall at %x, we are done' % eip)
             self.cleanup(cpu)
         elif (self.first_back and not self.uncall) and (not self.isRet(instruct[1]) or self.step_into):
             self.lgr.debug('stoppedReverseToCall first back not a ret or step_into at %x, we are done' % eip)
             self.cleanup(cpu)
         elif self.isCall(instruct[1]):
             self.got_calls += 1
             if self.got_calls == self.need_calls:
                 self.lgr.debug('stoppedReverseToCall %s at %x we must be done' % (instruct[1], eip))
                 self.cleanup(cpu)
             elif eip in self.frame_ips:
                 self.lgr.debug('stoppedReverseToCall %s at %x found stack frame entry, declare we are done' % (instruct[1], eip))
                 self.cleanup(cpu)
             else:
                self.lgr.debug('stoppedReverseToCall 0x%x got call %s   got_calls %d, need %d' % (eip, instruct[1], self.got_calls, self.need_calls))
                SIM_run_alone(SIM_run_command, cmd)
         elif self.isRet(instruct[1]):
             self.need_calls += 1
             self.lgr.debug('stoppedReverseToCall 0x%x got ret %s  need: %d' % (eip, instruct[1], self.need_calls))
             if self.first_back and not self.uncall:
                 self.rmBreaks()
                 ''' TBD fix this? '''
                 for item in self.x_pages:
                     self.setBreakRange(self.cell_name, pid, item.address, item.length, cpu, comm, True)
             SIM_run_alone(SIM_run_command, cmd)
         else:
             self.lgr.debug('stoppedReverseToCall Not call or ret at %x, is %s' % (eip, instruct[1]))
             SIM_run_alone(SIM_run_command, cmd)
     else:
         self.lgr.debug('stoppedReverseInstruction in wrong pid (%d) or in kernel, try again' % pid)
         SIM_run_alone(SIM_run_command, cmd)
     self.first_back = False
Пример #7
0
 def modeChangedToUserSpace(self, dbi, cpu, old, new):
     ''' TBD what if it dies before going to user space? '''
     cur_processor, cur_addr, comm, pid = self.os_utils.currentProcessInfo(
         self.cpu)
     self.lgr.debug('chainHap in modeChangedToUserSpace pid %d' % pid)
     if self.pid == pid:
         cpl = memUtils.getCPL(cpu)
         #if new != Sim_CPU_Mode_Supervisor:
         if cpl != 0:
             print('mode changed to user for pid %d' % self.pid)
             SIM_break_simulation('should be in user space')
             SIM_hap_delete_callback_id("Core_Mode_Change",
                                        self.mode_changed_hap)
             self.mode_changed_hap = None
Пример #8
0
 def runToUser(self, cpu, cell_name, pid, reverse=False):
     self.cpu = cpu
     self.cell_name = cell_name
     self.pid = pid
     cpl = memUtils.getCPL(self.cpu)
     if cpl != 0:
         self.lgr.debug('runToUser already in user space')
         self.top.skipAndMail(1)
         return
     if reverse:
         self.lgr.debug('runToUser, go backward')
         self.revToUser()
     else:
         self.lgr.debug('runToUser, go forward')
         self.runForward()
Пример #9
0
 def __init__(self, top, cpu, cpu_list, pid, comm, callback, os_p_utils, is_monitor_running, lgr):
     self.the_hap = []
     self.callback = callback
     self.lgr = lgr
     self.cpu_list = cpu_list
     self.pid = pid
     self.cpu = cpu
     self.comm = comm
     self.top = top
     self.os_p_utils = os_p_utils
     self.is_monitor_running = is_monitor_running
     self.cell_name = self.top.getTopComponentName(cpu)
     cpl = memUtils.getCPL(cpu)
     if cpl != 0:
         self.lgr.debug('returnToUser init, but already in user space')
         return
     if pid is not None:
         self.lgr.debug('returnToUserHap %s:%d ' % (self.cell_name, pid))
         is_monitor_running.setRunning(True)
         SIM_run_alone(self.installModeHap, None)
Пример #10
0
 def modeChangedPostFixup(self, dbi, cpu, old, new):
     cur_processor, cur_addr, comm, pid = self.os_utils.currentProcessInfo(
         cpu)
     self.lgr.debug('chainHap in modeChangedPostFixup pid %d' % pid)
     if self.pid == pid:
         cpl = memUtils.getCPL(cpu)
         if cpl != 0:
             reg_num = self.cpu.iface.int_register.get_number("eip")
             eip = self.cpu.iface.int_register.read(reg_num)
             phys_block = cpu.iface.processor_info.logical_to_physical(
                 eip, Sim_Access_Read)
             if phys_block.address != 0:
                 # page is mapped, put do-debug back into chain of haps
                 self.lgr.debug('chainHap mode changed, page now mapped')
                 SIM_hap_delete_callback_id("Core_Mode_Change",
                                            self.mode_changed_hap)
                 self.cmds.append('do-debug')
                 SIM_break_simulation('chainHap page now mapped')
             else:
                 self.lgr.debug(
                     'chainHap mode changed, page STILL NOT MAPPED')
Пример #11
0
 def writeHap(self, dumb, third, forth, memory):
     if self.write_hap is None:
         return
     cpu, comm, cur_pid = self.task_utils.curProc()
     if cur_pid != self.pid:
         return
     addr = memory.logical_address
     if addr >= self.param.kernel_base:
         return
     sp = self.mem_utils.getRegValue(self.cpu, 'sp')
     ''' TBD fix, pickle stack pointer recorded in genMonitor and use it!'''
     if addr > (sp - 9000):
         return
     cpl = memUtils.getCPL(cpu)
     if cpl == 0:
         return
     size = memory.size
     #eip = self.mem_utils.getRegValue(self.cpu, 'pc')
     #self.lgr.debug('trackFunctionWrite writeHap 0x%x length %d eip: 0x%x 0x%x' % (addr, size, eip, self.cpu.cycles))
     count = self.writeMarks.dataWrite(addr, size)
     if count > 200:
         self.funExitHap(None, None, None, None)
Пример #12
0
    def stop_callback2(self, dbi, one, two, three):
        if self.__stop_hap2 is None:
            return
        SIM_hap_delete_callback_id("Core_Simulation_Stopped", self.__stop_hap2)
        self.__stop_hap2 = None
        cycles = dbi.cpu.cycles
        self.lgr.debug('debugSignal after skip to bookmark, cycles is %x' % cycles)
        new_want = cycles - 1
        if dbi.unmapped_eip:
            self.lgr.debug('stop_callback2, was unmapped, rev 1')
            SIM_run_command('pselect cpu-name = %s' % dbi.cpu.name)
            SIM_run_command('skip-to cycle = 0x%x' % new_want)
            cycles = dbi.cpu.cycles
            if cycles == new_want:
                cpl = memUtils.getCPL(dbi.cpu)
                if cpl == 0:
                    eip = self.top.getEIP(dbi.cpu)
                    self.lgr.debug('debugSignal stop_callback2, simicsError after rev, cycle is 0x%x  but eip is in kernel at %x, fail, try again' % (cycles, eip))
                    return
            else:
                self.lgr.debug('debugSignal, stop_callback2, simicsError after rev, cycle is 0x%x  expected it to be 0x%x' % (cycles, new_want))

        ida_msg = ''
        if dbi.frame is not None:
            ida_msg += 'Signal %d, thread frame from kernel:\n%s' \
                             % (dbi.event_value, self.os_utils.stringFromFrame(dbi.frame))
        if dbi.negotiate_result is not None:
            ida_msg +='\n[%s]' % dbi.negotiate_result 
        elif db.event_value is not None:
            ida_msg +='\n[Signal %d, failed negotiate]' % dbi.event_value
        dbi.context_manager.setIdaMessage(ida_msg)
        self.bookmarks.setOrigin(dbi.cpu)
        if not dbi.auto_analysis:
            dbi.context_manager.debug(dbi.cell_name, dbi.pid, dbi.comm, dbi.cpu, False, cycles)
        else:
            self.lgr.debug('debugSignal, call autoAnalysis')
            dbi.context_manager.debug(dbi.cell_name, dbi.pid, dbi.comm, dbi.cpu, False, cycles, auto_analysis=True)
            self.top.autoAnalysis(dbi.cell_name, dbi.pid, dbi.comm, dbi.cpu, False, cycles)
Пример #13
0
 def modeChanged(self, cpu, one, old, new):
     dum_cpu, cur_addr, comm, pid = self.os_utils.currentProcessInfo(
         self.cpu)
     cell_name = self.top.getTopComponentName(self.cpu)
     #cpl = SIM_processor_privilege_level(self.cpu)
     cpl = memUtils.getCPL(cpu)
     self.lgr.debug('mode_changed %s %d (%s) look for %d, cpl is %d ' %
                    (cell_name, pid, comm, self.pid, cpl))
     if pid == self.pid and cpl != 0:
         #self.top.skipAndMail(1)
         eip = self.top.getEIP()
         instruct = SIM_disassemble_address(cpu, eip, 1, 0)
         self.lgr.debug(
             'mode_changed in correct process, we are done, 0x%x %s' %
             (eip, instruct[1]))
         SIM_hap_delete_callback_id("Core_Mode_Change", self.mode_hap)
         self.mode_hap = None
         my_args = procInfo.procInfo(self.comm, self.cpu, self.pid)
         self.stop_in_user_hap = SIM_hap_add_callback(
             "Core_Simulation_Stopped", self.stoppedRanToUser, my_args)
         SIM_break_simulation('should be in user space')
     else:
         pass
Пример #14
0
 def modeChanged(self, cpu, one, old, new):
     if self.__mode_changed is None:
         return
     cell_name = self.top.getTopComponentName(cpu)
     cpu, cur_addr, comm, pid = self.os_p_utils[cell_name].getPinfo(cpu)
     #self.lgr.debug('modeChanged %d %s' % (pid, comm))
     if self.isTraced(comm, pid):
         # force comm, may not be updated in proc utils
         comm = self.i_trace
         cpl = memUtils.getCPL(cpu)
         if cpl == 0:
             cmd = '%s.stop' % self.tracer
             SIM_run_alone(SIM_run_command, cmd)
             self.lgr.debug('stopped tracing %s' % comm)
             if True:
                 eip = self.top.getEIP(cpu)
                 instruct = SIM_disassemble_address(cpu, eip, 1, 0)
                 if decode.getMn(instruct[1]) == 'jmp':
                     op1, op0 = decode.getOperands(instruct[1])
                     eip_str = '0x%x' % eip
                     self.lgr.debug(
                         'modeChanged jmp is %s eip_str is <%s> op0 is <%s>'
                         % (instruct[1], eip_str, op0))
                     if op0 == eip_str:
                         self.closeTrace(cell_name, pid)
                         self.lgr.debug(
                             'modeChanged, found ebfe, stop tracing')
                         return
         else:
             if self.tracer is None:
                 SIM_run_alone(self.createTracer, comm)
                 self.lgr.debug('created tracer for %s' % comm)
             else:
                 outfile = self.outfile[comm]
                 cmd = '%s.start file=%s' % (self.tracer, outfile)
                 SIM_run_alone(SIM_run_command, cmd)
             self.lgr.debug('start tracing %s' % comm)
Пример #15
0
    def runAlone(self, dbi):
        all_done = False
        expected = dbi.command.split('=')[1].strip()
        want_cycle = int(expected)
        simics_crap_counter = 0
        ida_msg = ''
        start_cycle = self.bookmarks.getCycle('_start+1')
        if self.top.SIMICS_BUG:
          while not all_done:
            done = False
            while not done:
                SIM_run_command('pselect cpu-name = %s' % dbi.cpu.name)
                SIM_run_command('skip-to cycle = 0x%x' % start_cycle)
                cycles = dbi.cpu.cycles
                self.lgr.debug('debugSignal, did skip to start at cycle %x, expected %x counter %d' % (cycles, start_cycle, simics_crap_counter))
                
                #SIM_run_command('skip-to bookmark = bookmark0')
                #cycles = SIM_cycle_count(dbi.cpu)
                #self.lgr.debug('debugSignal, did skip to bookmark0, cycle now %x' % cycles)
                SIM_run_command('pselect cpu-name = %s' % dbi.cpu.name)
                SIM_run_command(dbi.command)
                cycles = dbi.cpu.cycles
                if dbi.command.startswith('skip-to'):
                    eip = self.top.getEIP(dbi.cpu)
                    if want_cycle != cycles or eip != dbi.sig_eip:
                        self.lgr.error('debugSignal, simicsError expected cycle %x (0x%x) eip:0x%x, got cycles %x eip:0x%x' % (want_cycle, dbi.cycle, dbi.sig_eip, cycles, eip))
                        SIM_run_command('pselect cpu-name = %s' % dbi.cpu.name)
                        SIM_run_command('skip-to cycle = 0x%x' % start_cycle)
                        
                    else:
                        self.lgr.debug('debugSignal, went where we expected, expected cycle %x (0x%x) eip: 0x%x, got cycles %x eip:0x%x counter: %d' % (want_cycle, dbi.cycle, dbi.sig_eip, cycles, eip, simics_crap_counter))
                done = True

            if dbi.unmapped_eip:
                new_want = want_cycle - 1
                # TBD debug, do one time
                simics_crap_counter_x = 0
                while all_done is False and simics_crap_counter_x < 1:
                    self.lgr.debug('debugSignal was unmapped eip, so rev 1 so we do not end up looking at dumb eip counter: %d' % simics_crap_counter_x)
                    SIM_run_command('pselect cpu-name = %s' % dbi.cpu.name)
                    SIM_run_command('skip-to cycle = 0x%x' % start_cycle)
                    cycles = dbi.cpu.cycles
                    self.lgr.debug('debugSignal, before doing rev, did skip to start at cycle %x, expected %x counter %d' % (cycles, start_cycle, simics_crap_counter))
                    SIM_run_command('pselect cpu-name = %s' % dbi.cpu.name)
                    SIM_run_command('skip-to cycle = 0x%x' % new_want)
                    cycles = dbi.cpu.cycles
                    if cycles == new_want:
                        cpl = memUtils.getCPL(dbi.cpu)
                        if cpl != 0:
                            all_done = True
                        else:
                            eip = self.top.getEIP(dbi.cpu)
                            self.lgr.debug('debugSignal, simicsError after rev, cycle is 0x%x  but eip is in kernel at %x, fail, try again' % (cycles, eip))
                            break
                    else:
                        self.lgr.debug('debugSignal, simicsError after rev, cycle is 0x%x  expected it to be 0x%x' % (cycles, new_want))
                        break
                    simics_crap_counter_x += 1
            else:
                all_done = True  
            simics_crap_counter += 1
            self.lgr.debug('inc counter to %d' % simics_crap_counter)
            if simics_crap_counter > 9:
                all_done = True
                self.lgr.error('debugSignal, simicsError simics has lost its way, TBD tell the idaClient user to try again later...')
                ida_msg += 'Simics got lost, what follows is wrong.  Suggest you quit and try again'
        else:
         SIM_run_command('pselect cpu-name = %s' % dbi.cpu.name)
         SIM_run_command(dbi.command)
         cycles = dbi.cpu.cycles
         if dbi.unmapped_eip:
             new_want = want_cycle - 1
             SIM_run_command('pselect cpu-name = %s' % dbi.cpu.name)
             SIM_run_command('skip-to cycle = 0x%x' % new_want)
             cycles = dbi.cpu.cycles

        self.lgr.debug('debugSignal after command, cycles is %x' % cycles)
        if dbi.frame is not None:
            ida_msg += 'Signal %d, thread frame from kernel:\n%s' \
                         % (dbi.event_value, self.os_utils.stringFromFrame(dbi.frame))
        if dbi.negotiate_result is not None:
            ida_msg +='\n[%s]' % dbi.negotiate_result 
        elif dbi.event_value is not None:
            ida_msg +='\n[Signal %d, failed negotiate]' % dbi.event_value
        dbi.context_manager.setIdaMessage(ida_msg)
        self.bookmarks.setOrigin(dbi.cpu)
        if not dbi.auto_analysis:
            dbi.context_manager.debug(dbi.cell_name, dbi.pid, dbi.comm, dbi.cpu, False, cycles)
        else:
            self.lgr.debug('debugSignal, call autoAnalysis')
            dbi.context_manager.debug(dbi.cell_name, dbi.pid, dbi.comm, dbi.cpu, False, cycles, auto_analysis=True)
            self.top.autoAnalysis(dbi.cell_name, dbi.pid, dbi.comm, dbi.cpu, False, cycles)
Пример #16
0
    def cycleRegisterMod(self):
        '''
        Step backwards one cycle at a time looking for the register being modified.
        If kernel entered before the register is found, return False.
        TBD: ARM write-back operations
        '''
        retval = None
        done = False
        self.lgr.debug('cycleRegisterMod start for %s' % self.reg)
        while not done:
            #current = SIM_cycle_count(self.cpu)
            current = self.cpu.cycles
            previous = current - 1
            SIM_run_command('pselect cpu-name = %s' % self.cpu.name)
            SIM_run_command('skip-to cycle = %d' % previous)
            self.lgr.debug('cycleRegisterMod skipped to 0x%x  cycle is 0x%x' %
                           (previous, self.cpu.cycles))
            if self.tooFarBack():
                self.lgr.debug(
                    'cycleRegisterMod prev cycle 0x%x prior to first 0x%x, stop here'
                    % (previous, self.start_cycles))
                break
            cpl = memUtils.getCPL(self.cpu)
            if cpl == 0:
                self.lgr.debug('cycleRegisterMod entered kernel')
                done = True
            else:
                cur_val = self.cpu.iface.int_register.read(self.reg_num)
                #self.lgr.debug('compare %x to %x eip: %x' % (cur_val, self.reg_val, eip))
                '''
                if cur_val != self.reg_val: 
                    eip = self.top.getEIP(self.cpu)
                    self.lgr.debug('cycleRegisterMod at %x, we are done' % eip)
                    done = True
                    retval = True
                    self.is_monitor_running.setRunning(False)
                '''
                eip = self.top.getEIP(self.cpu)
                self.lgr.debug('cycleRegisterMod do disassemble for eip 0x%x' %
                               eip)
                instruct = SIM_disassemble_address(self.cpu, eip, 1, 0)
                self.lgr.debug(
                    'cycleRegisterMod disassemble for eip 0x%x is %s' %
                    (eip, str(instruct)))
                mn = self.decode.getMn(instruct[1])
                self.lgr.debug('cycleRegisterMod decode is %s' % mn)
                if self.conditionalMet(mn):
                    if self.decode.modifiesOp0(mn):
                        self.lgr.debug('get operands from %s' % instruct[1])
                        op1, op0 = self.decode.getOperands(instruct[1])
                        self.lgr.debug(
                            'cycleRegisterMod mn: %s op0: %s  op1: %s  compare <%s> to <%s>'
                            % (mn, op0, op1, op0, self.reg))
                        if self.decode.isReg(op0) and self.decode.regIsPart(
                                op0, self.reg):
                            self.lgr.debug(
                                'cycleRegisterMod at %x, we are done' % eip)
                            done = True
                            retval = RegisterModType(None,
                                                     RegisterModType.UNKNOWN)
                    elif self.cpu.architecture == 'arm':
                        if ']!' in instruct[1]:
                            ''' Look for write-back register mod '''
                            ''' for now just look for [myreg, xxx]! '''
                            if self.decode.armWriteBack(instruct[1], self.reg):
                                done = True
                                retval = RegisterModType(
                                    None, RegisterModType.UNKNOWN)
                        elif mn.startswith('ldm') and self.reg in instruct[
                                1] and '{' in instruct[1]:
                            addr = self.decode.armLDM(self.cpu, instruct[1],
                                                      self.reg)
                            if addr is not None:
                                done = True
                                retval = RegisterModType(
                                    addr, RegisterModType.ADDR)

        return retval
Пример #17
0
    def tryOneStopped(self, my_args, one, exception, error_string):
        '''
        Invoked when the simulation stops after trying to go back one
        '''
        if self.stop_hap is None:
            self.lgr.error('stoppedReverseToCall invoked though hap is none')
            return
        SIM_hap_delete_callback_id("Core_Simulation_Stopped", self.stop_hap)
        self.stop_hap = None
        #cmd = 'reverse-step-instruction'
        if self.tooFarBack():
            self.lgr.debug('At start of recording, cycle: 0x%x' %
                           self.cpu.cycles)
            print('At start of recording, cycle: 0x%x' % self.cpu.cycles)
            self.cleanup(self.cpu)
            self.top.skipAndMail()
            return
        self.lgr.debug('tryOneStopped, entered at cycle 0x%x' %
                       self.cpu.cycles)
        eip = self.top.getEIP(self.cpu)
        instruct = SIM_disassemble_address(self.cpu, eip, 1, 0)
        self.lgr.debug('tryOneStopped reversed 1, eip: %x  %s' %
                       (eip, instruct[1]))
        cpl = memUtils.getCPL(self.cpu)
        done = False
        if cpl > 0:
            self.lgr.debug('tryBackOne user space')
            if self.step_into or not self.isRet(instruct[1]):
                self.lgr.debug('tryBackOne worked ok')
                done = True
                self.cleanup(self.cpu)
                self.top.skipAndMail()
                self.context_manager.setExitBreak(self.cpu)
        elif len(self.sysenter_cycles) > 0:
            cur_cycles = self.cpu.cycles
            cur_cpu, comm, pid = self.os_utils[self.cell_name].curProc()
            self.lgr.debug('tryBackOne kernel space pid %d expected %d' %
                           (pid, my_args.pid))
            is_exit = self.isExit(instruct[1], eip)
            if pid == self.pid and is_exit:
                self.lgr.debug('tryOneStopped is sysexit, cur_cycles is 0x%x' %
                               cur_cycles)
                prev_cycles = None
                got_it = None
                page_cycles = self.sysenter_cycles
                if self.page_faults is not None:
                    self.lgr.debug(
                        'tryBackOne adding %d page faults to cycles' %
                        (len(self.page_faults.getFaultingCycles())))
                    page_cycles = page_cycles + self.page_faults.getFaultingCycles(
                    )
                for cycles in sorted(page_cycles):
                    if cycles > cur_cycles:
                        self.lgr.debug(
                            'tryOneStopped found cycle between 0x%x and 0x%x' %
                            (prev_cycles, cycles))
                        got_it = prev_cycles - 1
                        break
                    else:
                        self.lgr.debug('tryOneStopped is not cycle 0x%x' %
                                       (cycles))
                        prev_cycles = cycles

                if not got_it:
                    self.lgr.debug(
                        'tryOneStopped nothing between, assume last cycle of 0x%x'
                        % prev_cycles)
                    got_it = prev_cycles - 1
                SIM_run_alone(self.jumpCycle, got_it)
                done = True
            elif pid == self.pid and not is_exit:
                self.lgr.debug(
                    'tryOneStopped in kernel but not exit? 0x%x  %s' %
                    (eip, instruct[1]))

        if not done:
            self.lgr.debug(
                'tryOneStopped, back one did not work, starting at %x' % eip)
            self.stop_hap = SIM_hap_add_callback("Core_Simulation_Stopped",
                                                 self.stoppedReverseToCall,
                                                 my_args)
            self.lgr.debug('tryOneStopped, added stop hap')
            if self.previous_eip is not None and eip != self.previous_eip and cpl > 0:
                self.lgr.debug(
                    'tryOneStopped, prev %x not equal eip %x, assume syscall, set break on prev and rev'
                    % (self.previous_eip, eip))
                self.setOneBreak(self.previous_eip, self.cpu)
            else:
                self.uncall = False
                #for item in self.x_pages:
                #    self.setBreakRange(self.cell_name, my_args.pid, item.address, item.length, self.cpu, my_args.comm, False)
                self.pageTableBreaks(False)
                self.lgr.debug('tryOneStopped, set break range')
            SIM_run_alone(SIM_run_command, 'reverse')
            #self.lgr.debug('reverseToCall, did reverse-step-instruction')
            self.lgr.debug('tryOneStopped, did reverse')
Пример #18
0
    def thinkWeWrote(self, offset):
        #if self.stop_write_hap is None:
        #    return
        eip = self.mem_utils.getRegValue(self.cpu, 'pc')
        cycle = self.cpu.cycles
        cpl = memUtils.getCPL(self.cpu)
        instruct = SIM_disassemble_address(self.cpu, eip, 1, 0)
        orig_cycle = self.bookmarks.getFirstCycle()
        dumb, comm, pid = self.task_utils.curProc()
        self.lgr.debug(
            'in thinkWeWrote pid:%d, cycle 0x%x eip: %x  %s cpl: %d orig cycle 0x%x'
            % (pid, cycle, eip, str(instruct), cpl, orig_cycle))
        if cycle <= orig_cycle:
            range_start = self.dataWatch.findRange(self.addr)
            range_msg = ''
            if range_start is not None:
                offset = self.addr - range_start
                range_msg = ' And that is %d bytes from buffer starting at 0x%x' % (
                    offset, range_start)
            ida_msg = "Content of 0x%x was modified prior to enabling reverse execution. %s" % (
                self.addr, range_msg)
            self.lgr.debug('findKernelWrite thinkWeWrote ' + ida_msg)
            self.context_manager.setIdaMessage(ida_msg)
            SIM_run_alone(self.cleanup, False)
            self.top.skipAndMail()
            return
        elif pid == 0:
            ida_msg = "Content of 0x%x was modified in pid ZERO?" % self.addr
            self.lgr.error('findKernelWrite thinkWeWrote ' + ida_msg)
            self.context_manager.setIdaMessage(ida_msg)
            SIM_run_alone(self.cleanup, False)
            self.top.skipAndMail()
            return
        if cpl == 0:
            if self.found_kernel_write:
                self.lgr.debug(
                    'thinkWeWrote stopToCheckWriteCallback found second write?  but we deleted the breakpoint!!!! ignore this and reverse'
                )
                #SIM_run_alone(SIM_run_command, 'reverse')
                return
            ''' get return address '''
            self.found_kernel_write = True
            ''' Simics has no way to get recent memory transaction, so, go back one and set a hap on the break so we can get the memop '''
            ''' We were going to run forward anyway to get to user space ,so manage it on the fly '''
            back_one = self.cpu.cycles - 1
            if not self.rev_to_call.skipToTest(back_one):
                return
            #cmd =  'skip-to cycle=%d' % (self.cpu.cycles-1)
            #SIM_run_command(cmd)
            self.forward_hap = SIM_hap_add_callback_index(
                "Core_Breakpoint_Memop", self.hitForwardCallback, None,
                self.kernel_write_break)

            self.lgr.debug(
                'thinkWeWrote, forward_hap is %d  on write to 0x%x. Set breaks on exit to user'
                % (self.forward_hap, self.kernel_write_break))
            if self.cpu.architecture == 'arm':
                self.kernel_exit_break1 = self.context_manager.genBreakpoint(
                    self.cell, Sim_Break_Linear, Sim_Access_Execute,
                    self.param.arm_ret, 1, 0)
                self.exit_hap = self.context_manager.genHapIndex(
                    "Core_Breakpoint_Memop", self.exitHap, None,
                    self.kernel_exit_break1, 'findKernelWrite armexit')
                #self.cleanup()
            else:
                if self.param.sysexit is not None:
                    self.kernel_exit_break1 = self.context_manager.genBreakpoint(
                        self.cell, Sim_Break_Linear, Sim_Access_Execute,
                        self.param.sysexit, 1, 0)
                    self.exit_hap = self.context_manager.genHapIndex(
                        "Core_Breakpoint_Memop", self.exitHap, None,
                        self.kernel_exit_break1, 'findKernelWrite sysexit')
                if self.param.iretd is not None:
                    self.kernel_exit_break2 = self.context_manager.genBreakpoint(
                        self.cell, Sim_Break_Linear, Sim_Access_Execute,
                        self.param.iretd, 1, 0)
                    self.exit_hap2 = self.context_manager.genHapIndex(
                        "Core_Breakpoint_Memop", self.exitHap, None,
                        self.kernel_exit_break2, 'findKernelWrite iretd')
            SIM_run_alone(SIM_run_command, 'continue')

        elif self.found_kernel_write:
            self.lgr.debug(
                'thinkWeWrote, BACKTRACK pid:%d user space address 0x%x after finding kernel write to  0x%x'
                % (pid, eip, self.addr))
            if not self.checkWriteValue(eip):
                return

            value = self.mem_utils.readWord32(self.cpu, self.addr)
            eip = self.top.getEIP(self.cpu)
            if eip == self.bookmarks.getEIP('_start+1'):
                ida_message = "Content of 0x%x existed pror to _start+1, perhaps from loader." % self.addr
                bm = None
            else:
                ida_message = 'Kernel wrote 0x%x to address: 0x%x' % (
                    value, self.addr)
                self.lgr.debug('set ida msg to %s' % ida_message)
                bm = "eip:0x%x follows kernel write of value:0x%x to memory:0x%x" % (
                    eip, value, self.addr)
            if bm is not None:
                self.bookmarks.setBacktrackBookmark(bm)
            self.context_manager.setIdaMessage(ida_message)
            SIM_run_alone(self.cleanup, False)
            self.top.skipAndMail()
            #previous = SIM_cycle_count(my_args.cpu) - 1
            #SIM_run_alone(SIM_run_command, 'skip-to cycle=%d' % previous)
            #eip = self.top.getEIP()
            #msg = '0x%x' % eip
            #self.top.gdbMailbox(msg)

            self.context_manager.setExitBreaks()

        else:
            if not self.checkWriteValue(eip):
                return
            eip = self.top.getEIP(self.cpu)
            SIM_run_alone(self.cleanup, False)
            if eip == self.bookmarks.getEIP('_start+1'):
                ida_message = "Content of %s came modified prior to enabling reverse." % self.addr
                bm = "eip:0x%x content of memory:%s modified prior to enabling reverse" % (
                    eip, self.addr)
                self.bookmarks.setBacktrackBookmark(bm)
                self.context_manager.setIdaMessage(ida_message)
                SIM_run_alone(self.cleanup, False)
                self.top.skipAndMail()

            elif self.rev_to_call is None:
                # reverse two so we land on the instruction that does the write (after client steps forward 1)
                self.lgr.debug(
                    'thinkWeWrote eip is %x in user space,  stop here and reverse 2  : may break if page fault?'
                    % eip)
                self.top.skipAndMail(cycles=2)
            else:
                self.lgr.debug('thinkWeWrote, call backOneAlone')
                SIM_run_alone(self.backOneAlone, offset)
            #self.top.skipAndMail()
            #previous = SIM_cycle_count(my_args.cpu) - 1
            #SIM_run_alone(SIM_run_command, 'skip-to cycle=%d' % previous)
            #eip = self.top.getEIP()
            #msg = '0x%x' % eip
            #self.top.gdbMailbox(msg)

            self.context_manager.setExitBreaks()
Пример #19
0
    def readHap(self, index, third, forth, memory):
        ''' watched data has been read (or written) '''
        if self.cpu.cycles == self.prev_cycle:
            return
        if len(self.read_hap) == 0:
            return
        self.prev_cycle = self.cpu.cycles

        if self.back_stop is not None and not self.break_simulation and self.use_back_stop:
            self.back_stop.setFutureCycle(self.back_stop_cycles)
        if index >= len(self.read_hap):
            self.lgr.error(
                'dataWatch readHap invalid index %d, only %d read haps' %
                (index, len(self.read_hap)))
            return
        if self.read_hap[index] is None:
            return
        op_type = SIM_get_mem_op_type(memory)
        addr = memory.logical_address
        eip = self.top.getEIP(self.cpu)
        #self.lgr.debug('dataWatch readHap index %d addr 0x%x eip 0x%x' % (index, addr, eip))
        if self.show_cmp:
            self.showCmp(addr)

        if self.break_simulation:
            self.lgr.debug('readHap will break_simulation, set the stop hap')
            self.stopWatch()
            SIM_run_alone(self.setStopHap, None)
        offset = addr - self.start[index]
        cpl = memUtils.getCPL(self.cpu)
        ''' If execution outside of text segment, check for mem-something library call '''
        start, end = self.context_manager.getText()
        call_sp = None
        self.lgr.debug('readHap eip 0x%x start 0x%x  end 0x%x' %
                       (eip, start, end))
        if cpl != 0:
            if not self.break_simulation:
                ''' prevent stack trace from triggering haps '''
                self.stopWatch()
            st = self.top.getStackTraceQuiet(max_frames=3)
            if st is None:
                self.lgr.debug('stack trace is None, wrong pid?')
                return
            #self.lgr.debug('%s' % st.getJson())
            ''' look for memcpy'ish... TBD generalize '''
            mem_stuff = st.memsomething()
            #mem_stuff = self.isMemSomething(eip)
            if mem_stuff is not None:
                self.lgr.debug('DataWatch readHap ret_ip 0x%x' %
                               (mem_stuff.ret_addr))
                ''' src is the referenced memory address by default '''
                mem_something = self.MemSomething(mem_stuff.fun,
                                                  mem_stuff.ret_addr, addr,
                                                  None, None)
                SIM_run_alone(self.handleMemStuff, mem_something)
            else:
                self.lgr.debug(
                    'DataWatch readHap not memsomething, reset the watch')
                self.watch()
        instruct = SIM_disassemble_address(self.cpu, eip, 1, 0)
        if op_type == Sim_Trans_Load:
            self.lgr.debug(
                'Data read from 0x%x within input buffer (offset of %d into buffer of %d bytes starting at 0x%x) eip: 0x%x <%s> cycle:0x%x'
                % (addr, offset, self.length[index], self.start[index], eip,
                   instruct[1], self.cpu.cycles))
            msg = (
                'Data read from 0x%x within input buffer (offset of %d into %d bytes starting at 0x%x) eip: 0x%x'
                % (addr, offset, self.length[index], self.start[index], eip))
            self.context_manager.setIdaMessage(msg)
            #mark_msg = 'Read from 0x%08x offset %4d into 0x%8x (buf size %4d) %s' % (addr, offset, self.start[index], self.length[index], self.getCmp())
            self.watchMarks.dataRead(addr, self.start[index],
                                     self.length[index], self.getCmp())
            if self.break_simulation:
                SIM_break_simulation('DataWatch read data')

            if cpl == 0:
                if not self.break_simulation:
                    self.stopWatch()
                SIM_run_alone(self.kernelReturn, addr)

        elif cpl > 0:
            self.lgr.debug(
                'Data written to 0x%x within input buffer (offset of %d into buffer of %d bytes starting at 0x%x) eip: 0x%x'
                % (addr, offset, self.length[index], self.start[index], eip))
            self.context_manager.setIdaMessage(
                'Data written to 0x%x within input buffer (offset of %d into %d bytes starting at 0x%x) eip: 0x%x'
                % (addr, offset, self.length[index], self.start[index], eip))
            if self.break_simulation:
                ''' TBD when to treat buffer as unused?  does it matter?'''
                self.start[index] = 0
                SIM_break_simulation('DataWatch written data')
Пример #20
0
    def runAlone(self, dbi):
        # record where the process is through, won't let debug past this point
        backstop_cycles = dbi.cpu.cycles

        bm = 'protected_memory:0x%x' % self.address
        self.bookmark_mgr.mapOrigin(bm)
        #self.bookmark_mgr.goToDebugBookmark(bm, internal=True, cpu=dbi.cpu)
        '''
        want_cycle = self.bookmark_mgr.getCycle(bm)
        want_step = self.bookmark_mgr.getStep(bm)
        want_eip = self.bookmark_mgr.getEIP(bm)
        done = False
        count = 0
        start_cycle = self.bookmark_mgr.getCycle('_start+1')
        while not done:
            SIM_run_command('pselect cpu-name = %s' % dbi.cpu.name)
            SIM_run_command('skip-to cycle = 0x%x' % start_cycle)
            cycles = SIM_cycle_count(dbi.cpu)
            self.lgr.debug('debugType2, did skip to start at cycle %x, expected %x ' % (cycles, start_cycle))
            SIM_run_command(dbi.command)
            cycles = SIM_cycle_count(dbi.cpu)
            eip = self.top.getEIP(dbi.cpu)
            steps = SIM_step_count(dbi.cpu)
            if want_step is not None:
                self.lgr.debug('debugType2, got cycle: %x step %x eip: %x, expected %x %x %x' % (cycles, steps, eip, want_cycle, want_step, want_eip))
            else:
                self.lgr.debug('debugType2, got cycle: %x step %x eip: %x, expected %x unknown %x' % (cycles, steps, eip, want_cycle, want_eip))
            if cycles != want_cycle or (want_step is not None and steps != want_step) or eip != want_eip:
                self.lgr.error('debugType2, simicsError, try again?')
            else:
                done = True
            
            count += 1
            if count > 4:
                self.lgr.error('debugType2 simics is hosed')
                done = True

        self.lgr.debug('debugType2 after command, cycles is 0x%x, backstop is 0x%x' % (cycles, backstop_cycles))
        '''
        dbi.context_manager.setIdaMessage('[Type 2 Pov read from 0x%x]' %
                                          self.address)
        # remove the previously added bookmark for protected memory
        #self.bookmark_mgr.clearOtherBookmarks('protected_memory:')
        self.bookmark_mgr.clearOtherBookmarks('protected_memory:', bm)
        if not dbi.auto_analysis:
            dbi.context_manager.debug(dbi.cell_name, dbi.pid, dbi.comm,
                                      dbi.cpu, False, backstop_cycles)
        else:
            self.lgr.debug('debugType2, call autoAnalysis')
            dbi.context_manager.debug(dbi.cell_name,
                                      dbi.pid,
                                      dbi.comm,
                                      dbi.cpu,
                                      False,
                                      backstop_cycles,
                                      auto_analysis=True)
            self.top.autoAnalysis(dbi.cell_name, dbi.pid, dbi.comm, dbi.cpu,
                                  False, backstop_cycles)
        cpl = memUtils.getCPL(dbi.cpu)
        if cpl == 0:
            # should not get here, cycles was adjusted when protected memory was read
            self.lgr.error('debugType2 found self in kernel space')
Пример #21
0
    def mem_callback(self, my_args, third, forth, memory):
        cell_name = self.top.getTopComponentName(my_args.cpu)
        cpu, cur_addr, comm, pid = self.os_p_utils[cell_name].getPinfo(
            my_args.cpu)
        self.lgr.debug('mem_callack, %s %d' % (comm, pid))
        if pid == my_args.pid:
            #if self.context_manager.getDebugging() or pid in self.top.__pending_signals:
            if self.context_manager.getDebugging(
            ) or self.top.hasPendingSignal(cell_name, pid):
                self.lgr.debug('mem_callack, debugging or pending signal?')
                return
            if self.ignore_me:
                self.lgr.debug('mem_callack, ignore me?')
                return
            self.ignore_me = True
            location = memory.logical_address
            physical = memory.physical_address
            if location is 0 and physical is 0:
                self.lgr.debug('mem_callack, location zero?')
                ''' recursive callback triggered by this Hap '''
                return
            elif location is 0:
                if pid in self.protected[cell_name]:
                    protected = self.protected[cell_name][pid]
                    if protected is not None:
                        offset = physical & 0x00000fff
                        location = protected.start + offset

            length = memory.size
            op_type = SIM_get_mem_op_type(memory)
            eip = self.os_p_utils[cell_name].mem_utils.getRegValue(cpu, 'eip')
            type_name = SIM_get_mem_op_type_name(op_type)
            self.lgr.debug(
                'mem_callback location 0x%x phys 0x%x len %d  type %s' %
                (location, physical, length, type_name))
            value = 0xDEADBEEF
            where = location
            if length <= 8:
                if op_type is Sim_Trans_Store:
                    value = SIM_get_mem_op_value_le(memory)
                else:
                    if location is not 0:
                        value = int(self.top.getBytes(cpu, length, location),
                                    16)
                    else:
                        value = int(
                            self.top.getBytesPhys(cpu, length, physical), 16)
                        where = physical
                if length == 4:
                    self.recent_value = value
                    self.recent_where = where
                    self.lgr.debug(
                        'protectedMemory, set recent_value to 0x%x' % value)
                elif length == 1:
                    if self.recent_where is None:
                        self.recent_value = value
                        self.recent_where = where
                        self.lgr.debug(
                            'protectedMemory, set 1 byte recent_value to 0x%x'
                            % value)
                    else:
                        value_str = '%x' % self.recent_value
                        if len(value_str) >= 7:
                            ''' more than three bytes, reset '''
                            self.recent_value = value
                            self.recent_where = where
                            self.lgr.debug(
                                'protectedMemory, reset 1 byte recent_value to 0x%x'
                                % value)
                        elif where == self.recent_where + 1:
                            self.recent_value = (
                                self.recent_value << 8) + value
                            self.recent_where = where
                            self.lgr.debug(
                                'protectedMemory, append 1 byte recent_value of 0x%x, now is 0x%x'
                                % (value, self.recent_value))
                        else:
                            self.recent_value = value
                            self.recent_where = where
                            self.lgr.debug(
                                'protectedMemory, not contiguous, reset 1 byte recent_value to 0x%x'
                                % value)

            else:
                self.lgr.info(
                    'Following entry for memory operation > 8 bytes, IGNORE VALUE'
                )

            self.negotiate.getPage(cpu, pid, cell_name)

            self.lgr.info(
                'protectedMemory mem_callback cycle: 0x%x from eip: %x, %d (%s) %s address %x (phys %x)  (%d bytes) value: %x'
                % (my_args.cpu.cycles, eip, pid, comm, type_name, location,
                   physical, length, value))
            cpl = memUtils.getCPL(my_args.cpu)
            if cpl == 0:
                # assume transmit direct from protected page, what else would cause pl0 reference to it?
                if not self.track_access:
                    log_entry = "Protected memory, %d bytes, read from %x using kernel" % (
                        length, where)
                    self.top.addLogEvent(cell_name,
                                         pid,
                                         comm,
                                         forensicEvents.USER_MEM_LEAK,
                                         log_entry,
                                         low_priority=True)
            ''' track the protected memory access for a CB magic page use assessment '''
            if self.track_access:
                #delta = my_args.cpu.cycles - self.start_cycle
                delta = self.top.getPidCycles(cell_name, my_args.pid)
                record = utils.protectedAccess(length, location, delta, cpl)
                #self.lgr.debug('delta is 0x%x' % delta)
                #json_dump = json.dumps(record, default=utils.jdefault)
                #log_entry = 'Protected memory tracker %d bytes from 0x%x cycle 0x%x' % (length, location, delta)
                #self.top.addLogEvent(cell_name, pid, comm, forensicEvents.USER_MEM_LEAK,
                #   json_dump , low_priority=False)
                self.top.addProtectedAccess(record, my_args.pid, cell_name)

            if self.stop_on_memory:
                bm = 'protected_memory:0x%x' % location
                if cpl == 0:
                    cycles, eip = self.other_faults.getCycles(
                        cell_name, my_args.pid)
                    if cycles is None:
                        self.lgr.error(
                            'protectedMemory failed to find cycle of int80 from otherFaults'
                        )
                        return
                    self.top.setDebugBookmark(bm,
                                              cpu=my_args.cpu,
                                              cycles=cycles,
                                              eip=eip)
                    self.lgr.debug(
                        'Protected memory, add bookmark for syscall %s' % bm)
                    #self.lgr.debug('Protected memory, add bookmark adjusted for user space %s set for address %x' % (bm, location))
                else:
                    self.top.setDebugBookmark(bm, cpu=my_args.cpu)
                    self.lgr.debug(
                        'Protected memory, add bookmark %s set for address %x'
                        % (bm, location))

                t_cpu, t_cur_addr, t_comm, t_pid = self.os_p_utils[
                    cell_name].currentProcessInfo(my_args.cpu)
                #self.lgr.debug('Protected memory os_p_utils says %s %d ' % (t_comm, t_pid))
                if location not in self.address_readers:
                    self.address_readers[location] = procInfo.procInfo(
                        comm, cpu, pid)
                #SIM_break_simulation('address 0x%x (virt: 0x%x)  value 0x%x' % (physical, location, value))
        else:
            self.lgr.info(
                'unexpected memory access in %s %d, comm: %s  address %x' %
                (cell_name, pid, comm, memory.logical_address))
            pass

        self.ignore_me = False
Пример #22
0
    def thinkWeWrote(self):
        #if self.stop_write_hap is None:
        #    return
        reg_num = self.cpu.iface.int_register.get_number("eip")
        eip = self.cpu.iface.int_register.read(reg_num)
        cycle = self.cpu.cycles
        cpl = memUtils.getCPL(self.cpu)
        instruct = SIM_disassemble_address(self.cpu, eip, 1, 0)
        self.lgr.debug('in thinkWeWrote, cycle %x eip: %x  %s cpl: %d' %
                       (cycle, eip, str(instruct), cpl))
        if cpl == 0:
            if self.found_kernel_write:
                self.lgr.debug(
                    'stopToCheckWriteCallback found second write?  but we deleted the breakpoint!!!! ignore this and reverse'
                )
                #SIM_run_alone(SIM_run_command, 'reverse')
                return
            cpu, cur_addr, comm, pid = self.os_utils.currentProcessInfo(
                self.cpu)
            ''' get return address '''
            self.found_kernel_write = True
            if self.kernel_write_break is not None:
                self.lgr.debug('deleting breakpoint %d' %
                               self.kernel_write_break)
                SIM_delete_breakpoint(self.kernel_write_break)
                self.kernel_write_break = None

            self.kernel_exit_break1 = self.context_manager.genBreakpoint(
                self.cell, Sim_Break_Linear, Sim_Access_Execute,
                self.param.sysexit, 1, 0)
            self.kernel_exit_break2 = self.context_manager.genBreakpoint(
                self.cell, Sim_Break_Linear, Sim_Access_Execute,
                self.param.iretd, 1, 0)
            self.exit_hap = self.context_manager.genHapRange(
                "Core_Breakpoint_Memop", self.exitHap, None,
                self.kernel_exit_break1, self.kernel_exit_break2,
                'findKernelWrite exits')
            self.cleanup()
            SIM_run_alone(SIM_run_command, 'continue')

        elif self.found_kernel_write:
            self.lgr.debug(
                'thinkWeWrote, BACKTRACK user space address 0x%x after finding kernel write to  0x%x'
                % (eip, self.addr))
            if not self.checkWriteValue(eip):
                return

            value = self.os_p_utils.getMemUtils().readWord32(
                self.cpu, self.addr)
            eip = self.top.getEIP(self.cpu)
            if eip == self.bookmarks.getEIP('_start+1'):
                ida_message = "Content of 0x%x existed pror to _start+1, perhaps from loader." % self.addr
                bm = None
            else:
                ida_message = 'Kernel wrote 0x%x to address: 0x%x' % (
                    value, self.addr)
                self.lgr.debug('set ida msg to %s' % ida_message)
                bm = "backtrack eip:0x%x follows kernel write of value:0x%x to memory:0x%x" % (
                    eip, value, self.addr)
            if bm is not None:
                self.bookmarks.setDebugBookmark(bm)
            self.context_manager.setIdaMessage(ida_message)
            SIM_run_alone(self.cleanup, False)
            self.top.skipAndMail()
            #previous = SIM_cycle_count(my_args.cpu) - 1
            #SIM_run_alone(SIM_run_command, 'skip-to cycle=%d' % previous)
            #eip = self.top.getEIP()
            #msg = '0x%x' % eip
            #self.top.gdbMailbox(msg)

            self.context_manager.setExitBreak(self.cpu)

        else:
            if not self.checkWriteValue(eip):
                return
            eip = self.top.getEIP(self.cpu)
            SIM_run_alone(self.cleanup, False)
            if eip == self.bookmarks.getEIP('_start+1'):
                ida_message = "Content of %s came from loader." % self.addr
                bm = "backtrack eip:0x%x content of memory:%s came from loader" % (
                    eip, self.addr)
                self.bookmarks.setDebugBookmark(bm)
                self.context_manager.setIdaMessage(ida_message)
                SIM_run_alone(self.cleanup, False)
                self.top.skipAndMail()

            elif self.rev_to_call is None:
                # reverse two so we land on the instruction that does the write (after client steps forward 1)
                self.lgr.debug(
                    'thinkWeWrote eip is %x in user space,  stop here and reverse 2  : may break if page fault?'
                    % eip)
                self.top.skipAndMail(cycles=2)
            else:
                SIM_run_alone(self.backOneAlone, None)
            #self.top.skipAndMail()
            #previous = SIM_cycle_count(my_args.cpu) - 1
            #SIM_run_alone(SIM_run_command, 'skip-to cycle=%d' % previous)
            #eip = self.top.getEIP()
            #msg = '0x%x' % eip
            #self.top.gdbMailbox(msg)

            self.context_manager.setExitBreak(self.cpu)