首页
社区
课程
招聘
[原创]利用GET请求从微软符号服务器下载PDB
发表于: 2022-9-12 21:33 12727

[原创]利用GET请求从微软符号服务器下载PDB

2022-9-12 21:33
12727

使用SymSrvGetFileIndexInfo函数获取到可执行文件对应PDB文件的GUID
然后使用HTTPS协议发送GET请求到微软符号服务器下载PDB文件
下载速度慢的话可以复制PDB文件的下载链接到迅雷中下载
详细代码如下:

#include <windows.h>
#include <DbgHelp.h>
#include <WinInet.h>
#include <stdio.h>
 
#pragma comment(lib,"dbghelp.lib")
#pragma comment(lib,"wininet.lib")
 
BOOL DownloadPdbFile(const char *szModuleFileName, const char *szDownloadDir)
{
    HINTERNET hInternet;
    HINTERNET hConnect;
    HINTERNET hRequest;
    char buf[512];
    char szGuid[128];
    SYMSRV_INDEX_INFO info;
    BOOL bReturn = FALSE;
    ZeroMemory(&info, sizeof(info));
    info.sizeofstruct = sizeof(info);
 
    //////////////////////////////////////////////////////
    //    查询模块文件的GUID信息;
 
    if (!SymSrvGetFileIndexInfo(szModuleFileName, &info, 0))
    {
 
        printf("error : SymSrvGetFileIndexInfo:[%d]", GetLastError());
        return FALSE;
    }
 
    //////////////////////////////////////////////////////
    //    GUID转换为文本;
    sprintf_s(szGuid, sizeof szGuid,
        "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%X",
        info.guid.Data1,
        info.guid.Data2,
        info.guid.Data3,
        info.guid.Data4[0],
        info.guid.Data4[1],
        info.guid.Data4[2],
        info.guid.Data4[3],
        info.guid.Data4[4],
        info.guid.Data4[5],
        info.guid.Data4[6],
        info.guid.Data4[7],
        info.age);
 
 
    printf(
        "下载链接:https://msdl.microsoft.com/download/symbols/%s/%s/%s\n",
        info.pdbfile,
        szGuid,
        info.pdbfile);
 
    printf("下载目录:%s\n", szDownloadDir);
 
    system("pause");
 
 
    hInternet = InternetOpenW(L"Microsoft-Symbol-Server/10.1710.0.0", 0, 0, 0, 0);
    if (hInternet)
    {
        hConnect = InternetConnectW(
            hInternet,
            L"msdl.microsoft.com",
            INTERNET_DEFAULT_HTTPS_PORT,
            NULL,
            NULL,
            INTERNET_SERVICE_HTTP,
            0,
            NULL);
 
        if (hConnect)
        {
            /////////////////////////////////////////////////
            // 页面地址;
            sprintf_s(
                buf,
                sizeof buf,
                "/download/symbols/%s/%s/%s",
                info.pdbfile,
                szGuid,
                info.pdbfile);
 
            hRequest = HttpOpenRequestA(
                hConnect,
                "GET",
                buf,
                "HTTP/1.0",
                NULL,
                NULL,
                INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_SECURE | INTERNET_FLAG_KEEP_CONNECTION,
                NULL);
 
            if (hRequest)
            {
                DWORD dwFlags = 0;
                DWORD dwLen = sizeof(dwFlags);
 
                InternetQueryOption(
                     hRequest,
                     INTERNET_OPTION_SECURITY_FLAGS,
                     (LPVOID)&dwFlags,
                      &dwLen);
                dwFlags |=
                     SECURITY_FLAG_IGNORE_UNKNOWN_CA;
                dwFlags |=
                     SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
                dwFlags |=
                     SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
                InternetSetOption(
                    hRequest,    
                    INTERNET_OPTION_SECURITY_FLAGS,
                    &dwFlags,
                    sizeof dwFlags);
 
 
                printf("发送GET请求...\n");
                if (HttpSendRequestW(hRequest, NULL, 0, NULL, 0))
                {
                    DWORD dwStatus = 0;
                    DWORD dwIndex = 0;
                    dwLen = sizeof(dwStatus);
 
                    ////////////////////////////////////////
                    //获取页面返回状态;
                    if (HttpQueryInfoW(
                        hRequest,
                        HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE,
                        &dwStatus,
                        &dwLen,
                        &dwIndex) && dwStatus == HTTP_STATUS_OK)
                    {
                        DWORD dwFileSize = 0;
                        dwLen = sizeof(dwFileSize);
                        dwIndex = 0;
                        /////////////////////////////////////
                        //获取PDB文件大小;
                        if (HttpQueryInfoW(
                            hRequest,
                            HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
                            &dwFileSize,
                            &dwLen,
                            &dwIndex) && dwFileSize)
                        {
                            printf("文件总大小:%dKB", dwFileSize / 1024);
 
                            ////////////////////////////////
                            //申请缓冲区;
                            LPVOID lpBuffer;
                            lpBuffer = VirtualAlloc(NULL, dwFileSize, MEM_COMMIT, PAGE_READWRITE);
                            if (lpBuffer)
                            {
                                /////////////////////////////
                                //为PDB文件创建目录;
                                CreateDirectoryA(szDownloadDir, NULL);
 
                                //下载目录//PDB文件名;
                                sprintf_s(
                                    buf,
                                    sizeof buf,
                                    "%s\\%s",
                                    szDownloadDir,
                                    info.pdbfile);
                                CreateDirectoryA(buf, NULL);
 
                                //下载目录//PDB文件名//GUID;
                                sprintf_s(
                                    buf,
                                    sizeof buf,
                                    "%s\\%s\\%s",
                                    szDownloadDir,
                                    info.pdbfile, szGuid);
                                CreateDirectoryA(buf, NULL);
 
                                //创建一个空白的PDB文件用于写入接收到的数据;
                                HANDLE hFile;
 
 
                                sprintf_s(
                                    buf,
                                    sizeof buf,
                                    "%s\\%s\\%s\\%s",
                                    szDownloadDir,
                                    info.pdbfile,
                                    szGuid,
                                    info.pdbfile);
 
                                hFile = CreateFileA(
                                    buf,
                                    GENERIC_READ | GENERIC_WRITE,
                                    0,
                                    NULL,
                                    CREATE_ALWAYS,
                                    FILE_ATTRIBUTE_NORMAL,
                                    NULL);
 
                                if (hFile != INVALID_HANDLE_VALUE)
                                {
                                    DWORD dwRecvSize = 0;
                                    //循环获取可接收的数据大小,直到接收完成;
                                    while (
                                        (InternetQueryDataAvailable(hRequest, &dwLen, 0, 0)) &&
                                        dwLen &&
                                        (dwRecvSize + dwLen) <= dwFileSize)
                                    {
                                        bReturn = TRUE;
 
                                        //读取数据;
                                        if (InternetReadFile(hRequest, (char*)lpBuffer + dwRecvSize, dwLen, &dwLen))
                                        {
                                            dwRecvSize += dwLen;
                                            printf(
                                                "下载文件:%dKB/%dKB : %d%s\r\n",
                                                dwRecvSize / 1024,
                                                dwFileSize / 1024,
                                                (DWORD)((double)dwRecvSize / (double)dwFileSize * 100.0),
                                                "%");
                                        }
                                        else
                                        {
                                            bReturn = FALSE;
                                            printf("error : InternetReadFile:[%d]", GetLastError());
                                            break;
                                        }
                                    }
 
                                    if (bReturn)
                                    {
                                        bReturn = WriteFile(hFile, lpBuffer, dwRecvSize, &dwRecvSize, NULL);
                                        if (bReturn)
                                        {
                                            printf("下载完成!\n");
                                        }
                                        else
                                        {
                                            printf("error : WriteFile:[%d]", GetLastError());
                                        }
                                    }
 
                                    CloseHandle(hFile);
                                }else printf("error : CreateFileA:[%d]", GetLastError());
                                VirtualFree(lpBuffer, 0, MEM_RELEASE);
 
                            } else printf("error : VirtualAlloc:[%d]", GetLastError());
 
                        } else printf("error : HttpQueryInfoW.GetFileSize:[%d]", GetLastError());
 
                    }else printf("error : HttpQueryInfoW.GetStatus:[%d]", GetLastError());
 
                } else printf("error : HttpSendRequestW:[%d]", GetLastError());
 
                InternetCloseHandle(hConnect);
            } else printf("error : HttpOpenRequestA:[%d]", GetLastError());
 
 
            InternetCloseHandle(hConnect);
        } else printf("error : InternetConnectW:[%d]", GetLastError());
 
 
        InternetCloseHandle(hInternet);
    } else printf("error : InternetOpenW:[%d]", GetLastError());
 
 
 
    return bReturn;
}
 
