采用vs2010的 DIA库以及DbgHelp的API开发, 本工具可以生成目标应用程序的全局变量信息以及所有数据类型的信息
主要目的是通过这个过程,开发一个比较完善的Symbol file生成工具。
Symbol file (霍尼韦尔机载软件测试TIU Server Dtmon input file)格式:
PDBDump工具运行界面:
源码:
main.h
#ifndef _MAIN_H_
#define _MAIN_H_
#include <stdio.h>
#include <windows.h>
#endif /* _MAIN_H_ */
main.cpp
#include "main.h"
#include "PDBDump.h"
#include "DataInfo.h"
#include <dbghelp.h>
FILE *pfDbg;
FILE *pfRpt;
int main(const int avgc, char *argv[])
{
HANDLE processHandle;
BOOL bRetVal;
char *sImageName;
if(avgc < 2)
return -1;
else
sImageName = argv[1];
printf("Start the process...\r\n");
if((pfDbg = fopen("Debug.txt", "wb")) == NULL)
{
printf("Can't open the debug file.\r\n");
return -1;
}
if((pfRpt = fopen("SymbolFile.txt", "wb")) == NULL)
{
printf("Can't open the debug file.\r\n");
return -1;
}
processHandle = GetCurrentProcess();
printf("Process Handle: 0x%08X\r\n", (unsigned long)processHandle);
if(SymInitialize(processHandle, sImageName , TRUE))
{
printf("SymInitialize is OK!\r\n");
ProcessInfo.baseAddr = SymLoadModule(processHandle, NULL, sImageName, NULL, 0, 0);
ProcessInfo.m_hProcess = processHandle;
printf("Process base address: 0x%08X\r\n", ProcessInfo.baseAddr);
fprintf(pfDbg, "************************************\r\n");
fprintf(pfDbg, "File path: %s\r\n", sImageName);
fprintf(pfDbg, "Process base address: %08X\r\n", ProcessInfo.baseAddr);
fprintf(pfDbg, "************************************\r\n");
if(ProcessInfo.baseAddr)
{
SymSetOptions(SymGetOptions() | SYMOPT_UNDNAME);
bRetVal = SymEnumerateModules64(ProcessInfo.m_hProcess, enumModules, NULL);
printf("SymEnumerateModules64 | bRetVal = %s\r\n", bRetVal? "TRUE" : "FALSE");
bRetVal = SymEnumSourceFiles(ProcessInfo.m_hProcess, ProcessInfo.baseAddr, "", enumSourceFiles, NULL);
printf("SymEnumSourceFiles | bRetVal = %s\r\n", bRetVal? "TRUE" : "FALSE");
bRetVal = SymEnumTypes(ProcessInfo.m_hProcess, ProcessInfo.baseAddr, enumUDT, NULL);
printf("SymEnumTypes | bRetVal = %s\r\n", bRetVal? "TRUE" : "FALSE");
bRetVal = SymEnumSymbols(ProcessInfo.m_hProcess, ProcessInfo.baseAddr, 0, enumSymbols, NULL);
printf("SymEnumSymbols | bRetVal = %s\r\n", bRetVal? "TRUE" : "FALSE");
SymUnloadModule(ProcessInfo.m_hProcess, ProcessInfo.baseAddr);
printf("SymUnloadModule\r\n");
}
else
{
printf("Can't get the base address of the process.\r\n");
}
}
else
{
printf("SymInitialize is ERROR!\r\n");
}
test();
fclose(pfDbg);
fclose(pfRpt);
printf("Stop this process...\r\n");
return 0;
}
PDBDump.h
#ifndef _PDBDUMP_H_
#define _PDBDUMP_H_
#include "main.h"
#include <dbghelp.h>
enum SymTagEnum // Stolen from CVCONST.H in the DIA 2.0 SDK
{
SymTagNull,
SymTagExe,
SymTagCompiland,
SymTagCompilandDetails,
SymTagCompilandEnv,
SymTagFunction,
SymTagBlock,
SymTagData,
SymTagAnnotation,
SymTagLabel,
SymTagPublicSymbol,
SymTagUDT,
SymTagEnum,
SymTagFunctionType,
SymTagPointerType,
SymTagArrayType,
SymTagBaseType,
SymTagTypedef,
SymTagBaseClass,
SymTagFriend,
SymTagFunctionArgType,
SymTagFuncDebugStart,
SymTagFuncDebugEnd,
SymTagUsingNamespace,
SymTagVTableShape,
SymTagVTable,
SymTagCustom,
SymTagThunk,
SymTagCustomType,
SymTagManagedType,
SymTagDimension
};
enum BasicType
{
btNoType = 0,
btVoid = 1,
btChar = 2,
btWChar = 3,
btInt = 6,
btUInt = 7,
btFloat = 8,
btBCD = 9,
btBool = 10,
btLong = 13,
btULong = 14,
btCurrency = 25,
btDate = 26,
btVariant = 27,
btComplex = 28,
btBit = 29,
btBSTR = 30,
btHresult = 31
};
extern BOOL CALLBACK enumSymbols(PSYMBOL_INFO pSymInfo,ULONG SymbolSize, PVOID UserContext);
extern BOOL CALLBACK enumUDT(PSYMBOL_INFO pUDTInfo,ULONG UDTSize, PVOID UserContext);
extern BOOL CALLBACK enumSourceFiles(PSOURCEFILE pSourceFile, PVOID UserContext);
extern BOOL CALLBACK enumModules(PCSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext);
typedef struct{
char *pname;
unsigned long baseAddr;
HANDLE m_hProcess;
}ProcessInfo_sTypedef;
extern ProcessInfo_sTypedef ProcessInfo;
extern char * basicTypeDataTypeString[];
extern const char * const basicTypeTypeNameString[];
extern const char * const rgTags[];
#endif /* _PDBDUMP_H_ */
PDBDump.cpp
#include "PDBDump.h"
#include <string>
#include "DataInfo.h"
ProcessInfo_sTypedef ProcessInfo;
extern FILE *pfDbg;
// Basic types
const char * const basicTypeTypeNameString[] =
{
"<NoType>", // btNoType = 0,
"void", // btVoid = 1,
"char", // btChar = 2,
"wchar_t", // btWChar = 3,
"signed char",
"unsigned char",
"int", // btInt = 6,
"unsigned int", // btUInt = 7,
"float", // btFloat = 8,
"<BCD>", // btBCD = 9,
"bool", // btBool = 10,
"short",
"unsigned short",
"long", // btLong = 13,
"unsigned long", // btULong = 14,
"__int8",
"__int16",
"__int32",
"__int64",
"__int128",
"unsigned __int8",
"unsigned __int16",
"unsigned __int32",
"unsigned __int64",
"unsigned __int128",
"<currency>", // btCurrency = 25,
"<date>", // btDate = 26,
"VARIANT", // btVariant = 27,
"<complex>", // btComplex = 28,
"<bit>", // btBit = 29,
"BSTR", // btBSTR = 30,
"HRESULT" // btHresult = 31
};
char * basicTypeDataTypeString[] = {
"UNKNOWN",
"UNKNOWN",
"C8",
"C8",
"UNKNOWN",
"UNKNOWN",
"S32",
"U32",