Debug Interface Access SDKã使ã£ã¦å é¨é¢æ°ã®åå解決ãè¡ã
IDAã使ã£ã¦ã½ããã¦ã§ã¢ã®è§£æããã¦ãã¨ãã¤ãæããã§ããããããã°æ
å ±ã£ã¦ä¾¿å©ã§ããããIDAã¯ã¤ã¡ã¼ã¸ãã¡ã¤ã«ããã¼ãããå¾ã«pdbã®æ¤ç´¢ãè¡ã£ã¦ãã¦ãã·ã³ãã«æ
å ±ã¨ãã®ã©ãã«ãèªåã§åãè¾¼ãã§ããã¾ããããããããããã§ãã¢ã»ã³ããªããã¾ãèªã¾ãªãã¦ã大ä½ã®åä½ã¯ç解ã§ãã¦ãã¾ãã¾ããä»åã¯ãã®pdbã解æãã¦IDAãè¡ã£ã¦ãã(ã¢ãã¬ã¹ -> ã·ã³ãã«)ã¨ã¯éã®(ã·ã³ãã« -> ã¢ãã¬ã¹)ãèªåã§ãã£ã¦ã¿ããã¨æãã¾ãã
ã¨ã¯è¨ã£ã¦ããæ®å¿µãªããpdbã®ä»æ§ã¯éå
¬éã§ãã(å¤å)
IDAã¯IMAGEHELP.dllã使ã£ã¦pdbã解æãã¦ãã¿ãããªãã§ãã(ä¸è¨åç
§)â
https://www.hex-rays.com/products/ida/support/idadoc/1374.shtml
æ£ç´dbghelp.dll(IMAGEHELPã®ç¸®å°çã§ã)ãããã®APIã¯ä»æ§å¤æ´ãæ¿ãããåä½ãä¸å®å®ãªã¤ã¡ã¼ã¸ãããã®ã§ãã¾ã使ããããªãã§ããä½ãè¯ãæã¯ç¡ããã¨ãããã調ã¹ã¦ã¿ãã¨ãããDebug Interface Access SDKã¨ããç©ãè¦ã¤ãã¾ããã â
http://blogs.msdn.com/b/vcblog/archive/2010/01/05/dia-based-stack-walking.aspx
ä½ãããè¶
ããã...
ã¨ã¦ãè¯ããã ã£ãã®ã§ããã使ãäºã«ãã¾ãããã¨ã¯ãããDIAã®æ¥æ¬èªè³æãã»ã¼çç¡ã ã£ãã®ã§çµæ§è¦å´ãã¾ããorz
ãã¨ãDIAèªä½ãåä½ã§é
å¸ããã¦ãã訳ã§ã¯ç¡ãã¦ãVisualStudioããã¦ã³ãã¼ãããéã«ä¸ç·ã«ã¤ãã¦æ¥ãã¿ããã§ãã(expressã¯ç¡ãã§ã)
以ä¸åèã«ãããµã¤ã(ã¨ãããã»ã¼ä¸¸ãã¯ãª
Debug Interface Access SDK
[Win32] [COM] How to read PDB Symbol file using DIA SDK | すなのかたまり
ããã§(ã·ã³ãã« -> ã¢ãã¬ã¹)å¤æãã§ããããã«ãªãã¾ãããã¨ããã§ãããã§ããã¨ä½ãå¬ããã®ãã¨è¨ãã¨ããã¨ãã°DLLã¤ã³ã¸ã§ã¯ã·ã§ã³ã§ä»ããã»ã¹ã«ã³ã¼ãã注å
¥ãããããæã«ãã®ããã»ã¹å
ã®é¢æ°ãå¼ã³åºãããæãããã¨æãã¾ãããã®æããã¡ãã¡ãããã¬ãéã¢ã»ã³ãã©ãªã©ã§é¢æ°ã®å ´æãç¹å®ããã®ã¯ããã©ãã§ããããããæã«ãå
é¨é¢æ°ã®åå解決(ã¤ã¾ã ã·ã³ãã« -> ã¢ãã¬ã¹ã®å¤æ)ãDLLå
ã§èªåã§ã§ããã°ãå¼ã³åºãããé¢æ°åãæå®ããã ãã§è¯ããªãã®ã§ã¨ã¦ã楽ã§ãã(ã¾ããã£ã¨è¯ãæ¹æ³ãããã®ããããã¾ããã...
ãã¨ãã°ã²ã¼ã å
ã®Game::Win(void)ã¿ãããªé¢æ°ãç´æ¥DLLããååæå®ã§å¼ã³åºãããã§ããããã§ãã
ã§ãæ¸ããã³ã¼ãããããªæãâ
#include <windows.h> #include <tlhelp32.h> #include <psapi.h> #include <stdio.h> #include <tchar.h> #include <map> #include "C:\Program Files\Microsoft Visual Studio 12.0\DIA SDK\include\dia2.h" #define DIA_SDK_PATH "C:\\Program Files\\Microsoft Visual Studio 12.0\\DIA SDK\\" #pragma comment (lib, "psapi.lib") typedef HRESULT (__stdcall *DLLGETCLASSOBJECT)( _In_ REFCLSID rclsid, _In_ REFIID riid, _Out_ LPVOID *ppv ); DWORD FindProcessId(TCHAR* processName);//ããã»ã¹å -> PID LPVOID GetBaseAddressFromName(TCHAR* ProcessName);//ã¤ã¡ã¼ã¸ãã¼ã¹ã®åå¾ BOOL DumpSymbolsFromDll(TCHAR* DllPath, LPCWSTR PdbFile, LPCWSTR SymbolName); VOID DumpSymbols(IDiaEnumSymbols *EnumSymbols); BOOL DumpSymbolsInternal(IDiaDataSource *MsdiaInstance, LPCWSTR PdbFile, LPCWSTR SymbolName); std::map<BSTR,DWORD> NameToRVA;//é¢æ°åã¨RVAã®å¯¾å¿ TCHAR* target_function = TEXT("MyFunction"); DWORD target_RVA = 0; int _tmain(int argc, TCHAR* argv[]){ if(argc < 4){ fprintf(stderr,"%s <pdb file> <symbol pattern> <target process> <target dll>\n",argv[0]); return 1; } TCHAR* dll_path = TEXT("C:\\Program Files\\Microsoft Visual Studio 12.0\\DIA SDK\\bin\\msdia120.dll"); LPVOID baseAddress = GetBaseAddressFromName(argv[3]); DumpSymbolsFromDll(dll_path,argv[1],argv[2]); void (*MyFunc)(void); /*for(std::map<BSTR,DWORD>::iterator it = NameToRVA.begin(); it != NameToRVA.end(); ++it){ wprintf(TEXT("%s %08X\n"),(*it).first,(*it).second); }*/ if(!target_RVA){ fprintf(stderr,"Cannot find function\n"); return 1;} printf("\tBase Address: %08X\n\tRVA: %08X\n",(int)baseAddress,target_RVA); MyFunc = (void(*)())((int)baseAddress + target_RVA - 1);//ãã¼ã¹ã¢ãã¬ã¹ + æå®é¢æ°ã®RVA printf("\tMyFunction: %08X\n",(int)MyFunc); MyFunc(); } /* ããã»ã¹å -> PID */ DWORD FindProcessId(TCHAR* processName) { PROCESSENTRY32 processInfo; processInfo.dwSize = sizeof(processInfo); HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); if ( processesSnapshot == INVALID_HANDLE_VALUE ) return 0; Process32First(processesSnapshot, &processInfo); if ( !wcscmp(processName,processInfo.szExeFile) ) { CloseHandle(processesSnapshot); return processInfo.th32ProcessID; } while ( Process32Next(processesSnapshot, &processInfo) ) { if ( !wcscmp(processName,processInfo.szExeFile) ) { CloseHandle(processesSnapshot); return processInfo.th32ProcessID; } } CloseHandle(processesSnapshot); return 0; } /* ã¤ã¡ã¼ã¸ãã¼ã¹ã®åå¾ */ LPVOID GetBaseAddressFromName(TCHAR* ProcessName) { HANDLE hProcess; HMODULE ModuleHandles[1000]; DWORD ModuleNum; DWORD ReturnSize; TCHAR szModule[256]; MODULEINFO ModInfo; DWORD i; DWORD dwProcessId = FindProcessId(ProcessName);//ããã»ã¹å -> PID /* æå®ãããååã®ããã»ã¹ãã³ãã«ãåå¾ */ hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); /* ç¾å¨ã®ããã»ã¹ã«ãã¼ãããã¦ããã¢ã¸ã¥ã¼ã«ã®ä¸è¦§ã¨æ°ãåå¾ */ EnumProcessModules(hProcess, ModuleHandles, sizeof(ModuleHandles), &ReturnSize); ModuleNum = ReturnSize / sizeof(HMODULE); /* åã¢ã¸ã¥ã¼ã«ã®æ å ±ã表示 */ for(i=0; i<ModuleNum; i++) { /* ã¢ã¸ã¥ã¼ã«ã®ãã¡ã¤ã«åã¨æ å ±ãåå¾ */ GetModuleBaseName(hProcess, ModuleHandles[i], szModule, sizeof(szModule)); GetModuleInformation(hProcess, ModuleHandles[i], &ModInfo, sizeof(ModInfo)); /* çµæã表示 */ wprintf(TEXT("\tName: %s\n"),szModule); wprintf(TEXT("\tBase Address: %p\n"), ModInfo.lpBaseOfDll); wprintf(TEXT("\tSize: %08X\n"), ModInfo.SizeOfImage); wprintf(TEXT("\tEntryPoint: %p\n"), ModInfo.EntryPoint); if(!wcscmp(szModule,ProcessName)) return ModInfo.EntryPoint; } return NULL; } VOID DumpSymbols(IDiaEnumSymbols *EnumSymbols) { HRESULT hr = 0; BOOL Ret = FALSE; ULONG Retrieved = 0; for (;;) { IDiaSymbol *Symbol = NULL; BSTR Name = NULL; BSTR Undecorated = NULL; DWORD Rva = 0; DWORD SymTag = 0; hr = EnumSymbols->Next(1, &Symbol, &Retrieved); if ( Retrieved==0 ) break; hr = Symbol->get_relativeVirtualAddress(&Rva); hr = Symbol->get_name(&Name); hr = Symbol->get_undecoratedName(&Undecorated); hr = Symbol->get_symTag(&SymTag); //wprintf(TEXT("%4d RVA=%08x %-30s %-30s\n"), SymTag, Rva, Name, Undecorated); //NameToRVA[Name] = Rva; if(!wcscmp(Name,target_function)) target_RVA = Rva; if ( Name ) SysFreeString(Name); if ( Undecorated ) SysFreeString(Undecorated); if ( Symbol ) Symbol->Release(); } } BOOL DumpSymbolsInternal(IDiaDataSource *MsdiaInstance, LPCWSTR PdbFile, LPCWSTR SymbolName) { HRESULT hr = 0; BOOL Ret = FALSE; IDiaSession *Session = NULL; IDiaSymbol *Global = NULL; IDiaEnumSymbols *EnumSymbols = NULL; hr = MsdiaInstance->loadDataFromPdb(PdbFile); hr = MsdiaInstance->openSession(&Session); hr = Session->get_globalScope(&Global); hr = Global->findChildren(SymTagNull, SymbolName, nsfRegularExpression, &EnumSymbols); DumpSymbols(EnumSymbols); cleanup: if ( EnumSymbols ) EnumSymbols->Release(); if ( Global ) Global->Release(); if ( Session ) Session->Release(); return Ret; } BOOL DumpSymbolsFromDll(TCHAR* DllPath, LPCWSTR PdbFile, LPCWSTR SymbolName) { HRESULT hr = 0; BOOL Ret = FALSE; HMODULE MsDiaDll = NULL; DLLGETCLASSOBJECT MsDiaDllGetClassObject = NULL; IClassFactory *Factory = NULL; IDiaDataSource *Source = NULL; MsDiaDll = LoadLibrary(DllPath); if ( !MsDiaDll ) { printf("LoadLibrary failed ? 0x%08x\n", GetLastError()); goto cleanup; } MsDiaDllGetClassObject = (DLLGETCLASSOBJECT)GetProcAddress(MsDiaDll, "DllGetClassObject"); if ( !MsDiaDllGetClassObject ) { printf("LoadLibrary failed ? 0x%08x\n", GetLastError()); goto cleanup; } hr = MsDiaDllGetClassObject(__uuidof(DiaSource), __uuidof(IClassFactory), (void**)&Factory); hr = Factory->CreateInstance(NULL, __uuidof(IDiaDataSource), (void**)&Source); Ret = DumpSymbolsInternal(Source, PdbFile, SymbolName); cleanup: if(Source) Source->Release(); if(Factory) Factory->Release(); if(MsDiaDll) FreeLibrary(MsDiaDll); return Ret; }
å®è¡ããã¨
Name: test.exe Base Address: 00890000 Size: 00029000 EntryPoint: 008A1235 Base Address: 008A1235 RVA: 00014050 MyFunction: 008B5284
ãããªæãã§test.exeå ã®MyFunctioné¢æ°ã®ã¢ãã¬ã¹ã表示ãã¦ããã¾ãã
ä»åã¯ããã¾ã§DIAã®ç´¹ä»ãªã®ã§ãã¾ãä¸è¨ã®ã³ã¼ãã¯ãã¦ã«ããªãã§ãã ããã