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..")
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))
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()
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