好吧……我承认这个东西很是有骗子的嫌疑
但是我本身就是说放的初级的文章。好东西留着以后再放,还望大家海涵~
符号文件大家应该很熟咯,我就不说什么废话了
具体看DbgHelp库的用法。要想解析符号,只需要做以下几步即可;
1:首先创建一个目录 symsrv.yes文件,据说symsrv.dll会检查,如果存在才允许下载,道听途说的,没有去逆一下,见谅见谅
2:调用SymInitialize初始化,其中必须要传入有效进程句柄,可选传入符号文件搜索路径……如果没有指定这个路径,稍后可以调用SymSetSearchPath来指定
3:欲解析符号前,使用SymGetSymbolFile来取得符号文件,如果搜索路径没有这个文件,那么将从微软服务器下载,然后调用SymLoadModule64加载它咯
4:解析咯
注:很重要的一点,要想从微软符号文件服务器下载东西,第二步符号文件搜索路径时须得指定:
srv* xxxx *http://msdl.microsoft.com/download/symbols
大家都眼熟,就不多说了
PS:我代码里用了一个硬编码,大家见谅,嘿嘿
代码很短,我直接贴上来了
#include <stdio.h> #include <Windows.h> #include <DbgHelp.h> #pragma comment(lib , "DbgHelp.lib") #pragma comment(lib , "ImageHlp.lib") PLOADED_IMAGE IMAGEAPI ImageLoad( __in PSTR DllName, __in PSTR DllPath ); HANDLE hProcess; char* url = "http://msdl.microsoft.com/download/symbols"; HANDLE hIn; HANDLE hOut; void ChangeOutputTextColor( DWORD rgbColor) { SetConsoleTextAttribute ( hOut , FOREGROUND_RED); } BOOLEAN InitSymHandler() { HANDLE hfile; char Path[MAX_PATH]={0}; char FileName[MAX_PATH]={0}; char SymPath[MAX_PATH*2]={0}; if (!GetCurrentDirectoryA( MAX_PATH ,Path)) { printf ("cannot get current directory \n"); return FALSE; } strcpy( FileName , Path); strcat(FileName ,"\\symsrv.yes"); printf ("%s \n",FileName); hfile = CreateFileA ( FileName, FILE_ALL_ACCESS, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hfile == INVALID_HANDLE_VALUE) { printf ("create or open file error: 0x%X \n",GetLastError()); return FALSE; } CloseHandle (hfile); hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, 4); if (hProcess == INVALID_HANDLE_VALUE) { printf ("Cannot open system process \n"); return FALSE; } SymSetOptions ( SYMOPT_CASE_INSENSITIVE | SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME); strcat(Path,"\\symbols*"); strcpy(SymPath,"SRV*"); strcat(SymPath,Path); strcat(SymPath,url); printf ("%s \n",SymPath); SymInitialize( hProcess, SymPath, FALSE); return TRUE; } BOOLEAN LoadSymModule( char* ImageName, DWORD ModuleBase) { DWORD64 tmp; char SymFileName[MAX_PATH]={0}; PLOADED_IMAGE pli = ImageLoad ( ImageName , NULL); if (pli == NULL) { printf ("cannot get loaded module of %s \n",ImageName); return FALSE; } if (!SymGetSymbolFile( hProcess, NULL, pli->ModuleName, sfPdb, SymFileName, MAX_PATH, SymFileName, MAX_PATH)) { printf ("cannot get symbol file of %s ,error: 0x%x \n",ImageName,GetLastError()); return FALSE; } tmp = SymLoadModule64( hProcess, pli->hFile, pli->ModuleName, NULL, (DWORD64)ModuleBase, pli->SizeOfImage); if (!tmp) { printf ("cannot load module , error : %X \n",GetLastError()); return FALSE; } return TRUE; } BOOLEAN EnumSyms( char* ImageName, DWORD ModuleBase, PSYM_ENUMERATESYMBOLS_CALLBACK EnumRoutine, PVOID Context) { BOOLEAN bEnum; if ( !LoadSymModule( ImageName , ModuleBase) ) { return FALSE; } bEnum = SymEnumSymbols( hProcess, ModuleBase, NULL, EnumRoutine, Context); if (!bEnum) { printf ("cannot enum symbols ,error: %x \n",GetLastError()); } return bEnum; } BOOLEAN CALLBACK EnumSymRoutine( PSYMBOL_INFO psi, ULONG SymSize, PVOID Context) { printf ("%s : 0x%X \n",psi->Name,psi->Address); return TRUE; } int main(void) { hIn = GetStdHandle ( STD_INPUT_HANDLE); hOut = GetStdHandle (STD_OUTPUT_HANDLE); if (!InitSymHandler ()) { goto __exit; } ; //ChangeOutputTextColor (4); EnumSyms("ntkrnlpa.exe", 0x804d8000,(PSYM_ENUMERATESYMBOLS_CALLBACK)EnumSymRoutine,NULL); __exit: getchar(); }