static gboolean get_process_cmdline(gint p_pid, gchar **p_exe, gchar **p_cmd_line)
{
#ifdef DEBUG_VERBOSE
    purple_debug_info("gfire", "trace: get_process_cmdline(%d)\n", p_pid);
#endif // DEBUG_VERBOSE

    HANDLE process;
    PVOID peb;
    PVOID rtlUserProcParamsAddress;
    UNICODE_STRING cmdline;
    WCHAR *cmdline_buff;

    *p_exe = *p_cmd_line = NULL;

    if((process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, p_pid)) == 0)
    {
        // Don't handle missing permissions as an error
        if(GetLastError() != ERROR_ACCESS_DENIED)
        {
            gchar tmpError[1024];
            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, tmpError, 1024, NULL);
            purple_debug_error("gfire", "get_process_cmdline: Could not open process for reading:\n(%u) %s", (guint)GetLastError(), tmpError);
        }
#ifdef DEBUG
        else
            purple_debug_error("gfire", "get_process_cmdline: Could not open process for reading:\n Access denied\n");
#endif // DEBUG

        return FALSE;
    }

    peb = get_peb_address(process);
    if(!peb)
    {
#ifdef DEBUG
        purple_debug_error("gfire", "get_process_cmdline: bad peb address!\n");
#endif // DEBUG

        CloseHandle(process);
        return FALSE;
    }

    if(!ReadProcessMemory(process, (PCHAR)peb + 0x10, &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
    {
        if(GetLastError() != ERROR_ACCESS_DENIED  && GetLastError() != ERROR_PARTIAL_COPY)
        {
            gchar tmpError[1024];
            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, tmpError, 1024, NULL);
            purple_debug_error("gfire", "get_process_cmdline: Could not read the address of ProcessParameters:\n(%u) %s", (guint)GetLastError(), tmpError);
        }
#ifdef DEBUG
        else
            purple_debug_error("gfire", "get_process_cmdline: Could not read the address of ProcessParameters:\n Access denied/Partial Read\n");
#endif // DEBUG

        CloseHandle(process);
        return FALSE;
    }

    if(!ReadProcessMemory(process, (PCHAR)rtlUserProcParamsAddress + 0x40, &cmdline, sizeof(cmdline), NULL))
    {
        if(GetLastError() != ERROR_ACCESS_DENIED  && GetLastError() != ERROR_PARTIAL_COPY)
        {
            gchar tmpError[1024];
            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, tmpError, 1024, NULL);
            purple_debug_error("gfire", "get_process_cmdline: Could not read CommandLine:\n(%u) %s", (guint)GetLastError(), tmpError);
        }
#ifdef DEBUG
        else
            purple_debug_error("gfire", "get_process_cmdline: Could not read CommandLine:\n Access denied/Partial Read\n");
#endif // DEBUG

        CloseHandle(process);
        return FALSE;
    }

    cmdline_buff = (WCHAR*)g_malloc0(cmdline.Length);
    if(!ReadProcessMemory(process, cmdline.Buffer, cmdline_buff, cmdline.Length, NULL))
    {
        if(GetLastError() != ERROR_ACCESS_DENIED && GetLastError() != ERROR_PARTIAL_COPY)
        {
            gchar tmpError[1024];
            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, tmpError, 1024, NULL);
            purple_debug_error("gfire", "get_process_cmdline: Could not read the command line string:\n(%u) %s", (guint)GetLastError(), tmpError);
        }
#ifdef DEBUG
        else
            purple_debug_error("gfire", "get_process_cmdline: Could not read the command line string:\n Access denied/Partial Read\n");
#endif // DEBUG

        g_free(cmdline_buff);
        CloseHandle(process);
        return FALSE;
    }

    *p_cmd_line = g_utf16_to_utf8((gunichar2*)cmdline_buff, cmdline.Length / 2, NULL, NULL, NULL);
    g_free(cmdline_buff);

#ifdef DEBUG
    if(!*p_cmd_line)
        purple_debug_error("gfire", "get_process_cmdline: g_utf16_to_utf8 failed on cmdline\n");
