2

I am trying to dump a process, say calc.exe

When I run my program I get

Program received signal SIGSEGV, Segmentation fault.
0x0000000000401640 in MiniDumpWriteDump ()

Here is the code

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

int main(){
    HANDLE hFile = CreateFileA(
        "calc.dmp",
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );

    DWORD procID = 196;

    HANDLE hProc = OpenProcess(
        PROCESS_ALL_ACCESS,
        FALSE,
        procID
    );

    MiniDumpWriteDump(
        hProc,
        procID,
        hFile,
        MiniDumpWithFullMemory,
        NULL,
        NULL,
        NULL
    );

    CloseHandle(hFile);
}
Zombo
  • 1
  • 62
  • 391
  • 407

1 Answers1

1

You example works on 32 bit and 64 bit windows, but it has to be compiled with the same "bitness" (64 bit on 64 bit Windows, 32 bit on 32 bit Windows).

I only added a window enumeration and a way to supply a procID as an argument. The functions that return values should be checked for errors.

#include <windows.h>
#include <dbghelp.h>
#include <stdio.h>
#define TRYTO(b,a) if (!(a)) { \
fprintf(stderr,"Unable to " b "\n"); exit(1);}
static BOOL CALLBACK FunkyCallback(HWND hWnd, LPARAM lParam ){
    char b[100]; RECT Rect;
    DWORD pid;
    if(!GetParent(hWnd)){
        GetWindowText(hWnd, b, 99); GetWindowRect(hWnd,&Rect);
        GetWindowThreadProcessId(hWnd, &pid);
        printf("%li: %s left:%li top:%li\n",pid,b,Rect.left,Rect.top);
    }
    return TRUE;
}
int main(int argc, char ** argv){
    HANDLE hFile;
    DWORD procID;
    HANDLE hProc;
    if (argc > 1){
        TRYTO("create file",(
            hFile = CreateFile(
                "proc.dmp",
                GENERIC_READ | GENERIC_WRITE,
                FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                NULL,
                CREATE_ALWAYS,
                FILE_ATTRIBUTE_NORMAL,
                NULL
            ))!=INVALID_HANDLE_VALUE);
        DWORD procID = atoi(argv[1]);
        TRYTO("open process",(
            hProc = OpenProcess(
                PROCESS_ALL_ACCESS,
                FALSE,
                procID
            )));
        TRYTO("write dump",(
            MiniDumpWriteDump(
                hProc,
                procID,
                hFile,
                MiniDumpNormal,
                NULL,
                NULL,
                NULL
            )));
        fprintf(stderr,"Successfully created proc.dmp.\n",argv[0]);
        CloseHandle(hFile);
    } else { 
        EnumChildWindows(GetDesktopWindow(),FunkyCallback, 0);
        fprintf(stderr,"Usage: %s procID\n",argv[0]);
    }
}

Compilation notes

Tested on Linux with Mingw64. Fedora Linux has packages here. I copied the 64 bit dbghelp.dll from Windows Server 2008 Windows/system32 to the source folder. objdump -f can confirm whether the dll is 64 or 32 bit. The compile line was something like

/usr/bin/x86_64-w64-mingw32-gcc dmp.c -L. -l dbghelp -o dmp.exe

Links

Community
  • 1
  • 1
hellork
  • 420
  • 2
  • 5
  • I tried it on WS 2008 64 bit and it dumps an empty file, but it does not crash. Then I made this http://pastebin.com/j3UJKKRT which enumerates a bunch of proc ID's when run without arguments. I still could not get it to crash, but it only creates a valid dump file on win32. Perhaps it needs to be compiled as 64 bit. – hellork Apr 10 '12 at 00:26
  • Confirmed. It does need to be compiled as 64 bit. It works on Windows Server 2008 64 bit when linked against 64 bit dbghelp.dll (located in Windows\system32 folder). Compiled with mingw64. Had to set up a new build environment to do it. – hellork Apr 10 '12 at 02:33
  • Bad style, not checking return values and not enabling privs ... Win9x style in the NT era. Should IMO be improved. – 0xC0000022L Apr 10 '12 at 02:54