2011-02-01 10 views
7

Próbuję zadzwonić SymLoadModuleEx załadować symbole z pliku PDB, a następnie użyć SymFromAddr patrzeć symbole z tym WPB. Jednak nie mogę dowiedzieć się, co przekazać do parametrów BaseOfDll i DllSize - dokumentacja wyraźnie mówi, że podczas ładowania pliku PDB, parametry te nie mogą być 0, a nawet próbuje przejść 0 wyników w to niepowodzeniem z ERROR_INVALID_PARAMETER .Jak używać SymLoadModuleEx do ładowania pliku PDB?

Oto co mój kod wygląda następująco:

SymSetOptions(SYMOPT_LOAD_LINES); 
HANDLE hprocess = GetCurrentProcess(); 
if (!SymInitialize(hprocess, NULL, FALSE)) 
    die("SymInitialize"); 

if(SymLoadModuleEx(hprocess, NULL, "full path to some PDB file.pdb", NULL, 
        0, // What to pass here? 
        0, // What to pass here? 
        NULL, 0) == 0) 
{ 
    die("SymLoadModuleEx"); 
} 

Jak można dowiedzieć się, co BaseOfDll i DllSize przejść w podczas ładowania pliku PDB? Wspomniany plik PDB jest plikiem symboli dla innego pliku wykonywalnego programu (nie biblioteki DLL) i dla samego argumentu przyjmijmy, że nie masz dostępu do oryginalnego pliku EXE, z którego wygenerowano PDB.

Alternatywnie, czy istnieje lepszy sposób patrzenia się symbole odpowiadające danym adresem z pliku PDB?

Odpowiedz

8

Metody dbghelp.dll i Sym* to tylko otoki wokół interfejsu API Debug Interface Access (DIA). DIA jest oparty na COM i nadużywa niektórych swoich interfejsów (wydaje się, że wszystko to jest IDiaSymbol), ale jest znacznie bardziej elastyczny niż to, co oferuje dbghelp.

szczególności, aby załadować znany WPB i odszukać symbol na podstawie adresu, można wykonać następujące czynności:

  1. CoCreate źródło Danych DIA (patrz rozdział „przykład” here).
  2. Użyj IDiaDataSource::loadDataFromPdb, aby załadować określony PDB (rozmiar DLL i adres bazowy nie są potrzebne). Aby uzyskać IDiaSession dla źródła danych, należy użyć IDiaDataSource::openSession.
  3. W zależności od tego, czy masz bezwzględny adres wirtualny (VA) lub względny adres wirtualny (RVA), możesz użyć odpowiednio findSymbolByVA lub findSymbolByRVA, aby uzyskać IDiaSymbol skojarzony z tym adresem.
  4. Wreszcie, można użyć IDiaSymbol::get_name, aby uzyskać nazwę funkcji zawierającą określony adres.

Nic z tego nie wymaga oryginalnego obrazu; wymagany jest tylko WPB. Zakładając, że używasz Visual Studio, nagłówki i biblioteki dla DIA są dostępne w (na przykład) C:\Program Files (x86)\Microsoft Visual Studio 10.0\DIA SDK.

3

Spójrz na próbce SymLoadPdb.cpp here.

0

Dia2Dump próbka działa dobrze dla mnie w rozwiązywaniu względnego adresu wirtualnego (adres obciążenie EIP-program) do PDB na nierozwiązanych wskaźników funkcji.Jest to sposób próbuję go:

DWORD64 dwAddress = _wcstoui64(argv[i], NULL, 16); 
    DWORD64 dwRVA = dwAddress - dwLoadAddress; 
    long displacement = 0; 
    IDiaSymbol* pFunc = 0; 
    error = (DWORD)g_pDiaSession->findSymbolByRVAEx(dwRVA, SymTagFunction, &pFunc, &displacement); 

    if (!error && pFunc) 
    { 
     BSTR bstrName; 

     if (pFunc->get_name(&bstrName) != S_OK) { 
      wprintf(L"(???)\n\n"); 
     } 

     else { 
      wprintf(L"%s \n\n", bstrName); 
      if (displacement) 
       wprintf(L"+ 0x%x \n\n", displacement); 
      else 
       wprintf(L" \n\n"); 
      SysFreeString(bstrName); 
     } 
    } 

Na przykład: Zastosowanie: [00447B60] [0001: 00446B60] ServerConfig :: getSSLConfig (publiczne: struct ssl_config __cdecl ServerConfig :: getSSLConfig (void) __ptr64)

Tutaj RVA jest 00447B60 [EIP - Adres Proces ładowania] Segment jest 0001 offset jest 00446B60

0

nie mam wg uprawnień do komentowania, więc będzie to zrobić w osobnym odpowiedź.

  1. Tak, DbgHelp jest opakowaniem wokół DIA, tylko pod względem statycznej biblioteki lib. DIA jest statycznie połączony z plikiem DbgHelp.dll. DbgHelp bezpośrednio wywołuje implementację fabryki klasy COM firmy Dia (IClassFactory) z pominięciem COM. Mówię o wersji 6.1.7601.17514. Tak więc DbgHelp.dll jest samodzielny (w połączeniu z symcrv.dll i srcsrv.dll)
  2. Obiekty Dia COM są dostarczane z Visual Studio (ta sama lokalizacja z dbgeng.dll), więc rozwiązanie nie działa na envs gdzie VS jest nie zainstalowano (ale nadal można próbować użyć msdia120.dll jako zespołu prywatnego, który wskazuje na to poprzez ActivateActCtx, ale musi również wdrożyć zależności, jeśli występują)
  3. DbgPomoc jest niewielka i zalecana do dystrybucji prywatnych kopii w aplikacji przez Microsoft. See "The redistribution policies for these included DLLs were specifically designed to make it as easy as possible for people to include these files in their own packages and release"

  4. Nie znalazłem sposobu pobierania plików PDB za pomocą interfejsów DIA. Sym API pozwala na to. deleguje wywołania do SymSrv.dll.

Tak oryginalne pytanie jest nadal aktualne.

Powiązane problemy