int main()
{
    DownloadPdbFile("C:\\Windows\\System\\win32k.sys", "C:\\Symbols");
    return 0;
}
#include <windows.h>
#include <DbgHelp.h>
#include <WinInet.h>
#include <stdio.h>
 
#pragma comment(lib,"dbghelp.lib")
#pragma comment(lib,"wininet.lib")
 
BOOL DownloadPdbFile(const char *szModuleFileName, const char *szDownloadDir)
{
    HINTERNET hInternet;
    HINTERNET hConnect;
    HINTERNET hRequest;
    char buf[512];
    char szGuid[128];
    SYMSRV_INDEX_INFO info;
    BOOL bReturn = FALSE;
    ZeroMemory(&info, sizeof(info));
    info.sizeofstruct = sizeof(info);
 
    //////////////////////////////////////////////////////
    //    查询模块文件的GUID信息;
 
    if (!SymSrvGetFileIndexInfo(szModuleFileName, &info, 0))
    {
 
        printf("error : SymSrvGetFileIndexInfo:[%d]", GetLastError());
        return FALSE;
    }
 
    //////////////////////////////////////////////////////
    //    GUID转换为文本;
    sprintf_s(szGuid, sizeof szGuid,
        "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%X",
        info.guid.Data1,
        info.guid.Data2,
        info.guid.Data3,
        info.guid.Data4[0],
        info.guid.Data4[1],
        info.guid.Data4[2],
        info.guid.Data4[3],
        info.guid.Data4[4],
        info.guid.Data4[5],
        info.guid.Data4[6],
        info.guid.Data4[7],
        info.age);
 
 
    printf(
        "下载链接:https://msdl.microsoft.com/download/symbols/%s/%s/%s\n",
        info.pdbfile,
        szGuid,
        info.pdbfile);
 
    printf("下载目录:%s\n", szDownloadDir);
 
    system("pause");
 
 
    hInternet = InternetOpenW(L"Microsoft-Symbol-Server/10.1710.0.0", 0, 0, 0, 0);
    if (hInternet)
    {
        hConnect = InternetConnectW(
            hInternet,
            L"msdl.microsoft.com",
            INTERNET_DEFAULT_HTTPS_PORT,
            NULL,
            NULL,
            INTERNET_SERVICE_HTTP,
            0,
            NULL);
 
        if (hConnect)
        {
            /////////////////////////////////////////////////
            // 页面地址;
            sprintf_s(
                buf,
                sizeof buf,
                "/download/symbols/%s/%s/%s",
                info.pdbfile,
                szGuid,
                info.pdbfile);
 
            hRequest = HttpOpenRequestA(
                hConnect,
                "GET",
                buf,
                "HTTP/1.0",
                NULL,
                NULL,
                INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_SECURE | INTERNET_FLAG_KEEP_CONNECTION,
                NULL);
 
            if (hRequest)
            {
                DWORD dwFlags = 0;
                DWORD dwLen = sizeof(dwFlags);
 
                InternetQueryOption(
                     hRequest,
                     INTERNET_OPTION_SECURITY_FLAGS,
                     (LPVOID)&dwFlags,
                      &dwLen);
                dwFlags |=
                     SECURITY_FLAG_IGNORE_UNKNOWN_CA;
                dwFlags |=
                     SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
                dwFlags |=
                     SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
                InternetSetOption(
                    hRequest,    
                    INTERNET_OPTION_SECURITY_FLAGS,
                    &dwFlags,
                    sizeof dwFlags);
 
 
                printf("发送GET请求...\n");
                if (HttpSendRequestW(hRequest, NULL, 0, NULL, 0))
                {
                    DWORD dwStatus = 0;
                    DWORD dwIndex = 0;
                    dwLen = sizeof(dwStatus);
 
                    ////////////////////////////////////////
                    //获取页面返回状态;
                    if (HttpQueryInfoW(
                        hRequest,
                        HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE,
                        &dwStatus,
                        &dwLen,
                        &dwIndex) && dwStatus == HTTP_STATUS_OK)
                    {
                        DWORD dwFileSize = 0;
                        dwLen = sizeof(dwFileSize);
                        dwIndex = 0;

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 5
支持
分享
最新回复 (4)
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2022-9-13 08:43
0
雪    币: 6233
活跃值: (4462)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2022-9-13 08:51
0
雪    币: 19
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
error : HttpQueryInfoW.GetStatus:[400]
2024-1-29 12:34
0
雪    币: 3004
活跃值: (30861)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
感谢分享
2024-1-31 09:38
1
游客
登录 | 注册 方可回帖
返回
//