吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 915|回复: 5
收起左侧

[求助] 如果x64dbg不去创建MiniDump文件夹会怎样?

  [复制链接]
冥界3大法王 发表于 2023-4-22 10:13
还是代码说话吧
[C++] 纯文本查看 复制代码
#include <windows.h>
#pragma warning(push)
#pragma warning(disable:4091)
#include <dbghelp.h>
#pragma warning(pop)
#include <stdio.h>
#include <exception>
#include <signal.h>
#include "crashdump.h"

#define PROCESS_CALLBACK_FILTER_ENABLED 0x1

BOOL
(WINAPI*
 MiniDumpWriteDumpPtr)(
     _In_ HANDLE hProcess,
     _In_ DWORD ProcessId,
     _In_ HANDLE hFile,
     _In_ MINIDUMP_TYPE DumpType,
     _In_opt_ PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
     _In_opt_ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
     _In_opt_ PMINIDUMP_CALLBACK_INFORMATION CallbackParam
 );

BOOL
(WINAPI*
 SetProcessUserModeExceptionPolicyPtr)(
     _In_ DWORD PolicyFlags
 );

BOOL
(WINAPI*
 GetProcessUserModeExceptionPolicyPtr)(
     _Out_ LPDWORD PolicyFlags
 );

void CrashDumpInitialize()
{
    // Get handles to kernel32 and dbghelp
    HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
    HMODULE hDbghelp = LoadLibraryA("dbghelp.dll");

    if(hDbghelp)
        *(FARPROC*)&MiniDumpWriteDumpPtr = GetProcAddress(hDbghelp, "MiniDumpWriteDump");

    if(hKernel32)
    {
        *(FARPROC*)&SetProcessUserModeExceptionPolicyPtr = GetProcAddress(hKernel32, "SetProcessUserModeExceptionPolicy");
        *(FARPROC*)&GetProcessUserModeExceptionPolicyPtr = GetProcAddress(hKernel32, "GetProcessUserModeExceptionPolicy");
    }

    if(MiniDumpWriteDumpPtr)
        SetUnhandledExceptionFilter(CrashDumpExceptionHandler);

    // Ensure that exceptions are not swallowed when dispatching certain Windows
    // messages.
    //
    // [url]http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/[/url]
    // [url]https://support.microsoft.com/en-gb/kb/976038[/url]
    if(SetProcessUserModeExceptionPolicyPtr && GetProcessUserModeExceptionPolicyPtr)
    {
        DWORD flags = 0;

        if(GetProcessUserModeExceptionPolicyPtr(&flags))
            SetProcessUserModeExceptionPolicyPtr(flags & ~PROCESS_CALLBACK_FILTER_ENABLED);
    }

    // If not running under a debugger, redirect purecall, terminate, abort, and
    // invalid parameter callbacks to force generate a dump.
    if(!IsDebuggerPresent())
    {
        _set_purecall_handler(TerminateHandler);                // [url]https://msdn.microsoft.com/en-us/library/t296ys27.aspx[/url]
        _set_invalid_parameter_handler(InvalidParameterHandler);// [url]https://msdn.microsoft.com/en-us/library/a9yf33zb.aspx[/url]
        set_terminate(TerminateHandler);                        // [url]http://en.cppreference.com/w/cpp/error/set_terminate[/url]
        signal(SIGABRT, AbortHandler);                          // [url]https://msdn.microsoft.com/en-us/library/xdkz3x12.aspx[/url]
    }
}

void CrashDumpFatal(const char* Format, ...)
{
    char buffer[1024];
    va_list va;

    va_start(va, Format);
    vsnprintf_s(buffer, _TRUNCATE, Format, va);
    va_end(va);

    MessageBoxA(nullptr, buffer, "Error", MB_ICONERROR);
}

