Пример #1
0
// perform an action (func) on all debuggers
int for_all_debuggers(debmod_visitor_t &v)
{
  int code = 0;
  qmutex_lock(g_lock);
  {
    rpc_server_list_t::iterator it;
    for ( it=clients_list.begin(); it != clients_list.end(); ++it )
    {
      code = v.visit(it->first->get_debugger_instance());
      if ( code != 0 )
        break;
    }
  } qmutex_unlock(g_lock);
  return code;
}
Пример #2
0
//--------------------------------------------------------------------------
static void NT_CDECL shutdown_gracefully(int signum)
{
  qeprintf("got signal #%d\n", signum);

#ifdef __SINGLE_THREADED_SERVER__

  if ( g_global_server != NULL )
  {
    debmod_t *d = g_global_server->get_debugger_instance();
    if ( d != NULL )
      d->dbg_exit_process();
    g_global_server->term_irs();
  }
#else
  qmutex_lock(g_lock);

  for (rpc_server_list_t::iterator it = clients_list.begin(); it != clients_list.end();++it)
  {
    rpc_server_t *server = it->first;
    qthread_t thr = it->second;

    // free thread
    if ( thr != NULL )
      qthread_free(thr);

    if ( server == NULL || server->irs == NULL )
      continue;

    debmod_t *d = server->get_debugger_instance();
    if ( d != NULL )
      d->dbg_exit_process(); // kill the process instead of letting it run in wild

    server->term_irs();
  }

  clients_list.clear();
  qmutex_unlock(g_lock);
  qmutex_free(g_lock);
#endif

  if ( listen_socket != INVALID_SOCKET )
    closesocket(listen_socket);

  term_subsystem();
  _exit(1);
}
Пример #3
0
//--------------------------------------------------------------------------
static void NT_CDECL shutdown_gracefully(int signum)
{
  if ( signum == SIGINT && ignore_sigint )
  {
    ignore_sigint = false;
    return;
  }

#if defined(__NT__) || defined(__ARM__) // strsignal() is not available
  qeprintf("got signal #%d, terminating\n", signum);
#else
  qeprintf("%s: terminating the server\n", strsignal(signum));
#endif

  srv_lock_begin();

  for (rpc_server_list_t::iterator it = clients_list.begin(); it != clients_list.end();++it)
  {
    rpc_server_t *server = it->first;
#ifndef __SINGLE_THREADED_SERVER__
    qthread_t thr = it->second;

    // free thread
    if ( thr != NULL )
      qthread_free(thr);
#endif
    if ( server == NULL || server->irs == NULL )
      continue;

    debmod_t *d = server->get_debugger_instance();
    if ( d != NULL )
      d->dbg_exit_process(); // kill the process instead of letting it run in wild

    server->term_irs();
  }

  clients_list.clear();
  srv_lock_end();
  srv_lock_free();

  if ( listen_socket != INVALID_SOCKET )
    closesocket(listen_socket);

  term_subsystem();
  _exit(1);
}
Пример #4
0
//--------------------------------------------------------------------------
static void handle_single_session(rpc_server_t *server)
{
  lprintf("=========================================================\n"
    "Accepting incoming connection...\n");

  qstring open = prepare_rpc_packet(RPC_OPEN);
  append_long(open, IDD_INTERFACE_VERSION);
  append_long(open, DEBUGGER_ID);
  append_long(open, sizeof(ea_t));

  rpc_packet_t *rp = server->process_request(open, PRF_LOGIN|PRF_DONT_POLL);

  if ( rp == NULL )
  {
    lprintf("Could not establish the connection\n");

    delete server;
    return;
  }

  // Answer is beyond the rpc_packet_t buffer
  const uchar *answer = (uchar *)(rp+1);
  const uchar *end = answer + rp->length;
  bool send_response = true;

  bool ok = extract_long(&answer, end);
  if ( !ok )
  {
    lprintf("Incompatible IDA Pro version\n");
    send_response = false;
  }
  else if ( server_password != NULL )
  {
    char *pass = extract_str(&answer, end);
    if ( strcmp(pass, server_password) != '\0' )
    {
      lprintf("Bad password\n");
      ok = false;
    }
  }

  qfree(rp);

  if ( send_response )
  {
    server->poll_debug_events = false;
    server->has_pending_event = false;

    open = prepare_rpc_packet(RPC_OK);
    append_long(open, ok);
    server->send_request(open);

    if ( ok )
    {
      qstring cmd;
      rpc_packet_t *packet = server->process_request(cmd, PRF_POLL);
      if ( packet != NULL )
        qfree(packet);
    }
  }
  server->network_error_code = 0;

  lprintf("Closing incoming connection...\n");

  server->term_irs();

#ifndef __SINGLE_THREADED_SERVER__
  // Remove the session from the list
  qmutex_lock(g_lock);
  for (rpc_server_list_t::iterator it = clients_list.begin(); it != clients_list.end();++it)
  {
    if ( it->first != server )
      continue;

    // free the thread resources
    qthread_free(it->second);

    // remove client from the list
    clients_list.erase(it);
    break;
  }
  qmutex_unlock(g_lock);
#endif

  // Free the debug session
  delete server;
}
Пример #5
0
//--------------------------------------------------------------------------
static void handle_single_session(rpc_server_t *server)
{
  static int s_sess_id = 1;
  int sid = s_sess_id++;

  char peername[MAXSTR];
  if ( !irs_peername(server->irs, peername, sizeof(peername), false) )
    qstrncpy(peername, "(unknown)", sizeof(peername));
  lprintf("=========================================================\n"
          "[%d] Accepting connection from %s...\n", sid, peername);

  bytevec_t req = prepare_rpc_packet(RPC_OPEN);
  append_dd(req, IDD_INTERFACE_VERSION);
  append_dd(req, DEBUGGER_ID);
  append_dd(req, sizeof(ea_t));

  rpc_packet_t *rp = server->process_request(req, true);

  bool handle_request = true;
  bool send_response  = true;
  bool ok;
  if ( rp == NULL )
  {
    lprintf("[%d] Could not establish the connection\n", sid);
    handle_request = false;
    send_response  = false;
  }

  if ( handle_request )
  {
    // Answer is beyond the rpc_packet_t buffer
    const uchar *answer = (uchar *)(rp+1);
    const uchar *end = answer + rp->length;

    ok = extract_long(&answer, end) != 0;
    if ( !ok )
    {
      lprintf("[%d] Incompatible IDA version\n", sid);
      send_response = false;
    }
    else if ( server_password != NULL )
    {
      char *pass = extract_str(&answer, end);
      if ( strcmp(pass, server_password) != '\0' )
      {
        lprintf("[%d] Bad password\n", sid);
        ok = false;
      }
    }

    qfree(rp);
  }

  if ( send_response )
  {
    req = prepare_rpc_packet(RPC_OK);
    append_dd(req, ok);
    server->send_request(req);

    if ( ok )
    {
      // the main loop: handle client requests until it drops the connection
      // or sends us RPC_OK (see rpc_debmod_t::close_remote)
      bytevec_t empty;
      rpc_packet_t *packet = server->process_request(empty);
      if ( packet != NULL )
        qfree(packet);
    }
  }
  server->network_error_code = 0;
  lprintf("[%d] Closing connection from %s...\n", sid, peername);

  bool preserve_server = keep_broken_connections && server->get_broken_connection();
  if ( !preserve_server )
  { // Terminate dedicated debugger instance.
    server->get_debugger_instance()->dbg_term();
    server->term_irs();
  }
  else
  {
    server->term_irs();
    lprintf("[%d] Debugged session entered into sleeping mode\n", sid);
    server->prepare_broken_connection();
  }

  if ( !preserve_server )
  {
    // Remove the session from the list
    srv_lock_begin();
    for (rpc_server_list_t::iterator it = clients_list.begin(); it != clients_list.end();++it)
    {
      if ( it->first != server )
        continue;

#ifndef __SINGLE_THREADED_SERVER__
      // free the thread resources
      qthread_free(it->second);
#endif

      // remove client from the list
      clients_list.erase(it);
      break;
    }
    srv_lock_end();

    // Free the debug session
    delete server;
  }
}