活着的虫子 from 为虫子生,为虫子死,为虫子奋斗一辈子 关于 PDB 与 EXE/DLL 文件的匹配问题
http://www.debuginfo.com/tools.html
regsvr32.exe "C:\kSource\pythonx\filetool\DIA SDK\bin\msdia140.dll"
regsvr64.exe "C:\kSource\pythonx\filetool\DIA SDK\bin\msdia140.dll"
C:\Windows\System32\regsvr32.exe "C:\kSource\pythonx\filetool\DIA SDK\bin\amd64\msdia140.dll"
C:\Windows\SysWOW64\regsvr32.exe "C:\kSource\pythonx\filetool\DIA SDK\bin\amd64\msdia140.dll"
ChkMatch can be used to check whether an executable and debug information file match. It can also be used to enforce matching between an executable and debug information file, if they are compatible. For more information about debug information matching and related issues, see this article. http://www.debuginfo.com/articles/debuginfomatch.html
判断 Exe(DLL) 和符号文件是否匹配—验证模块和符号文件是否匹配的工具和方法 当我们进行程序调试时,有时调试器会直接告诉你符号文件不对,或则显示出的调用栈不对,当你怀疑符号文件不匹配时,如何确定呢?
例用 Windows 调试工具集里的工具 symchk.exe symchk xxxx( 模块 ) /v /s .
从这里下载 http://www.debuginfo.com/download/chkmatch.zip
chkmatch -c
SymFindFileInPath 是 dbghelp.dll 里的函数,但是他也用到了 symsrv.dll,所以我们必须把写好的程序和这两个 dll 放在一起,否则函数 SymFindFileInPath 会返回错误。 from
BOOL SymFindFileInPath(
HANDLE hprocess,
LPSTR SearchPath,
LPSTR FileName,
PVOID id,
DWORD two,
DWORD three,
DWORD flags,
LPSTR FilePath,
PFINDFILEINPATHCALLBACK callback,
PVOID context
);
#include <ntifs.h>
#include <windef.h>
#include "ntimage.h"
#define NB10_SIG '01BN'
#define RSDS_SIG 'SDSR'
typedef struct CV_HEADER
{
DWORD Signature;
DWORD Offset;
} CV_HEADER;
typedef struct CV_INFO_PDB20
{
CV_HEADER CvHeader;
DWORD Signature;
DWORD Age;
BYTE PdbFileName[1];
} CV_INFO_PDB20;
typedef struct CV_INFO_PDB70
{
DWORD CvSignature;
GUID Signature;
DWORD Age;
BYTE PdbFileName[1];
} CV_INFO_PDB70;
BOOL PeIsRegionValid(PVOID Base, DWORD Size, PVOID Addr, DWORD RegionSize)
{
return ((PBYTE)Addr >= (PBYTE)Base && ((PBYTE)Addr + RegionSize) <= ((PBYTE)Base + Size));
}
// 返回 TRUE 但 PdbStr 为空意思是找过了确实没有 PDB
BOOLEAN PeGetPdb(PVOID ImageBase, DWORD ImageSize, PCHAR PdbStr)
{
PBYTE Base = (PBYTE)ImageBase;
BOOLEAN Result = FALSE;
CV_HEADER* CvInfo;
PIMAGE_DEBUG_DIRECTORY DbgDir;
ULONG PdbNameSize = 0;
__try
{
do
{
PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)Base;
PIMAGE_NT_HEADERS NtHeader = (PIMAGE_NT_HEADERS)(Base + DosHeader->e_lfanew);
PIMAGE_OPTIONAL_HEADER OptionalHeader;
PIMAGE_OPTIONAL_HEADER64 OptionalHeader64;
PIMAGE_OPTIONAL_HEADER32 OptionalHeader32;
DWORD DbgDirRva = 0;
// PE 解析代码
OptionalHeader = (PIMAGE_OPTIONAL_HEADER)(Base + DosHeader->e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader));
if (OptionalHeader->Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) // PE32+ x64
{
OptionalHeader64 = (PIMAGE_OPTIONAL_HEADER64)OptionalHeader;
DbgDirRva = OptionalHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
}
else // PE32 x86
{
OptionalHeader32 = (PIMAGE_OPTIONAL_HEADER32)OptionalHeader;
DbgDirRva = OptionalHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
}
DbgDir = (PIMAGE_DEBUG_DIRECTORY)(Base + DbgDirRva);
if (!DbgDir)
break;
ProbeForRead(DbgDir, sizeof(IMAGE_DEBUG_DIRECTORY), 1);
Result = TRUE; // 到此表示解析正常 能不能找到 PDB 就看有没有了
if (!DbgDir->AddressOfRawData || DbgDir->Type != IMAGE_DEBUG_TYPE_CODEVIEW)
break;
CvInfo = (CV_HEADER*)(Base + DbgDir->AddressOfRawData);
if (!PeIsRegionValid(Base, ImageSize, CvInfo, sizeof(CV_HEADER)))
break;
if (CvInfo->Signature == NB10_SIG) // VC6.0 (GBK)
{
if (!PeIsRegionValid(Base, ImageSize, CvInfo, sizeof(CV_INFO_PDB20)+MAX_PATH))
break;
PdbNameSize = strlen((CHAR*)((CV_INFO_PDB20*)CvInfo)->PdbFileName);
if (!PdbNameSize || PdbNameSize >= MAX_PATH)
break;
RtlCopyMemory(PdbStr, (CHAR*)((CV_INFO_PDB20*)CvInfo)->PdbFileName, PdbNameSize);
}
else if (CvInfo->Signature == RSDS_SIG) // VS2003+ (UTF-8)
{
if (!PeIsRegionValid(Base, ImageSize, CvInfo, sizeof(CV_INFO_PDB70)+MAX_PATH))
break;
PdbNameSize = strlen((CHAR*)((CV_INFO_PDB70*)CvInfo)->PdbFileName);
if (!PdbNameSize || PdbNameSize >= MAX_PATH)
break;
RtlCopyMemory(PdbStr, (CHAR*)((CV_INFO_PDB70*)CvInfo)->PdbFileName, PdbNameSize);
}
} while (0);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("EXCEPTION_EXECUTE_HANDLER\n"));
Result = FALSE;
}
return Result;
}
BOOLEAN PeGetFilePdb(PUNICODE_STRING pFilePath, PCHAR PdbStr)
{
BOOLEAN Result = FALSE;
SIZE_T Size = 0;
PVOID BaseAddress = CreateMapFileAndGetBaseAddr(pFilePath, &Size);
if (NULL == BaseAddress)
return FALSE;
Result = PeGetPdb(BaseAddress, Size, PdbStr);
ZwUnmapViewOfSection(ZwCurrentProcess(), BaseAddress);
return Result;
}