void CrashDumpCreate(EXCEPTION_POINTERS* ExceptionPointers)
{
    // Generate a crash dump file in the minidump directory
    wchar_t dumpFile[MAX_PATH];
    wchar_t dumpDir[MAX_PATH];

    if(!GetCurrentDirectoryW(ARRAYSIZE(dumpDir), dumpDir))
    {
        CrashDumpFatal("Unable to obtain current directory during crash dump");
        return;
    }

    wcscat_s(dumpDir, L"\\minidump");
    CreateDirectoryW(dumpDir, nullptr);

    // Append the name with generated timestamp
    SYSTEMTIME st;
    GetLocalTime(&st);

    swprintf_s(dumpFile, L"%ws\\dump-%02d%02d%04d_%02d%02d%02d%04d.dmp", dumpDir,
               st.wDay,
               st.wMonth,
               st.wYear,
               st.wHour,
               st.wMinute,
               st.wSecond,
               st.wMilliseconds);

    // Open the file
    HANDLE fileHandle = CreateFileW(dumpFile, GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);

    if(fileHandle == INVALID_HANDLE_VALUE)
    {
        CrashDumpFatal("Failed to open file path '%ws' while generating crash dump", dumpFile);
        return;
    }

    // Create the minidump with DbgHelp
    MINIDUMP_EXCEPTION_INFORMATION info;
    memset(&info, 0, sizeof(MINIDUMP_EXCEPTION_INFORMATION));

    info.ThreadId = GetCurrentThreadId();
    info.ExceptionPointers = ExceptionPointers;
    info.ClientPointers = TRUE;

    if(!MiniDumpWriteDumpPtr(GetCurrentProcess(), GetCurrentProcessId(), fileHandle, MiniDumpNormal, &info, nullptr, nullptr))
        CrashDumpFatal("MiniDumpWriteDump failed. Error: %u", GetLastError());

    // Close the file & done
    CloseHandle(fileHandle);
}

LONG CALLBACK CrashDumpExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo)
{
    // Any "exception" under 0x1000 is usually a failed remote procedure call (RPC)
    if(ExceptionInfo && ExceptionInfo->ExceptionRecord->ExceptionCode > 0x1000)
    {
        switch(ExceptionInfo->ExceptionRecord->ExceptionCode)
        {
        case DBG_PRINTEXCEPTION_C:  // OutputDebugStringA
        case 0x4001000A:            // OutputDebugStringW
        case STATUS_INVALID_HANDLE: // Invalid TitanEngine handle
        case 0x406D1388:            // SetThreadName
            return EXCEPTION_CONTINUE_SEARCH;
        }

        CrashDumpCreate(ExceptionInfo);
    }

    return EXCEPTION_CONTINUE_SEARCH;
}

void InvalidParameterHandler(const wchar_t* Expression, const wchar_t* Function, const wchar_t* File, unsigned int Line, uintptr_t Reserved)
{
    CrashDumpFatal("Invalid parameter passed to CRT function! Program will now generate an exception.\n\nFile: %ws\nFunction: %ws\nExpression: %ws",
                   Function ? Function : L"???",
                   File ? File : L"???",
                   Expression ? Expression : L"???");

    // RaiseException: avoid the use of throw/C++ exceptions and possible __fastfail calls
    RaiseException(0x78646267, EXCEPTION_NONCONTINUABLE, 0, nullptr);
}

void TerminateHandler()
{
    CrashDumpFatal("Process termination was requested in an unusual way. Program will now generate an exception.");

    // See InvalidParameterHandler()
    RaiseException(0x78646267, EXCEPTION_NONCONTINUABLE, 0, nullptr);
}

void AbortHandler(int Signal)
{
    TerminateHandler();
}


再来看下一段
[Asm] 纯文本查看 复制代码
/**
\file _global.cpp
\brief Implements the global class.
*/

#include "_global.h"
#include <objbase.h>
#include <shlobj.h>
#include <psapi.h>
#include "DeviceNameResolver/DeviceNameResolver.h"

/**
\brief x64dbg library instance.
*/
HINSTANCE hInst;

/**
\brief Number of allocated buffers by emalloc(). This should be 0 when x64dbg ends.
*/
static int emalloc_count = 0;
#ifdef ENABLE_MEM_TRACE
/**
\brief Path for debugging, used to create an allocation trace file on emalloc() or efree(). Not used.
*/
static char alloctrace[MAX_PATH] = "";
static std::unordered_map<void*, int> alloctracemap;
static CRITICAL_SECTION criticalSection;
#endif

