Example #1
0
 def run(self):
     self.please_stop = False
     # Loops until someone (the Dummy Target) tells me to stop by
     # externally setting the "please_stop" variable to True
     while not self.please_stop:
         self.target.log.info("Dummy target doing Nothing..")
         time.sleep(1)
         self.steps += 1
         # 10% chances of triggering a breakpoint
         if random.randint(0, 100) < 10:
             # If there are not breakpoints set, continue
             if len(self.target.bp) == 0:
                 continue
             # Randomly pick one of the breakpoints
             addr = random.choice(self.target.bp)
             self.target.log.info("Taking a break..")
             # Add a message to the Avatar queue to trigger the
             # breakpoint
             self.target.avatar.queue.put(
                 BreakpointHitMessage(self.target, 1, addr))
             break
         # 90% chances of reading from a forwarded memory address
         else:
             # Randomly pick one forwarded range
             mem_range = random.choice(self.target.mranges)
             # Randomly pick an address in the range
             addr = random.randint(mem_range[0], mem_range[1] - 4)
             # Add a message in the Avatar queue to read the value at
             # that address
             self.target.avatar.queue.put(
                 RemoteMemoryReadMessage(self.target, 55, 55, addr, 4))
     self.target.log.info("Avatar told me stop..")
Example #2
0
 def run(self):
     while True:
         msg = self._worker_queue.get()
         if msg is None:
             break
         if isinstance(msg, UnicornWorkerEmuStartMessage):
             self._avatar_queue.put(
                 UpdateStateMessage(self._origin, TargetStates.RUNNING))
             if self._protocol.pending_bp:
                 # Single-step over pending breakpoints, the hook will ignore them
                 old_pending_bp = self._protocol.pending_bp.copy()
                 self._uc.emu_start(self._get_next_pc(),
                                    self._EMU_END_ADDRESS,
                                    count=1)
                 if self._protocol.pending_bp == old_pending_bp:
                     # We did not hit another breakpoint during the step, empty the pending set
                     self._protocol.pending_bp.clear()
                 if msg.single_step:
                     # We already stepped: done
                     continue
             if not self._protocol.pending_bp:
                 # Either there was no pending breakpoint, or we didn't hit
                 # another breakpoint while single stepping: keep running
                 count = 1 if msg.single_step else 0
                 self._uc.emu_start(self._get_next_pc(),
                                    self._EMU_END_ADDRESS,
                                    count=count)
         elif isinstance(msg, UnicornWorkerUpdateStateMessage):
             self._avatar_queue.put(
                 UpdateStateMessage(self._origin, msg.state))
         elif isinstance(msg, UnicornWorkerBreakpointMessage):
             # When stopping from a hook, Unicorn resets the PC to the beginning of the basic
             # block that contains the instruction that triggered the hook.
             # The register state, however, isn't rolled back.
             # As a workaround, we set the PC here to the breakpoint address.
             # See https://github.com/unicorn-engine/unicorn/issues/969
             self._protocol.write_register(self._protocol.arch.pc_name,
                                           msg.address)
             self._avatar_queue.put(
                 BreakpointHitMessage(self._origin, msg.bkptno,
                                      msg.address))
         else:
             raise Exception(
                 'Unknown message in Unicorn worker queue: {}'.format(msg))