#endif // DEBUG

    // Get process executable
    cmdline_buff = (WCHAR*)g_malloc(2048);
    DWORD len = GetModuleFileNameExW(process, NULL, cmdline_buff, 1024);
    if(len == 0)
    {
        if(GetLastError() != ERROR_ACCESS_DENIED)
        {
            gchar tmpError[1024];
            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, tmpError, 1024, NULL);
            purple_debug_error("gfire", "get_process_cmdline: Could not read the executable filename string:\n(%u) %s", (guint)GetLastError(), tmpError);
        }
#ifdef DEBUG
        else
            purple_debug_error("gfire", "get_process_cmdline: Could not read the executable filename string:\n Access denied\n");
#endif // DEBUG

        g_free(cmdline_buff);
        g_free(*p_cmd_line);
        *p_cmd_line = NULL;
        CloseHandle(process);
        return FALSE;
    }

    *p_exe = g_utf16_to_utf8((gunichar2*)cmdline_buff, len, NULL, NULL, NULL);
    g_free(cmdline_buff);

#ifdef DEBUG
    if(!*p_exe)
        purple_debug_error("gfire", "get_process_cmdline: g_utf16_to_utf8 failed on exe\n");
#endif // DEBUG

    CloseHandle(process);

    return (*p_exe && *p_cmd_line);
}
Exemple #2
0
void handle_command(struct drpc_packet *pkt, char *buf)
{
  unsigned long pid;
  unsigned long tid;
  unsigned long addr;
  unsigned long len;
  unsigned long sel;
  unsigned long flags;
  unsigned long n;
  CONTEXT *ctxt;

  // Validate request
  if (pkt->startmark != startmark) logmsg("WARNING: unexpected startmark %08X\n", pkt->startmark);
  if (pkt->reserved1 != 0) logmsg("WARNING: reserved1 is %08X\n", pkt->reserved1);
  if (pkt->reserved2 != 0) logmsg("WARNING: reserved2 is %08X\n", pkt->reserved2);
  if (pkt->result != 0) logmsg("WARNING: result is %08X\n", pkt->result);

  // Execute command
  switch (pkt->cmd)
  {
    case DRPC_GET_SYSTEM_VERSION:
      logmsg("COMMAND GetSystemVersion: spnamelen=%d, buildnamelen=%d\n", *(unsigned long *) (buf + 0), *(unsigned long *) (buf + 8));
      get_system_version(pkt, buf);
      break;

    case DRPC_DEBUG_BREAK:
      tid = *(unsigned long *) (buf + 0);
      logmsg("COMMAND DebugBreak hthread=%08X\n", tid);
      pkt->result = E_FAIL;
      break;

    case DRPC_GET_HOST_INFO:
      logmsg("COMMAND GetHostInfo: hostlen=%d, transportlen=%d\n", *(unsigned long *) (buf + 0), *(unsigned long *) (buf + 8));
      get_host_info(pkt, buf);
      break;

    case DRPC_GET_CPU_INFO:
      logmsg("COMMAND GetCpuInfo: maxlen=%d\n", *(unsigned long *) buf);
      get_cpu_info(pkt, buf);
      break;

    case DRPC_GET_PROCESS_LIST:
      logmsg("COMMAND GetProcessList: maxpids=%d\n", *(unsigned long *) buf);
      get_process_list(pkt, buf);
      break;

    case DRPC_GET_PROCESS_NAME:
      pid = *(unsigned long *) buf;
      logmsg("COMMAND GetProcessName pid=%d:\n", pid);
      get_process_name(pkt, buf);
      break;

    case DRPC_DEBUG_PROCESS:
      pid = *(unsigned long *) buf;
      logmsg("COMMAND DebugProcess pid=%d (%08X):\n", pid, pid);
      pkt->result = E_FAIL;
      break;

    case DRPC_OPEN_PROCESS:
      pid = *(unsigned long *) buf;
      flags = *(unsigned long *) (buf + 8);
      logmsg("COMMAND OpenProcess pid=%d (%08X) flags=%08X:\n", pid, pid, flags);
      open_process(pkt, buf);
      break;

    case DRPC_CREATE_PROCESS:
      pid = *(unsigned long *) buf;
      logmsg("COMMAND CreateProcess: cmd=%S flags=%08X:\n", buf, *(unsigned long *)(buf + pkt->reqlen - 4));
      pkt->result = E_FAIL;
      break;

    case DRPC_READ_PROCESS_MEMORY:
      pid = *(unsigned long *) (buf + 0);
      addr = *(unsigned long *) (buf + 8);
      len = *(unsigned long *) (buf + 16);
      logmsg("COMMAND ReadProcessMemory hproc=%08X addr=%08x len=%d:\n", pid, addr, len);
      read_memory(pkt, buf);
      break;

    case DRPC_WRITE_PROCESS_MEMORY:
      pid = *(unsigned long *) (buf + 0);
      addr = *(unsigned long *) (buf + 8);
      len = *(unsigned long *) (buf + 16);
      logmsg("COMMAND WriteProcessMemory hproc=%08X addr=%08x len=%d:\n", pid, addr, len);
      write_memory(pkt, buf);
      break;

    case DRPC_SUSPEND_THREAD:
      len = *(unsigned long *) (buf + 0);
      logmsg("COMMAND SuspendThread: hthread=");
      for (n = 0; n < len; n++)
      {
        tid = *(unsigned long *) (buf + 8 + n * 8);
        logmsg(" %08X", tid);
      }
      logmsg("\n");
      suspend_threads(pkt, buf);
      break;

    case DRPC_RESUME_THREAD:
      len = *(unsigned long *) (buf + 0);
      logmsg("COMMAND ResumeThread: hthread=");
      for (n = 0; n < len; n++)
      {
        tid = *(unsigned long *) (buf + 8 + n * 8);
        logmsg(" %08X", tid);
      }
      logmsg("\n");
      resume_threads(pkt, buf);
      break;

    case DRPC_GET_THREAD_CONTEXT:
      tid = *(unsigned long *) (buf + 0);
      flags = *(unsigned long *) (buf + 8);
      len = *(unsigned long *) (buf + 16);
      logmsg("COMMAND GetThreadContext hthread=%08X context=%08x len=%d:\n", tid, flags, len);
      get_context(pkt, buf);
      break;

    case DRPC_SET_THREAD_CONTEXT:
      tid = *(unsigned long *) (buf + 0); 
      len = *(unsigned long *) (buf + 8);
      ctxt = (CONTEXT *) (buf + 12);
      logmsg("COMMAND SetThreadContext hthread=%08X eax=%08x len=%d:\n", tid, ctxt->Eax, len);
      set_context(pkt, buf);
      break;

    case DRPC_GET_PEB_ADDRESS:
      pid = *(unsigned long *) (buf + 0);
      logmsg("COMMAND GetPebAddress hproc=%08X:\n", pid);
      get_peb_address(pkt, buf);
      break;

    case DRPC_GET_THREAD_SELECTOR:
      tid = *(unsigned long *) (buf + 0);
      sel = *(unsigned long *) (buf + 8);
      len = *(unsigned long *) (buf + 12);
      logmsg("COMMAND GetThreadSelector hthread=%08X selector=%08x len=%08x:\n", tid, sel, len);
      get_thread_selector(pkt, buf);
      break;

    case DRPC_GET_DEBUG_EVENT:
      logmsg("COMMAND GetDebugEvent %08X %08X:\n", *(unsigned long *) buf, *(unsigned long *) (buf + 4));
      get_debug_event(pkt, buf);
      break;

    case DRPC_CONTINUE_DEBUG_EVENT:
      flags = *(unsigned long *) buf;
      if (flags == 0x00010001)
        logmsg("COMMAND ContinueDebugEvent: DBG_EXCEPTION_HANDLED\n");
      else if (flags == 0x00010002)
        logmsg("COMMAND ContinueDebugEvent: DBG_CONTINUE\n");
      else
        logmsg("COMMAND ContinueDebugEvent: %08X\n", flags);

      break;

    case 0x0000C001:
      logmsg("COMMAND 0000C001\n");
      pkt->result = dbg_state;
      break;

    case 0x0004C002:
      logmsg("COMMAND 0004C002\n");
      *(unsigned long *) buf = 5;
      break;

    default:
      logmsg("COMMAND %08X ??? (reqlen=%d, rsplen=%d):\n", pkt->cmd, pkt->reqlen, pkt->rsplen);
      if (pkt->reqlen > 0)
      {
        logmsg("reqdata: ");
        dump_data(stdout, buf, pkt->reqlen > 256 ? 256 : pkt->reqlen, 4, NULL);
        if (logfile) dump_data(logfile, buf, pkt->reqlen, 4, NULL);
      }
      pkt->result = E_FAIL;
  }

  pkt->cmd |= 0x00010000;
}