/**
\brief Allocates a new buffer.
\param size The size of the buffer to allocate (in bytes).
\param reason The reason for allocation (can be used for memory allocation tracking).
\return Always returns a valid pointer to the buffer you requested. Will quit the application on errors.
*/
void* emalloc(size_t size, const char* reason)
{
    ASSERT_NONZERO(size);
#ifdef ENABLE_MEM_TRACE
    unsigned char* a = (unsigned char*)GlobalAlloc(GMEM_FIXED, size + sizeof(void*));
#else
    unsigned char* a = (unsigned char*)GlobalAlloc(GMEM_FIXED, size);
#endif //ENABLE_MEM_TRACE
    if(!a)
    {
        wchar_t sizeString[25];
        swprintf_s(sizeString, L"%p bytes", size);
        MessageBoxW(0, L"Could not allocate memory (minidump will be created)", sizeString, MB_ICONERROR);
        //__debugbreak();
        //ExitProcess(1);
    }
    emalloc_count++;
#ifdef ENABLE_MEM_TRACE
    EnterCriticalSection(&criticalSection);
    memset(a, 0, size + sizeof(void*));
    FILE* file = fopen(alloctrace, "a+");
    fprintf(file, "DBG%.5d:  alloc:%p:%p:%s:%p\n", emalloc_count, a, _ReturnAddress(), reason, size);
    fclose(file);
    alloctracemap[_ReturnAddress()]++;
    *(void**)a = _ReturnAddress();
    LeaveCriticalSection(&criticalSection);
    return a + sizeof(void*);
#else
    memset(a, 0, size);
    return a;
#endif //ENABLE_MEM_TRACE
}

/**
\brief Reallocates a buffer allocated with emalloc().
\param [in] Pointer to memory previously allocated with emalloc(). When NULL a new buffer will be allocated by emalloc().
\param size The new memory size.
\param reason The reason for allocation (can be used for memory allocation tracking).
\return Always returns a valid pointer to the buffer you requested. Will quit the application on errors.
*/
void* erealloc(void* ptr, size_t size, const char* reason)
{
    ASSERT_NONZERO(size);

    // Free the memory if the pointer was set (as per documentation).
    if(ptr)
        efree(ptr, reason);

    return emalloc(size, reason);
}

/**
\brief Free memory previously allocated with emalloc().
\param [in] Pointer to the memory to free.
\param reason The reason for freeing, should be the same as the reason for allocating.
*/
void efree(void* ptr, const char* reason)
{
    emalloc_count--;
#ifdef ENABLE_MEM_TRACE
    EnterCriticalSection(&criticalSection);
    char* ptr2 = (char*)ptr - sizeof(void*);
    FILE* file = fopen(alloctrace, "a+");
    fprintf(file, "DBG%.5d:   free:%p:%p:%s\n", emalloc_count, ptr, *(void**)ptr2, reason);
    fclose(file);
    if(alloctracemap.find(*(void**)ptr2) != alloctracemap.end())
    {
        if(--alloctracemap.at(*(void**)ptr2) < 0)
        {
            String str = StringUtils::sprintf("address %p, reason %s", *(void**)ptr2, reason);
            MessageBoxA(0, str.c_str(), "Freed memory more than once", MB_OK);
            __debugbreak();
        }
    }
    else
    {
        String str = StringUtils::sprintf("address %p, reason %s", *(void**)ptr2, reason);
        MessageBoxA(0, str.c_str(), "Trying to free const memory", MB_OK);
        __debugbreak();
    }
    LeaveCriticalSection(&criticalSection);
    GlobalFree(ptr2);
#else
    GlobalFree(ptr);
#endif //ENABLE_MEM_TRACE
}

void* json_malloc(size_t size)
{
#ifdef ENABLE_MEM_TRACE
    return emalloc(size, "json:ptr");
#else
    return emalloc(size);
#endif
}

void json_free(void* ptr)
{
#ifdef ENABLE_MEM_TRACE
    return efree(ptr, "json:ptr");
#else
    return efree(ptr);
#endif
}

/**
\brief Gets the number of memory leaks. This number is only valid in _dbg_dbgexitsignal().
\return The number of memory leaks.
*/
int memleaks()
{
#ifdef ENABLE_MEM_TRACE
    EnterCriticalSection(&criticalSection);
    auto leaked = false;
    for(auto & i : alloctracemap)
    {
        if(i.second != 0)
        {
            String str = StringUtils::sprintf("memory leak at %p : count %d", i.first, i.second);
            MessageBoxA(0, str.c_str(), "memory leak", MB_OK);
            leaked = true;
        }
    }
    if(leaked)
        __debugbreak();
    LeaveCriticalSection(&criticalSection);
#endif
    return emalloc_count;
}

