Breaking a launched process programmatically

时间:2016-10-20 20:04:24

标签: windows process visual-studio-debugging

I need to launch a process and then break it immediately so that it can be debugged using Visual Studio. I wrote this code after searching bits and pieces on the internet. The code is not working. The process gets launched, but it does not break and the calling code keeps waiting infinitely. If I don't launch the process in suspended mode, it runs immediately and exits.

I cannot modify the code of .exe that I am launching. I just have the .exe and symbols file.

Code:

#include<iostream>
#include<Windows.h>

using namespace std;

int main(int argc, char **argv)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    LPWSTR commandLine;
    int commandLength;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    if (argc != 2)
    {
        cout << "Usage: Launcher <commandline>" << endl;
        return 1;
    }

    commandLength = MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, NULL, 0);
    commandLine = new WCHAR[commandLength];
    MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, commandLine, commandLength);

    if (!CreateProcess(NULL, commandLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi))
    {
        cout << "CreateProcess failed (" << GetLastError() << ")." << endl;
        delete[] commandLine;
        return 1;
    }

    cout << pi.dwProcessId << " " << pi.dwThreadId << endl;

    delete[] commandLine;

    DebugBreakProcess(pi.hProcess);

    WaitForSingleObject(pi.hProcess, INFINITE);

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return 0;
}

What am I doing wrong here?

EDIT: This is the code after the suggestion by tyson.

#include<iostream>
#include<Windows.h>

using namespace std;

int main(int argc, char **argv)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    LPWSTR commandLine;
    int commandLength;
    HANDLE processHandle;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    if (argc != 2)
    {
        cout << "Usage: Launcher <commandline>" << endl;
        return 1;
    }

    commandLength = MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, NULL, 0);
    commandLine = new WCHAR[commandLength];
    MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, commandLine, commandLength);

    if (!CreateProcess(NULL, commandLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi))
    {
        cout << "CreateProcess failed (" << GetLastError() << ")." << endl;
        delete[] commandLine;
        return 1;
    }

    delete[] commandLine;

    processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId);
    if (processHandle == NULL)
    {
        cout << "Could not obtain handle (" << GetLastError() << ")." << endl;
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        return 2;
    }

    DebugActiveProcess(pi.dwProcessId);

    //ResumeThread(pi.hThread);

    WaitForSingleObject(pi.hProcess, INFINITE);

    CloseHandle(processHandle);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return 0;
}

2 个答案:

答案 0 :(得分:0)

编辑:基于更新代码的修订说明。

我看到三件事会有所帮助。首先,您必须获得具有正确访问权限的流程句柄。 CreateProcess返回的句柄没有正确的访问权限。关闭该流程句柄(pi.hProcesspi.hThread)并致电OpenProcess请求PROCESS_ALL_ACCESS。请记住,如果运行程序的用户帐户没有所需的权限,则可能会失败。

接下来,请确保首先使用上面获得的流程句柄调用DebugActiveProcess来启动调试。 (这可能需要也可能不需要。)

最后,在您编辑之后,我注意到您正在等待使用WaitForSingleObject的流程句柄。这具有等待进程终止的效果。相反,请使用WaitForDebugEvent

答案 1 :(得分:0)

你太努力了。系统已经做好充分准备,可以为任意进程启动调试器。您只需将Image File Execution Options适当地设置为launch the debugger automatically

供参考,以下是MSDN引用的说明:

  

设置应用程序以自动启动调试程序

     
      
  1. 启动注册表编辑器(regedit)。
  2.   
  3. 在注册表编辑器中,打开HKEY_LOCAL_MACHINE文件夹。
  4.   
  5. 导航至HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows NT \ currentversion \ image文件执行选项。
  6.   
  7. 映像文件执行选项文件夹中,找到要调试的应用程序的名称,例如 myapp.exe 。如果找不到要调试的应用程序:

         

    一个。右键单击图像文件执行选项文件夹,然后在快捷菜单上单击新密钥

         

    湾右键单击新密钥,然后在快捷菜单上单击重命名

         

    ℃。编辑应用程序名称的密钥名称; myapp.exe ,在此示例中。

  8.   
  9. 右键单击 myapp.exe 文件夹,然后在快捷菜单上单击新字符串值

  10.   
  11. 右键单击新字符串值,然后在快捷菜单上单击重命名
  12.   
  13. 将名称更改为debugger
  14.   
  15. 右键单击新字符串值,然后在快捷菜单上单击修改   将出现编辑字符串对话框。
  16.   
  17. 值数据框中,键入 vsjitdebugger.exe
  18.   
  19. 点击确定
  20.   
  21. 注册表菜单中,点击退出
  22.   
  23. 包含vsjitdebugger.exe的目录必须位于系统路径中。要将其添加到系统路径,请按照下列步骤操作:

         

    一个。在经典视图中打开控制面板,然后双击系统

         

    湾点击高级系统设置

         

    ℃。在系统属性中,点击高级标签。

         

    d。在高级标签上,点击环境变量

         

    即在环境变量对话框的系统变量下,选择路径,然后点击修改按钮。

         

    F。在编辑系统变量对话框中,将目录添加到变量值框中。使用分号将其与列表中的其他条目分开。

         

    克。点击确定以关闭编辑系统变量对话框。

         

    小时。点击确定以关闭环境变量对话框。

         

    我。点击确定关闭系统属性对话框。

  24.         

    现在,使用任何方法启动您的应用程序。 Visual Studio将启动并加载应用程序。