3

I'm trying to create a service with the goal of monitor the applications created by my company.

When the app gets the state of No responding, the service have to generate a a dump with MiniDumpWriteDump.

The problem is: when using HANDLE of another process, the MiniDumpWriteDump doesn't work. The .dmp file stays empty.

GetLastError returns 0xD0000008 (3489660936)

That function is to get HANDLE by pid:

void CDumpGenerator::FindAndSetHandle()
{
    HANDLE hProcessSnap;
    HANDLE hProcess;
    PROCESSENTRY32 pe32;

    EnableDebugPriv();

    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
        return;

    pe32.dwSize = sizeof(PROCESSENTRY32);

    if (!Process32First(hProcessSnap, &pe32))
    {
        CloseHandle(hProcessSnap);

        return;
    }

    do
    {
        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_DUP_HANDLE, FALSE, pe32.th32ProcessID);

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

        if (pe32.th32ProcessID == this->pid)
        {
            this->processHandle = hProcess;

            break;
        }
    } while (Process32Next(hProcessSnap, &pe32));

    CloseHandle(hProcessSnap);
}

EnableDebugPriv:

void EnableDebugPriv()
{
    HANDLE hToken;
    LUID luid;
    TOKEN_PRIVILEGES tkp;

    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);

    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = luid;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    AdjustTokenPrivileges(hToken, false, &tkp, sizeof(tkp), NULL, NULL);

    CloseHandle(hToken);
}

And i'm calling MiniDumpWriteDump this way:

auto dumped = MiniDumpWriteDump(
    this->processHandle,
    this->pid,
    hFile,
    MINIDUMP_TYPE(MiniDumpNormal | MiniDumpWithThreadInfo |  MiniDumpWithProcessThreadData | MiniDumpWithFullMemoryInfo),
    nullptr,
    &userStream,
    nullptr);

When I change this->processHandle to GetCurrentProcess() works fine.

Handle being set:

enter image description here

Here is the GetLastError()

enter image description here

Kevin Kouketsu
  • 786
  • 6
  • 20
  • 1
    Improve the error reporting so we don't have to guess why "it didn't work". Call GetLastError() when it returns FALSE. Also run SysInternals' ProcDump utility to see if it has any better luck, that localizes the problem. – Hans Passant Nov 23 '18 at 12:51
  • @HansPassant The `GetLastError` returns me 0xD0000008. I didn't knew about ProcDump. I will see. – Kevin Kouketsu Nov 23 '18 at 12:56
  • That's obscure, but looks a lot like an "invalid handle" error. It is notable that FindAndSetHandle() can't tell you that it failed to find the process, that's not good. Could be the hFile as well. – Hans Passant Nov 23 '18 at 13:18
  • @HansPassant I change to `GetCurrentProcess` works and all dump is wrote so I think it's not `CreateFileA`. When I was debugging line by line on `FindAndSetHandle` I see the processHandle being setted. – Kevin Kouketsu Nov 23 '18 at 13:22
  • Another bug in FindAndSetHandle() is that it generates a bad handle value when OpenProcess() failed. Do take care of the basics, cuts down on the guessing. – Hans Passant Nov 23 '18 at 13:44
  • But when I know if OpenProcess fails if I don't get any throw or anything different. I have an unmanaged class in C# that does exactly what C ++ does but it works normally using OpenProcess. – Kevin Kouketsu Nov 24 '18 at 13:20

1 Answers1

1

I just solved the problem removing this part

hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_DUP_HANDLE, FALSE, pe32.th32ProcessID);

// This close handle
if (hProcess != NULL)
    CloseHandle(hProcess);

It's a simple thing that went unseen. So we need close handle on other part of code like destructor or anything else.

Kevin Kouketsu
  • 786
  • 6
  • 20