元始天尊 发表于 2015-11-18 23:54:57

实现windbg查看错误信息插件

vs有个实用程序是 错误查找,可以显示错误值信息,windbg也有,然而却不好使,内核错误显示不出,不明白为啥越能提供方便的功能微软越做不好

下面是我写的插件用例:
0:000> !err
usage: !err [-c code][-l]
        Default code is $retreg;        l stands for Api LastError
example:!err -c C0000001                !err        !err -l
Kernel ErrorCode:
        MessageId:STATUS_UNSUCCESSFUL
        MesageText:{Operation Failed} The requested operation was unsuccessful.
0:000> reax=c0000002
0:000> !err
usage: !err [-c code][-l]
        Default code is $retreg;        l stands for Api LastError
example:!err -c C0000001                !err        !err -l
Kernel ErrorCode:
        MessageId:STATUS_NOT_IMPLEMENTED
        MesageText:{Not Implemented} The requested operation is not implemented.
0:000> !err -c 5
usage: !err [-c code][-l]
        Default code is $retreg;        l stands for Api LastError
example:!err -c C0000001                !err        !err -l
Windows ErrorCode:
        MessageId:ERROR_ACCESS_DENIED
        MesageText:Access is denied.
0:000> eb @@(&(_TEB*)(@$teb)->LastErrorValue) 6
0:000> !err -l
usage: !err [-c code][-l]
        Default code is $retreg;        l stands for Api LastError
example:!err -c C0000001                !err        !err -l
Windows ErrorCode:
        MessageId:ERROR_INVALID_HANDLE
        MesageText:The handle is invalid.

注意,!err可以根据参数解析指定错误号、GetLastError()错误号、Eax错误号



ERRORINFO data1[]=//应用层
{
        {0, "ERROR_SUCCESS", "The operation completed successfully."},
        {1, "ERROR_INVALID_FUNCTION", "Incorrect function."},    // dderror
        {2, "ERROR_FILE_NOT_FOUND", "The system cannot find the file specified."},
        {3, "ERROR_PATH_NOT_FOUND", "The system cannot find the path specified."},
        {4, "ERROR_TOO_MANY_OPEN_FILES", "The system cannot open the file."}
        。。。。。。。。。。。。。。。。。
ERRORINFO data2[]=//内核层
{
        {0x00000000, "STATUS_WAIT_0", "STATUS_WAIT_0"},
        {0x00000001, "STATUS_WAIT_1", "STATUS_WAIT_1"},
        {0x00000002, "STATUS_WAIT_2", "STATUS_WAIT_2"},
        {0x00000003, "STATUS_WAIT_3", "STATUS_WAIT_3"},
        {0x0000003F, "STATUS_WAIT_63", "STATUS_WAIT_63"},
        {0x00000080, "STATUS_ABANDONED", "The success status codes 128 - 191 are reserved for wait completion status with an abandoned mutant object."},
        {0x00000080, "STATUS_ABANDONED_WAIT_0", "STATUS_ABANDONED_WAIT_0"},
        {0x000000BF, "STATUS_ABANDONED_WAIT_63", "STATUS_ABANDONED_WAIT_63"},

#include "DbgEng.h"
#include "errors.h"
#include <windows.h>

int GetOnlyParamVal(PCSTR& begin, PCSTR& end);

HRESULT CALLBACK
err(PDEBUG_CLIENT pDebugClient, PCSTR args)
{
        IDebugControl* pDebugControl;

        if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugControl), (void **)&pDebugControl)))
        {
                HRESULT result = 0;
                pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "usage: !err [-c code][-l]\n");//不指定参数则自动判断内核态用户态错误
                pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "\tDefault code is $retreg;        l stands for Api LastError\n");
                pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "example:!err -c C0000001                !err        !err -l\n");

                ULONG ErrorCode = -1;
                DEBUG_VALUE value;

                PCSTR a;
                if (a = strstr(args, "-c"))
                {
                        char exp="";
                        a += 2;
                        PCSTR begin = a, end = a;
                        int len = GetOnlyParamVal(begin, end);
                        strncpy(exp, begin, len);
                        exp = '\0';
                        if (SUCCEEDED(pDebugControl->Evaluate(exp, DEBUG_VALUE_INT32, &value, NULL)))
                        {
                                ErrorCode = value.I32;
                        }
                }
                else if (strstr(args, "-l"))
                {
                        if (SUCCEEDED(pDebugControl->Evaluate("@@((_TEB*)(@$teb)->LastErrorValue)", DEBUG_VALUE_INT32, &value, NULL)))
                        {
                                ErrorCode = value.I32;
                        }
                }
                else
                {
                        if (SUCCEEDED(pDebugControl->Evaluate("$retreg ", DEBUG_VALUE_INT32, &value, NULL)))
                        {
                                ErrorCode = value.I32;
                        }
                }

                if (ErrorCode != -1)
                {
                        int i;
                        for (i = 0; i < sizeof(data1) / sizeof(data1); i++)
                        {
                                if (ErrorCode == data1.ErrorCode)
                                {
                                        pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "Windows ErrorCode:\n\tMessageId:%s\n\tMesageText:%s\n",
                                                data1.MessageId, data1.MessageText);
                                }
                        }
                        for (i = 0; i < sizeof(data2) / sizeof(data2); i++)
                        {
                                if (ErrorCode == data2.ErrorCode)
                                {
                                        pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "Kernel ErrorCode:\n\tMessageId:%s\n\tMesageText:%s\n",
                                                data2.MessageId, data2.MessageText);
                                }
                        }
                }
                else
                {
                        pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "Cannot find this error value!\n");
                }
        }
        pDebugControl->Release();
        return S_OK;
}
页: [1]
查看完整版本: 实现windbg查看错误信息插件