#ifdef ENABLE_MEM_TRACE
/**
\brief Sets the path for the allocation trace file.
\param file UTF-8 filepath.
*/
void setalloctrace(const char* file)
{
    InitializeCriticalSection(&criticalSection);
    strcpy_s(alloctrace, file);
}
#endif //ENABLE_MEM_TRACE

/**
\brief Compares two strings without case-sensitivity.
\param a The first string.
\param b The second string.
\return true if the strings are equal (case-insensitive).
*/
bool scmp(const char* a, const char* b)
{
    if(!a || !b)
        return false;
    return !_stricmp(a, b);
}

/**
\brief Queries if a given file exists.
\param file Path to the file to check (UTF-8).
\return true if the file exists on the hard drive.
*/
bool FileExists(const char* file)
{
    DWORD attrib = GetFileAttributesW(StringUtils::Utf8ToUtf16(file).c_str());
    return (attrib != INVALID_FILE_ATTRIBUTES && !(attrib & FILE_ATTRIBUTE_DIRECTORY));
}

/**
\brief Queries if a given directory exists.
\param dir Path to the directory to check (UTF-8).
\return true if the directory exists.
*/
bool DirExists(const char* dir)
{
    DWORD attrib = GetFileAttributesW(StringUtils::Utf8ToUtf16(dir).c_str());
    return (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0);
}

/**
\brief Gets file path from a file handle.
\param hFile File handle to get the path from.
\param [in,out] szFileName Buffer of size MAX_PATH.
\return true if it succeeds, false if it fails.
*/
bool GetFileNameFromHandle(HANDLE hFile, char* szFileName)
{
    if(!hFile)
        return false;
    wchar_t wszFileName[MAX_PATH] = L"";
    if(!PathFromFileHandleW(hFile, wszFileName, _countof(wszFileName)))
        return false;
    strncpy_s(szFileName, MAX_PATH, StringUtils::Utf16ToUtf8(wszFileName).c_str(), _TRUNCATE);
    return true;
}

bool GetFileNameFromProcessHandle(HANDLE hProcess, char* szFileName)
{
    wchar_t wszDosFileName[MAX_PATH] = L"";
    wchar_t wszFileName[MAX_PATH] = L"";
    auto result = false;
    if(GetProcessImageFileNameW(hProcess, wszDosFileName, _countof(wszDosFileName)))
    {
        if(!DevicePathToPathW(wszDosFileName, wszFileName, _countof(wszFileName)))
            result = !!GetModuleFileNameExW(hProcess, 0, wszFileName, _countof(wszFileName));
        else
            result = true;
    }
    else
        result = !!GetModuleFileNameExW(hProcess, 0, wszFileName, _countof(wszFileName));
    if(result)
        strncpy_s(szFileName, MAX_PATH, StringUtils::Utf16ToUtf8(wszFileName).c_str(), _TRUNCATE);
    return result;
}

bool GetFileNameFromModuleHandle(HANDLE hProcess, HMODULE hModule, char* szFileName)
{
    wchar_t wszDosFileName[MAX_PATH] = L"";
    wchar_t wszFileName[MAX_PATH] = L"";
    auto result = false;
    if(GetMappedFileNameW(hProcess, hModule, wszDosFileName, _countof(wszDosFileName)))
    {
        if(!DevicePathToPathW(wszDosFileName, wszFileName, _countof(wszFileName)))
            result = !!GetModuleFileNameExW(hProcess, hModule, wszFileName, _countof(wszFileName));
        else
            result = true;
    }
    else
        result = !!GetModuleFileNameExW(hProcess, hModule, wszFileName, _countof(wszFileName));
    if(result)
        strncpy_s(szFileName, MAX_PATH, StringUtils::Utf16ToUtf8(wszFileName).c_str(), _TRUNCATE);
    return result;
}

/**
\brief Get a boolean setting from the configuration file.
\param section The section of the setting (UTF-8).
\param name The name of the setting (UTF-8).
\return true if the setting was set and equals to true, otherwise returns false.
*/
bool settingboolget(const char* section, const char* name)
{
    duint setting;
    if(!BridgeSettingGetUint(section, name, &setting))
        return false;
    if(setting)
        return true;
    return false;
}