Example #3
0
    def run(self):
        # Target state management thread
        # This thread needs to poll for the halted state
        # of the target
        # JLink is lame and doesn't let you do this asynch
        # Also, not all targets produce a "moe" (Mode of Entry)
        # so we have to actually do that here.
        try:
            while not self._shutdown.is_set():
                is_halted = self.jlink.halted()
                if is_halted and self._origin.state == TargetStates.RUNNING:
                    # We just halted
                    # But did we hit a BP?
                    self.log.debug("JLink Target is halting...")
                    avatar_msg = UpdateStateMessage(self._origin,
                                                    TargetStates.STOPPED)
                    self.avatar.fast_queue.put(avatar_msg)
                    self._origin.wait()
                    self.log.debug("JLink target has halted")
                    pc = self.get_pc()
                    if self.jlink.breakpoint_find(pc):
                        self.log.debug("JLink Target hit breakpoint %d" %
                                       self.jlink.breakpoint_find(pc))
                        avatar_msg = BreakpointHitMessage(
                            self._origin, self.jlink.breakpoint_find(pc), pc)
                        self.avatar.queue.put(avatar_msg)

                elif not is_halted and self._origin.state == TargetStates.STOPPED:
                    self.log.info("About to resume target.")
                    avatar_msg = UpdateStateMessage(self._origin,
                                                    TargetStates.RUNNING)
                    self.avatar.fast_queue.put(avatar_msg)
                    while self._origin.state != TargetStates.RUNNING:
                        pass
                    self.log.debug("JLink target has resumed")
        except:
            self.log.exception("JLink target errored")
        finally:
            self.log.info("JLink target exiting")
            self.jlink.close()
Example #4
0
    def parse_async_notify(self, response):
        """
        This functions converts gdb notify messages to an avatar message

        :param response: A pygdbmi response dictonary
        :returns:        An avatar message
        """

        # Make sure this is a notify-response
        if response['type'] != 'notify':
            raise RuntimeError()

        msg = response['message']
        payload = response['payload']
        avatar_msg = None

        self.log.debug("Received Message: %s", msg)

        if msg.startswith('thread'):
            if msg == 'thread-group-exited':
                avatar_msg = UpdateStateMessage(self._origin,
                                                TargetStates.EXITED)
        elif msg.startswith('tsv'):
            pass  # likewise tracing
        elif msg.startswith('library'):
            pass  # library loading not supported yet
        elif msg == 'breakpoint-modified':
            pass  # ignore breakpoint modified for now
        elif msg == 'memory-changed':
            pass  # ignore changed memory for now
        elif msg == 'stopped':
            if payload.get('reason') == 'breakpoint-hit':
                avatar_msg = BreakpointHitMessage(
                    self._origin, int(payload['bkptno']),
                    int(payload['frame']['addr'], 16))
            elif payload.get('reason') == 'exited-normally':
                avatar_msg = UpdateStateMessage(self._origin,
                                                TargetStates.EXITED)
            elif payload.get('reason') == 'end-stepping-range':
                avatar_msg = UpdateStateMessage(self._origin,
                                                TargetStates.STOPPED)
            elif payload.get('reason') == 'signal-received':
                if payload.get('signal-name') == 'SIGSEGV':
                    avatar_msg = UpdateStateMessage(self._origin,
                                                    TargetStates.EXITED)
                elif payload.get('signal-name') == 'SIGTRAP':
                    avatar_msg = BreakpointHitMessage(
                        self._origin, -1, int(payload['frame']['addr'], 16))
                else:
                    avatar_msg = UpdateStateMessage(self._origin,
                                                    TargetStates.STOPPED)
            elif payload.get('reason') == 'watchpoint-trigger':
                avatar_msg = UpdateStateMessage(self._origin,
                                                TargetStates.STOPPED)
            elif payload.get('reason') == 'access-watchpoint-trigger':
                avatar_msg = UpdateStateMessage(self._origin,
                                                TargetStates.STOPPED)
            elif payload.get('reason') == 'read-watchpoint-trigger':
                avatar_msg = UpdateStateMessage(self._origin,
                                                TargetStates.STOPPED)
            elif payload.get('reason') is not None:
                self.log.critical("Target stopped with unknown reason: %s" %
                                  payload['reason'])
                # raise RuntimeError
            else:
                avatar_msg = UpdateStateMessage(self._origin,
                                                TargetStates.STOPPED)
        elif msg == 'running':
            avatar_msg = UpdateStateMessage(self._origin, TargetStates.RUNNING)

        else:
            self.log.critical('Catched unknown async message: %s' % response)

        return avatar_msg