class GdbProtocolTestCase(unittest.TestCase): def setUp(self): pass def setup_env(self, binary, unix_socket=False): self.process = subprocess.Popen( ['gdbserver', '--once', '127.0.0.1:%d' % PORT, binary], stderr=subprocess.PIPE) out = str(self.process.stderr.readline()) self.assertEqual(binary in out, True, out) out = str(self.process.stderr.readline()) self.assertEqual(str(PORT) in out, True, out) self.gdb = GDBProtocol(arch=avatar2.archs.X86_64) if unix_socket is True: socket_path = '/tmp/test_socket' unix2tcp(socket_path, "127.0.0.1", PORT) self.gdb.remote_connect_unix(socket_path) else: self.gdb.remote_connect(port=PORT) # Base addresses can change across kernel versions due to PIE binaries self.base_address = self.gdb.get_symbol("main")[1] & ~0xfff def wait_stopped(self): # As we do not have access to avatar synchronizing target states # on this level, we apply this little hack to synchronize the target while True: ret, out = self.gdb.console_command('info program') if 'Program stopped' in out: break time.sleep(SLEEP_TIME) def tearDown(self): self.gdb.shutdown() self.process.terminate()
def _connect_protocols(self): """ Internal routine to connect the various protocols to a running qemu """ gdb = GDBProtocol( gdb_executable=self.gdb_executable, arch=self.avatar.arch, verbose=self.gdb_verbose, additional_args=self.gdb_additional_args, avatar=self.avatar, origin=self, ) qmp = QMPProtocol(self.qmp_port, origin=self) if "avatar-rmemory" in [ i[2].qemu_name for i in self._memory_mapping.iter() if hasattr(i[2], "qemu_name") ] and RemoteMemoryProtocol is not None: rmp = RemoteMemoryProtocol( self._rmem_tx_queue_name, self._rmem_rx_queue_name, self.avatar.queue, self, ) else: rmp = None self.protocols.set_all(gdb) self.protocols.monitor = qmp self.protocols.remote_memory = rmp connect_success = True if self.gdb_unix_socket_path: connect_success = connect_success and gdb.remote_connect_unix( self.gdb_unix_socket_path) else: connect_success = connect_success and gdb.remote_connect( port=self.gdb_port) connect_success = connect_success and qmp.connect() if connect_success: self.log.info("Connected to remote target") else: self.log.warning("Connection to remote target failed") if rmp: rmp.connect() self.wait()
def init(self): gdb = GDBProtocol(gdb_executable=self.gdb_executable, arch=self._arch, additional_args=self.gdb_additional_args, avatar=self.avatar, origin=self, enable_init_files=self._enable_init_files, binary=self._local_binary, local_arguments=self._arguments, verbose=self._verbose_gdbmi) # If we are debugging a program locally, # we do not need to establish any connections if not self._local_binary: if self.gdb_unix_socket_path is not None: if gdb.remote_connect_unix(self.gdb_unix_socket_path): self.log.info("Connected to Target") else: self.log.warning("Connecting failed") elif not self._serial: if gdb.remote_connect(ip=self.gdb_ip, port=self.gdb_port): self.log.info("Connected to Target") else: self.log.warning("Connecting failed") else: if gdb.remote_connect_serial( device=self.gdb_serial_device, baud_rate=self.gdb_serial_baud_rate, parity=self.gdb_serial_parity): self.log.info("Connected to Target") else: self.log.warning("Connecting failed") else: self.update_state(TargetStates.INITIALIZED) self.protocols.set_all(gdb) if self._local_binary: self.wait(state=TargetStates.INITIALIZED) else: self.wait()