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); }
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; }