首页
社区
课程
招聘
[旧帖] 64位 win7 解析pdb失败,跟踪之后找到了错误地址,但是找不出错误原因 0.00雪花
发表于: 2014-9-30 10:02 4385

[旧帖] 64位 win7 解析pdb失败,跟踪之后找到了错误地址,但是找不出错误原因 0.00雪花

2014-9-30 10:02
4385
源码在此,

#include "stdafx.h"
#include "Data.h"
#include "DataDlg.h"
#include "afxdialogex.h"
#include <winioctl.h>
#include <winsvc.h>
#include <DbgHelp.h>
#include "ntdll.h"

#pragma comment(lib, "DbgHelp.lib")
#pragma comment(lib, "ImageHlp.lib")

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

int __cdecl NewDbgPrint(char* _Format, ...);

#define STATUS_UNSUCCESSFUL              ((NTSTATUS)0xC0000001L)

typedef struct _SYSTEM_MODULE
{
        ULONG        Reserved1[2];
        ULONG        Reserved2[2];
        PVOID        Base;
        ULONG        Size;
        ULONG        Flags;
        USHORT        Index;
        USHORT        Unknown;
        USHORT        LoadCount;
        USHORT        ModuleNameOffset;
        CHAR        ImageName[256];
} SYSTEM_MODULE, *PSYSTEM_MODULE;

typedef struct _SYSTEM_MODULE_INFORMATION
{
        ULONG                        uCount;
        SYSTEM_MODULE        aSM[];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

typedef struct tagSymbolsInfo
{

        ULONG64 lpDbgkCreateThread;
        ULONG64 lpKiDispatchException;
        ULONG64 lpDbgkpQueueMessage;
        ULONG64 lpDbgkForwardException;
        ULONG64 lpPspExitThread;
        ULONG64 lpDbgkExitThread;
        ULONG64 lpPsGetProcessDebugPort;
        ULONG64 lpDbgkClearProcessDebugObject;
        ULONG64 lpDbgkpMarkProcessPeb;
        ULONG64 lpDbgkpCloseObject;
        ULONG64 lpPspProcessDelete;
        ULONG64 lpDbgkExitProcess;
        ULONG64 lpDbgkMapViewOfSection;
        ULONG64 lpDbgkUnMapViewOfSection;
        ULONG64 lpDbgkpSetProcessDebugObject;

}SYMBOLS_INFO, *PSYMBOLS_INFO;

HWND hwnd;
SYMBOLS_INFO        StSymbolsInfo = { 0 };
t_NtQuerySystemInformation _NtQuerySystemInformation = 0;

DWORD WINAPI ThreadFunction(LPVOID lpParamter);

#define IOCTL_STOP CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ANY_ACCESS)

// CDataDlg 对话框

CDataDlg::CDataDlg(CWnd* pParent /*=NULL*/)
        : CDialogEx(CDataDlg::IDD, pParent)
{
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CDataDlg::DoDataExchange(CDataExchange* pDX)
{
        CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CDataDlg, CDialogEx)
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_BN_CLICKED(IDC_BUTTON2, &CDataDlg::OnBnClickedButton2)
        ON_BN_CLICKED(IDC_BUTTON1, &CDataDlg::OnBnClickedButton1)
END_MESSAGE_MAP()

// CDataDlg 消息处理程序

BOOL CDataDlg::OnInitDialog()
{
        CDialogEx::OnInitDialog();

        // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
        //  执行此操作
        SetIcon(m_hIcon, TRUE);                        // 设置大图标
        SetIcon(m_hIcon, FALSE);                // 设置小图标

        // TODO:  在此添加额外的初始化代码

            hwnd = AfxGetMainWnd()->GetSafeHwnd();

        return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CDataDlg::OnPaint()
{
        if (IsIconic())
        {
                CPaintDC dc(this); // 用于绘制的设备上下文

                SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

                // 使图标在工作区矩形中居中
                int cxIcon = GetSystemMetrics(SM_CXICON);
                int cyIcon = GetSystemMetrics(SM_CYICON);
                CRect rect;
                GetClientRect(&rect);
                int x = (rect.Width() - cxIcon + 1) / 2;
                int y = (rect.Height() - cyIcon + 1) / 2;

                // 绘制图标
                dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
                CDialogEx::OnPaint();
        }
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CDataDlg::OnQueryDragIcon()
{
        return static_cast<HCURSOR>(m_hIcon);
}

void CDataDlg::OnBnClickedButton2()
{
        // TODO:  在此添加控件通知处理程序代码

        ::SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_CLOSE, 0,0);

}

void CDataDlg::OnBnClickedButton1()
{
        // TODO:  在此添加控件通知处理程序代码

        HANDLE hThread = ::CreateThread(NULL, 0, ThreadFunction, NULL, 0, NULL);
        if (hThread)
        CloseHandle(hThread);
}

BOOL
CALLBACK
EnumSymCallBack(
PSYMBOL_INFOW pSymInfo,
ULONG SymbolSize,
PVOID UserContext)
{
        BOOL IsPrint = FALSE;

        do
        {
                if (!wcscmp(pSymInfo->Name, _T("DbgkCreateThread")))
                {
                        StSymbolsInfo.lpDbgkCreateThread = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("KiDispatchException")))
                {
                        StSymbolsInfo.lpKiDispatchException = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("DbgkForwardException")))
                {
                        StSymbolsInfo.lpDbgkForwardException = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("DbgkpQueueMessage")))
                {
                        StSymbolsInfo.lpDbgkpQueueMessage = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("PspExitThread")))
                {
                        StSymbolsInfo.lpPspExitThread = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("DbgkExitThread")))
                {
                        StSymbolsInfo.lpDbgkExitThread = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("PsGetProcessDebugPort")))
                {
                        StSymbolsInfo.lpPsGetProcessDebugPort = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("DbgkClearProcessDebugObject")))
                {
                        StSymbolsInfo.lpDbgkClearProcessDebugObject = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("PsGetProcessDebugPort")))
                {
                        StSymbolsInfo.lpPsGetProcessDebugPort = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("DbgkpMarkProcessPeb")))
                {
                        StSymbolsInfo.lpDbgkpMarkProcessPeb = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("DbgkpCloseObject")))
                {
                        StSymbolsInfo.lpDbgkpCloseObject = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("PspProcessDelete")))
                {
                        StSymbolsInfo.lpPspProcessDelete = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("DbgkExitProcess")))
                {
                        StSymbolsInfo.lpDbgkExitProcess = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("DbgkMapViewOfSection")))
                {
                        StSymbolsInfo.lpDbgkMapViewOfSection = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("DbgkUnMapViewOfSection")))
                {
                        StSymbolsInfo.lpDbgkUnMapViewOfSection = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("DbgkpSetProcessDebugObject")))
                {
                        StSymbolsInfo.lpDbgkpSetProcessDebugObject = pSymInfo->Address;
                }
                else if (!wcscmp(pSymInfo->Name, _T("NtClose")))
                {
                       
                }
                else
                {
                        break;
                }
                IsPrint = TRUE;
        } while (0);

        if (IsPrint)
                NewDbgPrint("DbgObj-> %-32ws %llx\n", pSymInfo->Name, pSymInfo->Address);

        return TRUE;
}

