dmp文件自动分析
阅读原文时间:2023年07月14日阅读:1

dmp文件的分析,可以借助各种工具,比如WinDbg, CDB , NTSD,KD等。Windbg提供了窗口接口,而CDB , NTSD是基于命令行的工具,它们都使用了同样的调试引擎Dbgeng.dll,该调试引擎就是 “Windows 调试程序”。

dbgeng.dll 可以在基于x86,x64 或ARM的处理器上运行,并且可以调试在那些相同体系结构上运行的代码。

dbgeng.dll 的使用:

out.hpp

#ifndef __OUT_HPP__
#define __OUT_HPP__

#include

class StdioOutputCallbacks : public IDebugOutputCallbacks
{
public:
// IUnknown.
STDMETHOD(QueryInterface)(
THIS_
_In_ REFIID InterfaceId,
_Out_ PVOID* Interface
);
STDMETHOD_(ULONG, AddRef)(
THIS
);
STDMETHOD_(ULONG, Release)(
THIS
);

// IDebugOutputCallbacks.  
STDMETHOD(Output)(  
    THIS\_  
    \_In\_ ULONG Mask,  
    \_In\_ PCSTR Text  
    );  

};

extern StdioOutputCallbacks g_OutputCb;

#endif // #ifndef __OUT_HPP__

out.cpp

#include
#include
#include
#include "out.hpp"

StdioOutputCallbacks g_OutputCb;
FILE *fp = NULL;

STDMETHODIMP
StdioOutputCallbacks::QueryInterface(
THIS_
_In_ REFIID InterfaceId,
_Out_ PVOID* Interface
)
{
if (!fp) {
fp = fopen("D:/ZZZ/analyze.txt", "w+");
}

\*Interface = NULL;  
if (IsEqualIID(InterfaceId, \_\_uuidof(IUnknown)) ||  
    IsEqualIID(InterfaceId, \_\_uuidof(IDebugOutputCallbacks)))  
{  
    \*Interface = (IDebugOutputCallbacks \*)this;  
    AddRef();  
    return S\_OK;  
}  
else  
{  
    return E\_NOINTERFACE;  
}  

}

STDMETHODIMP_(ULONG)
StdioOutputCallbacks::AddRef(
THIS
)
{
// This class is designed to be static so
// there's no true refcount.
return 1;
}

STDMETHODIMP_(ULONG)
StdioOutputCallbacks::Release(
THIS
)
{
// This class is designed to be static so
// there's no true refcount.
//fclose(fp);
return 0;
}

STDMETHODIMP
StdioOutputCallbacks::Output(
THIS_
_In_ ULONG Mask,
_In_ PCSTR Text
)
{
UNREFERENCED_PARAMETER(Mask);
//fputs(Text, fp);
fputs(Text, stdout);
return S_OK;
}

main.cpp

#include "out.hpp"

#include
#include
#include
#include
#include

PSTR g_DumpFile;
IDebugClient* g_Client;
IDebugControl* g_Control;
IDebugSymbols3* g_Symbols3;

void Exit(int Code, _In_ _Printf_format_string_ PCSTR Format, …)
{
// Clean up any resources.
if (g_Symbols3 != NULL)
{
g_Symbols3->Release();
}

if (g\_Control != NULL) {  
    g\_Control->Release();  
}

if (g\_Client != NULL)  
{  
    g\_Client->SetOutputCallbacks(NULL);  
    g\_Client->EndSession(DEBUG\_END\_PASSIVE);  
    g\_Client->Release();  
}

// Output an error message if given.  
if (Format != NULL)  
{  
    va\_list Args;  
    va\_start(Args, Format);  
    vfprintf(stderr, Format, Args);  
    va\_end(Args);  
}  
exit(Code);  

}

