static int fork_and_ptraceme(const char *cmd) { PROCESS_INFORMATION pi; STARTUPINFO si = { sizeof (si) }; DEBUG_EVENT de; int pid, tid; HANDLE th = INVALID_HANDLE_VALUE; if (!*cmd) return -1; setup_tokens (); /* TODO: with args */ if (!CreateProcess (cmd, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi)) { r_sys_perror ("CreateProcess"); return -1; } /* get process id and thread id */ pid = pi.dwProcessId; tid = pi.dwThreadId; #if 0 /* load thread list */ { HANDLE h; THREADENTRY32 te32; HANDLE WINAPI (*win32_openthread)(DWORD, BOOL, DWORD) = NULL; win32_openthread = (HANDLE WINAPI (*)(DWORD, BOOL, DWORD)) GetProcAddress (GetModuleHandle ("kernel32"), "OpenThread"); th = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, pid); if (th == INVALID_HANDLE_VALUE || !Thread32First(th, &te32)) r_sys_perror ("CreateToolhelp32Snapshot"); do { if (te32.th32OwnerProcessID == pid) { h = win32_openthread (THREAD_ALL_ACCESS, 0, te32.th32ThreadID); if (h == NULL) r_sys_perror ("OpenThread"); else eprintf ("HANDLE=%p\n", h); } } while (Thread32Next (th, &te32)); } #endif #if 0 // Access denied here :? if (ContinueDebugEvent (pid, tid, DBG_CONTINUE) == 0) { r_sys_perror ("ContinueDebugEvent"); goto err_fork; } #endif /* catch create process event */ if (!WaitForDebugEvent (&de, 10000)) goto err_fork; /* check if is a create process debug event */ if (de.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT) { eprintf ("exception code 0x%04x\n", (ut32)de.dwDebugEventCode); goto err_fork; } if (th != INVALID_HANDLE_VALUE) CloseHandle (th); eprintf ("PID=%d\n", pid); eprintf ("TID=%d\n", tid); return pid; err_fork: eprintf ("ERRFORK\n"); TerminateProcess (pi.hProcess, 1); if (th != INVALID_HANDLE_VALUE) CloseHandle (th); return -1; }
static int fork_and_ptraceme(RIO *io, int bits, const char *cmd) { PROCESS_INFORMATION pi; STARTUPINFO si = { sizeof (si) }; DEBUG_EVENT de; int pid, tid; HANDLE th = INVALID_HANDLE_VALUE; if (!*cmd) return -1; setup_tokens (); char **argv = r_str_argv (cmd, NULL); // We need to build a command line with quoted argument and escaped quotes int cmd_len = 0; int i = 0; while (argv[i]) { char *current = argv[i]; int quote_count = 0; while ((current = strchr (current, '"'))) quote_count ++; cmd_len += strlen (argv[i]); cmd_len += quote_count; // The quotes will add one backslash each cmd_len += 2; // Add two enclosing quotes; i++; } cmd_len += i-1; // Add argc-1 spaces char *cmdline = malloc ((cmd_len + 1) * sizeof (char)); int cmd_i = 0; // Next character to write in cmdline i = 0; while (argv[i]) { if (i != 0) cmdline[cmd_i++] = ' '; cmdline[cmd_i++] = '"'; int arg_i = 0; // Index of current character in orginal argument while (argv[i][arg_i]) { char c = argv[i][arg_i]; if (c == '"') { cmdline[cmd_i++] = '\\'; } cmdline[cmd_i++] = c; arg_i++; } cmdline[cmd_i++] = '"'; i++; } cmdline[cmd_i] = '\0'; if (!CreateProcess (argv[0], cmdline, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi)) { r_sys_perror ("CreateProcess"); return -1; } free (cmdline); r_str_argv_free (argv); /* get process id and thread id */ pid = pi.dwProcessId; tid = pi.dwThreadId; #if 0 /* load thread list */ { HANDLE h; THREADENTRY32 te32; HANDLE WINAPI (*win32_openthread)(DWORD, BOOL, DWORD) = NULL; win32_openthread = (HANDLE WINAPI (*)(DWORD, BOOL, DWORD)) GetProcAddress (GetModuleHandle ("kernel32"), "OpenThread"); th = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, pid); if (th == INVALID_HANDLE_VALUE || !Thread32First(th, &te32)) r_sys_perror ("CreateToolhelp32Snapshot"); do { if (te32.th32OwnerProcessID == pid) { h = win32_openthread (THREAD_ALL_ACCESS, 0, te32.th32ThreadID); if (h == NULL) r_sys_perror ("OpenThread"); else eprintf ("HANDLE=%p\n", h); } } while (Thread32Next (th, &te32)); } #endif #if 0 // Access denied here :? if (ContinueDebugEvent (pid, tid, DBG_CONTINUE) == 0) { r_sys_perror ("ContinueDebugEvent"); goto err_fork; } #endif /* catch create process event */ if (!WaitForDebugEvent (&de, 10000)) goto err_fork; /* check if is a create process debug event */ if (de.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT) { eprintf ("exception code 0x%04x\n", (ut32)de.dwDebugEventCode); goto err_fork; } if (th != INVALID_HANDLE_VALUE) CloseHandle (th); eprintf ("PID=%d\n", pid); eprintf ("TID=%d\n", tid); return pid; err_fork: eprintf ("ERRFORK\n"); TerminateProcess (pi.hProcess, 1); if (th != INVALID_HANDLE_VALUE) CloseHandle (th); return -1; }