BOOL GetOsModuleInfo(PSYSTEM_MODULE SysModInfo)
{
        ULONG ulInfoLen = 0;
        NTSTATUS Status;
        SYSTEM_MODULE_INFORMATION* pStLoaderInfo = NULL;

        if (SysModInfo == NULL)
                return FALSE;
        NtQuerySystemInformation(SystemModuleInformation, NULL, 0, &ulInfoLen);
        if (!ulInfoLen)
                return STATUS_UNSUCCESSFUL;
        pStLoaderInfo = (SYSTEM_MODULE_INFORMATION*)malloc(ulInfoLen + sizeof(ULONG));
        if (pStLoaderInfo->aSM == NULL)
                return STATUS_UNSUCCESSFUL;
        Status = NtQuerySystemInformation(SystemModuleInformation, (PVOID)pStLoaderInfo,
                ulInfoLen, &ulInfoLen);
        if (!NT_SUCCESS(Status))
        {
                if (pStLoaderInfo)
                  free(pStLoaderInfo);
                return Status;
        }
        RtlMoveMemory(SysModInfo, &pStLoaderInfo->aSM[0], sizeof(SYSTEM_MODULE));
        if (pStLoaderInfo)
                free(pStLoaderInfo);

        return TRUE;
}

int __cdecl NewDbgPrint(char* _Format, ...)
{
        int iRet;
        va_list list;
        char SzBuf[8192] = { 0 };

        va_start(list, _Format);
        iRet = vsprintf_s(SzBuf, sizeof(SzBuf), _Format, list);
        OutputDebugStringA(SzBuf);
        va_end(list);

        return iRet;
}

BOOL GetModuleCurrentPath(CHAR* SzPath, size_t Size)
{
        int i;

        i = GetModuleFileNameA(NULL, SzPath, (DWORD)Size);
        while (SzPath[i] != L'\\')
        {
                i--;
        }
        SzPath[i + 1] = L'\0';

        return i;
}

