Problems with opening a process with DEBUG flags

2k views Asked by At

I'm trying to open a process with my debugger using CreateProcess with the DEBUG_PROCESS and DEBUG_ONLY_THIS_PROCESS flags and the the process is opened, but then when I try to call SymInitialize with the handle I receive, it fails.

This is my code:

#include <windows.h> 
#include <stdio.h> 
#include <dbghelp.h> 
#pragma (lib, "dbghelp.lib"); 

bool EnablePrivilege(LPCTSTR lpszPrivilegeName, BOOL bEnable)  
{  
    HANDLE hToken;  
    TOKEN_PRIVILEGES    tp;  
    LUID luid;  
    bool ret;  

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ, &hToken))  
        return FALSE;  

    if (!LookupPrivilegeValue(NULL, lpszPrivilegeName, &luid))  
        return FALSE;  

    tp.PrivilegeCount           = 1;  
    tp.Privileges[0].Luid       = luid;  
    tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;  

    ret = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);  
    CloseHandle(hToken);  

    return ret;  
} 

void main() 
{ 
    EnablePrivilege(SE_DEBUG_NAME, TRUE); 

    STARTUPINFOA startInfo; 
    PROCESS_INFORMATION processInfo; 
    ZeroMemory( &startInfo, sizeof(startInfo) ); 
    startInfo.cb = sizeof(startInfo); 
    ZeroMemory( &processInfo, sizeof(processInfo) ); 
    DWORD creationFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION; 
    const char* comLine = "Some process path and name"; 

//     Start the child process.  
    if( CreateProcessA( NULL,   // No module name (use command line) 
       (LPSTR)comLine, //argv[1],        // Command line 
        NULL,           // Process handle not inheritable 
        NULL,           // Thread handle not inheritable 
        FALSE,          // Set handle inheritance to FALSE 
        creationFlags,              // No creation flags 
        NULL,           // Use parent's environment block 
        NULL,           // Use parent's starting directory  
        &startInfo,            // Pointer to STARTUPINFO structure 
        &processInfo )           // Pointer to PROCESS_INFORMATION structure 
     == false )  
    { 
        printf("FAIL!"); 
return; 
    } 

    SetLastError(0); 
    bool ok = SymInitialize(processInfo.hProcess, NULL, true); 
    int err = GetLastError(); 

} 

If I call CreateProcess with no creation flags, symInitialize succeed.
What am I doing wrong?

2

There are 2 answers

1
j_kubik On BEST ANSWER

Your error is result of calling MAKE_HRESULT macro as

MAKE_HRESULT(ERROR_SEVERITY_ERROR, FACILITY_NULL, ERROR_INVALID_DATA)

So your error code is not trash. Documentaion doesn't say what kind of data might be invalid in this context. I will try to see what exactly is causing the problem.

EDIT:

This code works for me

#include <windows.h>
#include <stdio.h>
#include <dbghelp.h>
#include <WinError.h>

bool EnablePrivilege(LPCTSTR lpszPrivilegeName, BOOL bEnable)
{
    HANDLE hToken;
    TOKEN_PRIVILEGES    tp;
    LUID luid;
    bool ret;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ, &hToken))
    return FALSE;

    if (!LookupPrivilegeValue(NULL, lpszPrivilegeName, &luid))
    return FALSE;

    tp.PrivilegeCount           = 1;
    tp.Privileges[0].Luid       = luid;
    tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;

    ret = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
    CloseHandle(hToken);

    return ret;
}

void main()
{
    EnablePrivilege(SE_DEBUG_NAME, TRUE);

    STARTUPINFOA startInfo;
    PROCESS_INFORMATION processInfo;
    ZeroMemory( &startInfo, sizeof(startInfo) );
    startInfo.cb = sizeof(startInfo);
    ZeroMemory( &processInfo, sizeof(processInfo) );
    DWORD creationFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION;
    const char* comLine = "C:\\Windows\\Notepad.exe";

//     Start the child process.
    if( CreateProcessA( NULL,   // No module name (use command line)
       (LPSTR)comLine,// argv[1],        // Command line
    NULL,           // Process handle not inheritable
    NULL,           // Thread handle not inheritable
    FALSE,          // Set handle inheritance to FALSE
    creationFlags,              // No creation flags
    NULL,           // Use parent's environment block
    NULL,           // Use parent's starting directory
    &startInfo,            // Pointer to STARTUPINFO structure
    &processInfo )           // Pointer to PROCESS_INFORMATION structure
     == false )
    {
    printf("FAIL!");
return;
    }

    SetLastError(0);
    bool ok = SymInitialize(processInfo.hProcess, NULL, true);
    HRESULT err = HRESULT_FROM_WIN32(GetLastError());
}

I don't know why it doesn't for you - I am running windows XP, it might be a difference. For me SymInitialize returns true, and GetLastError returns 0x800700cb, which means only that it didn't found evirnment variable pointing it to directory with symbol files.

This might be stupid question, but perhaps you are missing some debugging libraries in your system? Have you tried installing eg. Debugging Tools for Windows? I would reccomend 'Download Debugging Tools from the Windows SDK' option - read the description. I guess every programming IDE around would install it for you or have you install it before debugging anything, but it's always best to check.

0
uri.z On

When process is just created with DEBUG_PROCESS flag no symbols are loaded. It is required to wait for some LOAD_DLL_DEBUG_EVENT and then call SymInitialize().