/**
\brief Query if x64dbg is running in Wow64 mode.
\return true if running in Wow64, false otherwise.
*/
bool IsWow64()
{
    BOOL bIsWow64Process = FALSE;
    //x64dbg supports WinXP SP3 and later only, so ignore the GetProcAddress crap :D
    IsWow64Process(GetCurrentProcess(), &bIsWow64Process);
    return !!bIsWow64Process;
}

//Taken from: [url]http://www.cplusplus.com/forum/windows/64088/[/url]
//And: [url]https://codereview.stackexchange.com/a/2917[/url]
bool ResolveShortcut(HWND hwnd, const wchar_t* szShortcutPath, wchar_t* szResolvedPath, size_t nSize)
{
    if(szResolvedPath == NULL)
        return SUCCEEDED(E_INVALIDARG);

    //Initialize COM stuff
    if(!SUCCEEDED(CoInitialize(NULL)))
        return false;

    //Get a pointer to the IShellLink interface.
    IShellLinkW* psl = NULL;
    HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl);
    if(SUCCEEDED(hres))
    {
        //Get a pointer to the IPersistFile interface.
        IPersistFile* ppf = NULL;
        hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
        if(SUCCEEDED(hres))
        {
            //Load the shortcut.
            hres = ppf->Load(szShortcutPath, STGM_READ);

            if(SUCCEEDED(hres))
            {
                //Resolve the link.
                hres = psl->Resolve(hwnd, 0);

                if(SUCCEEDED(hres))
                {
                    //Get the path to the link target.
                    wchar_t linkTarget[MAX_PATH];
                    hres = psl->GetPath(linkTarget, _countof(linkTarget), NULL, SLGP_RAWPATH);

                    //Expand the environment variables.
                    wchar_t expandedTarget[MAX_PATH];
                    auto expandSuccess = !!ExpandEnvironmentStringsW(linkTarget, expandedTarget, _countof(expandedTarget));

                    if(SUCCEEDED(hres) && expandSuccess)
                    {
                        wcscpy_s(szResolvedPath, nSize, expandedTarget);
                    }
                }
            }

            //Release the pointer to the IPersistFile interface.
            ppf->Release();
        }

        //Release the pointer to the IShellLink interface.
        psl->Release();
    }

    //Uninitialize COM stuff
    CoUninitialize();
    return SUCCEEDED(hres);
}

void WaitForThreadTermination(HANDLE hThread, DWORD timeout)
{
    WaitForSingleObject(hThread, timeout);
    CloseHandle(hThread);
}

void WaitForMultipleThreadsTermination(const HANDLE* hThread, int count, DWORD timeout)
{
    WaitForMultipleObjects(count, hThread, TRUE, timeout);
    for(int i = 0; i < count; i++)
        CloseHandle(hThread[i]);
}


发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 冥界3大法王 发表于 2023-4-22 10:15
或换句话说MiniDump 和 memdumps 这样的文件夹起到何作用?
也许是我不会看 用windbg也不能理解 MiniDump 崩溃在何问题上?
Link_Stark 发表于 2023-4-22 10:26
我记得其中有一个是存储调试工程的来着,保存之后文件夹中就会出现内容
 楼主| 冥界3大法王 发表于 2023-4-22 10:40
Link_Stark 发表于 2023-4-22 10:26
我记得其中有一个是存储调试工程的来着,保存之后文件夹中就会出现内容

你说的是跟踪窗口保存的那个吧?
我说的是崩溃后产生的
年-月-日.dump文件
yp17792351859 发表于 2023-4-23 13:32
冥界3大法王 发表于 2023-4-22 10:40
你说的是跟踪窗口保存的那个吧?
我说的是崩溃后产生的
年-月-日.dump文件

用windbg 配合 pdb 文件  定位异常原因
 楼主| 冥界3大法王 发表于 2023-4-23 20:16
yp17792351859 发表于 2023-4-23 13:32
用windbg 配合 pdb 文件  定位异常原因

定位了,日了一个文件,就编译通过了。
看来这dump文件删除的想法也不对。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 01:04

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表