void CreateInterfaces(void)
{
HRESULT Status;

// Start things off by getting an initial interface from  
// the engine.  This can be any engine interface but is  
// generally IDebugClient as the client interface is  
// where sessions are started.  
if ((Status = DebugCreate(\_\_uuidof(IDebugClient),  
    (void\*\*)&g\_Client)) != S\_OK)  
{  
    Exit(1, "DebugCreate failed, 0x%X\\n", Status);  
}

// Query for some other interfaces that we'll need.  
if ((Status = g\_Client->QueryInterface(\_\_uuidof(IDebugControl),  
    (void\*\*)&g\_Control)) != S\_OK ||  
    (Status = g\_Client->QueryInterface(\_\_uuidof(IDebugSymbols3),  
    (void\*\*)&g\_Symbols3)) != S\_OK)  
{  
    Exit(1, "QueryInterface failed, 0x%X\\n", Status);  
}  

}

//typedef _Null_terminated_ CHAR *TTPSTR;
void ParseCommandLine(int Argc, _In_reads_(Argc) PSTR* Argv)
{
int i;
while (--Argc > 0)
{
Argv++;
if (!strcmp(Argv[0], "-z"))
{
Argv++;
Argc--;
if (Argc > 0)
{
g_DumpFile = Argv[0];
}
else
{
Exit(1, "-z missing argument\n");
}
}
else
{
//Exit(1, "Unknown command line argument '%s'\n", Argv[0]);
}
}

if (g\_DumpFile == NULL)  
{  
    Exit(1, "No dump file specified, use -z <file>\\n");  
}  

}

void ApplyCommandLineArguments(void)
{
HRESULT Status;

// Install output callbacks so we get any output that the  
// later calls produce.  
if ((Status = g\_Client->SetOutputCallbacks(&g\_OutputCb)) != S\_OK)  
{  
    Exit(1, "SetOutputCallbacks failed, 0x%X\\n", Status);  
}

// Everything's set up so open the dump file.  
if ((Status = g\_Client->OpenDumpFile(g\_DumpFile)) != S\_OK)  
{  
    Exit(1, "OpenDumpFile failed, 0x%X\\n", Status);  
}

// Finish initialization by waiting for the event that  
// caused the dump.  This will return immediately as the  
// dump file is considered to be at its event.  
if ((Status = g\_Control->WaitForEvent(DEBUG\_WAIT\_DEFAULT,  
    INFINITE)) != S\_OK)  
{  
    Exit(1, "WaitForEvent failed, 0x%X\\n", Status);  
}

// Everything is now initialized and we can make any  
// queries we want.  

}

void DumpStack(void)
{
HRESULT Status;
DEBUG_STACK_FRAME Frames[3] = { 0 };
ULONG Filled;

g\_Symbols3->SetScopeFromStoredEvent();

if (Frames == NULL)  
{  
    Exit(1, "Unable to allocate stack frames\\n");  
}

if ((Status = g\_Control->  
    GetStackTrace(0, 0, 0,  
        Frames, 3, &Filled)) != S\_OK)  
{  
    Exit(1, "GetStackTrace failed, 0x%X\\n", Status);  
}

printf("\\nFirst %d frames of the call stack:\\n", Filled);

//// Print the call stack.  
if ((Status = g\_Control->  
    OutputStackTrace(DEBUG\_OUTCTL\_ALL\_CLIENTS, Frames,  
        Filled, DEBUG\_STACK\_ARGUMENTS | DEBUG\_STACK\_SOURCE\_LINE |  
        DEBUG\_STACK\_FRAME\_ADDRESSES |  
        DEBUG\_STACK\_COLUMN\_NAMES |  
        DEBUG\_STACK\_FRAME\_NUMBERS)) != S\_OK)  
{  
    Exit(1, "OutputStackTrace failed, 0x%X\\n", Status);  
}  

}

int main(int argc, char *argv[])
{
CreateInterfaces();
ParseCommandLine(argc, argv);
ApplyCommandLineArguments();
DumpStack();
return 0;
}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章