BOOL
WINAPI
EnumSymbolsFunction(VOID)
{
        CHAR CurrentPath[512] = { 0 };
        CHAR OsPath[512] = { 0 };
        CHAR SymbolsPath[512] = { 0 };
        CHAR SymFileName1[MAX_PATH] = { 0 };
        CHAR SymFileName2[MAX_PATH] = { 0 };
        SYSTEM_MODULE SysModInfo = { 0 };
        HANDLE hProcess = 0;
        BOOL bRet = TRUE;
        HANDLE hFile = 0;

        //获得系统模块的信息
        if (!GetOsModuleInfo(&SysModInfo))
                return FALSE;
        //获取系统内核文件路径
        GetSystemDirectoryA(OsPath, sizeof(OsPath));
        strcat_s(OsPath, sizeof(OsPath), "\\");
        strcat_s(OsPath, sizeof(OsPath), SysModInfo.ImageName + SysModInfo.ModuleNameOffset);
        OutputDebugStringA(OsPath);
        //获取当前程序绝对路径
        GetModuleCurrentPath(CurrentPath, sizeof(CurrentPath));
        sprintf_s(SymbolsPath, sizeof(SymbolsPath),
                "srv*%ssymbols*http://msdl.microsoft.com/download/symbols", CurrentPath);
        OutputDebugStringA(SymbolsPath);

        //首先创建一个目录 symsrv.yes文件,据说symsrv.dll会检查,如果存在才允许下载

        CHAR symsrvFilePath[500] = { 0 };
        GetSystemDirectoryA(symsrvFilePath, sizeof(symsrvFilePath));
        strcat_s(symsrvFilePath, sizeof(symsrvFilePath), "\\");
        strcat_s(symsrvFilePath, sizeof(symsrvFilePath), "symsrv.yes");
        hFile = CreateFileA(
                symsrvFilePath,//symsrv.yes文件路径
                FILE_ALL_ACCESS,
                FILE_SHARE_READ,
                NULL,
                OPEN_ALWAYS,
                FILE_ATTRIBUTE_NORMAL,
                NULL
                );
        if (hFile == INVALID_HANDLE_VALUE)
                return FALSE;
        CloseHandle(hFile);

        //设置符号选项,初始化符号库
        SymSetOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_DEFERRED_LOADS |
                SYMOPT_UNDNAME | SYMOPT_DEBUG | SYMOPT_IGNORE_NT_SYMPATH |
                SYMOPT_LOAD_LINES | SYMOPT_ALLOW_ABSOLUTE_SYMBOLS | SYMOPT_FAVOR_COMPRESSED);
        hProcess = GetCurrentProcess();
        bRet = SymInitialize(hProcess, SymbolsPath, TRUE);
             if (!bRet)
                    return FALSE;
                 //SymFindFileInPathW
                //使用SymGetSymbolFile来取得符号文件
                 bRet = SymGetSymbolFile(
                         hProcess,
                         NULL,
                         OsPath,
                         sfPdb,
                         SymFileName1,
                         MAX_PATH,
                         SymFileName2,
                         MAX_PATH
                         );
                 if (!bRet)
                         return FALSE;
                 DWORD64 ModBaseOfDll = SymLoadModuleEx(hProcess,
                         NULL,
                         OsPath,
                         0,
                         (DWORD64)SysModInfo.Base,
                         0,
                         0,
                         0);
                //调用SymLoadModule函数载入对应符号库
                //使用SymEnumSymbols函数枚举模块中的符号
                //DWORD64 ModBaseOfDll = SymLoadModule64(
                //        hProcess,
                //        NULL,
                //        OsPath,
                //        NULL,
                //        (DWORD64)SysModInfo.Base /*+ 0xFFFFF80000000000)*/,
                //        0
                //        );
                if (ModBaseOfDll == 0)
                        return FALSE;

                NewDbgPrint("SymFileName1  %s\n", SymFileName1);
                NewDbgPrint("SymFileName2  %s\n", SymFileName2);
                NewDbgPrint("ModBaseOfDll  %llx\n", ModBaseOfDll);
                NewDbgPrint("SysModInfo.Size  %x\n", SysModInfo.Size);
                NewDbgPrint("SysModInfo.Base  %llx\n", SysModInfo.Base );
               
                if (!SymEnumSymbolsW(
                        hProcess,
                        ModBaseOfDll,
                        NULL,
                        EnumSymCallBack,
                        NULL))       
                        return FALSE;       
                SymUnloadModule64(hProcess, ModBaseOfDll);
                SymCleanup(hProcess);
                    bRet = TRUE;

        return bRet;
}

DWORD WINAPI ThreadFunction(LPVOID lpParamter)
{

        HMODULE hNtdll = 0;
        HANDLE        hDevice = 0;
        DWORD   dw;
        DWORD   OutPut;

        LoadLibraryA("DbgHelp.dll");
        LoadLibraryA("symsrv.dll");

        hNtdll = GetModuleHandleW(L"ntdll.dll");
        _NtQuerySystemInformation = (t_NtQuerySystemInformation)GetProcAddress(
                hNtdll, "NtQuerySystemInformation");

        if (!EnumSymbolsFunction())
                return -1;

        hDevice = CreateFileA("\\\\.\\MDriverLinkName",
                GENERIC_READ | GENERIC_WRITE,
                0,
                NULL,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                NULL);
        if (hDevice == INVALID_HANDLE_VALUE)
                return -1;

        ::DeviceIoControl(hDevice, IOCTL_STOP, &StSymbolsInfo, sizeof(SYMBOLS_INFO),
                &OutPut, sizeof(DWORD), &dw, NULL);

        return -1;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 46
活跃值: (37)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
跟踪到上图的rip位置,返回值为0啊,正常的是1,谁给一个64位能用的啊
2014-9-30 10:09
0
游客
登录 | 注册 方可回帖
返回
//