Как получить имена полей и смещения структуры, используя dbghlp и pdb - PullRequest
2 голосов
/ 22 июня 2010

Я бы хотел сбросить поля и смещения структур так же, как команда dt windbg.Допустим, например, что я хотел бы вывести структуру _PEB, которая находится в символах Microsoft Public (поскольку работает команда DT windbg).

Из документации MSDN я понял, что функция SymFromName должна это делать,это код, который я пробовал, который не работает на SymFromName с LastError 126 (указанный модуль не может быть найден).Из зарегистрированного обратного вызова я получаю следующий вывод:

CBA_SET_OPTIONS
CBA_SET_OPTIONS
CBA_SET_OPTIONS
CBA_EVENT: code 0 desc DBGHELP: Symbol Search Path: symsrv*symsrv.dll*C:\Symbols*http://msdl.microsoft.com/download/symbols

DBGHELP: Symbol Search Path: symsrv*symsrv.dll*C:\Symbols*http://msdl.microsoft.com/download/symbols

CBA_DEFERRED_SYMBOL_LOAD_START: C:\Windows\Sysnative\ntdll.dll
CBA_DEFERRED_SYMBOL_LOAD_PARTIAL: C:\Windows\Sysnative\ntdll.dll
CBA_EVENT: code 0 desc DBGHELP: No header for C:\Windows\Sysnative\ntdll.dll.  Searching for image on disk

DBGHELP: No header for C:\Windows\Sysnative\ntdll.dll.  Searching for image on disk

CBA_EVENT: code 0 desc DBGHELP: C:\Windows\Sysnative\ntdll.dll - OK

DBGHELP: C:\Windows\Sysnative\ntdll.dll - OK

CBA_DEFERRED_SYMBOL_LOAD_COMPLETE: C:\Windows\Sysnative\ntdll.dll
CBA_EVENT: code 0 desc DBGHELP: ntdll - public symbols  
         C:\Symbols\ntdll.pdb\823B51C37A764AF7BA1558B42B627FAC2\ntdll.pdb

DBGHELP: ntdll - public symbols  
         C:\Symbols\ntdll.pdb\823B51C37A764AF7BA1558B42B627FAC2\ntdll.pdb

Код:

const
  Index: THandle =1;
  Size = (SizeOf(SYMBOL_INFO)-1 + MAX_SYM_NAME * SizeOf(TCHAR) + SizeOf(ULONG64) -1) div SizeOf(ULONG64);
var
  Symbol: String;
  Filename: String;
  Path: String;
  dwBaseAddress: DWORD;
  im: IMAGEHLP_MODULE64;
  Buffer: array[0..Size] of ULONG64;
  pSymbol: PSYMBOL_INFO;
  SymbolName: array[0..MAX_SYM_NAME-1] of Char;
begin
  ZeroMemory(@SymbolName, SizeOf(SymbolName));
  SymbolName := '_PEB';
  Filename := 'C:\Windows\Sysnative\ntdll.dll';
  Path := 'symsrv*symsrv.dll*C:\Symbols*http://msdl.microsoft.com/download/symbols';

  { Initialize }
  Win32Check(SymInitialize(Index, nil, False));
  { Register callback to get some debug info }
  Win32Check(SymRegisterCallback64(Index, DbgHelpCallback, 0));

  { Set Options }
  SymSetOptions(SymGetOptions or SYMOPT_UNDNAME);
  SymSetOptions(SymGetOptions or SYMOPT_DEBUG);
  SymSetOptions(SymGetOptions or SYMOPT_LOAD_ANYTHING);

  { Set Symbol Path }
  Win32Check(SymSetSearchPathW(Index, PChar(Path)));

  { Load Module }
  dwBaseAddress := SymLoadModuleExW(Index, 0, PChar(Filename), nil, 0, 0, nil, 0);
  Win32Check(dwBaseAddress > 0);

  ZeroMemory(@im, SizeOf(im));
  im.SizeOfStruct := SizeOf(im);
  Win32Check(SymGetModuleInfoW64(Index, dwBaseAddress, im));

  ZeroMemory(@Buffer, SizeOf(Buffer));
  pSymbol := PSYMBOL_INFO(@Buffer);
  pSymbol^.SizeOfStruct := SizeOf(SYMBOL_INFO);
  pSymbol^.MaxNameLen := MAX_SYM_NAME;

  Win32Check(SymFromNameW(Index, Symbolname, pSymbol));

  Win32Check(SymUnloadModule64(Index, dwBaseAddress));
  Win32Check(SymCleanup(Index));

Ответы [ 2 ]

3 голосов
/ 23 июня 2010

Я заставил его работать, используя SymGetTypeFromName, чтобы получить индекс символа, а затем использую SymGetTypeInfo, чтобы получить детали:

const
  Index: THandle =1;
  Size = (SizeOf(SYMBOL_INFO)-1 + MAX_SYM_NAME * SizeOf(TCHAR) + SizeOf(ULONG64) -1) div SizeOf(ULONG64);
var
  Filename: String;
  Path: String;
  dwBaseAddress: array[0..0] of DWORD;
  im: IMAGEHLP_MODULE64;
  Buffer: array[0..Size] of ULONG64;
  pSymbol: PSYMBOL_INFO;
  SymbolName: array[0..MAX_SYM_NAME-1] of Char;
  i: Integer;
  ChildParams: TI_FINDCHILDREN_PARAMS;
  dwOffset: DWORD;
  pSymName: PChar;
begin
  ZeroMemory(@SymbolName, SizeOf(SymbolName));
  SymbolName := '_PEB';
  Filename := 'C:\Windows\System32\ntdll.dll';
  Path := 'symsrv*symsrv.dll*C:\Symbols*http://msdl.microsoft.com/download/symbols';

  { Initialize }
  Win32Check(SymInitialize(Index, nil, False));
  { Register callback to get some debug info }
  Win32Check(SymRegisterCallback64(Index, DbgHelpCallback, 0));

  { Set Options }
  SymSetOptions(SymGetOptions or SYMOPT_UNDNAME);
  SymSetOptions(SymGetOptions or SYMOPT_DEBUG);
  SymSetOptions(SymGetOptions or SYMOPT_LOAD_ANYTHING);

  { Set Symbol Path }
  Win32Check(SymSetSearchPathW(Index, PChar(Path)));

  { Load Module }
  dwBaseAddress[0] := SymLoadModuleExW(Index, 0, PChar(Filename), nil, 0, 0, nil, 0);

  ZeroMemory(@im, SizeOf(im));

  im.SizeOfStruct := SizeOf(im);
  for i := 0 to Length(dwBaseAddress)-1 do
  begin
    SymGetModuleInfoW64(Index, dwBaseAddress[i], im);
  end;

  ZeroMemory(@Buffer, SizeOf(Buffer));
  pSymbol := PSYMBOL_INFO(@Buffer);
  pSymbol^.SizeOfStruct := SizeOf(SYMBOL_INFO);
  pSymbol^.MaxNameLen := MAX_SYM_NAME;
  { Get Type Info by Symbol Name (we need the index) }
  Win32Check(SymGetTypeFromNameW(Index, dwBaseAddress[0], SymbolName, pSymbol));

  { Get Child Count }
  ZeroMemory(@ChildParams, SizeOf(ChildParams));
  Win32Check(SymGetTypeInfo(Index, dwBaseAddress[0], pSymbol^.TypeIndex, TI_GET_CHILDRENCOUNT, @ChildParams.Count));

  { Get Child Info }
  // TODO: Caller must reserve memory for the ChildId array (Count * SizeOf(ULONG))
  Win32Check(SymGetTypeInfo(Index, dwBaseAddress[0], pSymbol^.TypeIndex, TI_FINDCHILDREN, @ChildParams));
  for i := ChildParams.Start to ChildParams.Count - 1 do
  begin
    { Get Child Name }
    Win32Check(SymGetTypeInfo(Index, dwBaseAddress[0], {pSymbol^.TypeIndex + }ChildParams.ChildId[i], TI_GET_SYMNAME, @pSymName));
    { Get Child Offset }
    Win32Check(SymGetTypeInfo(Index, dwBaseAddress[0], {pSymbol^.TypeIndex + }ChildParams.ChildId[i], TI_GET_OFFSET, @dwOffset));
    Memo1.Lines.Add(Format('+0x%.3x %s', [dwOffset, pSymName]));
    LocalFree(Cardinal(pSymName));
  end;

  for i := 0 to Length(dwBaseAddress)-1 do
  begin
    Win32Check(SymUnloadModule64(Index, dwBaseAddress[i]));
  end;
  Win32Check(SymCleanup(Index));
end;

, и это вывод:

+0x000 InheritedAddressSpace
+0x001 ReadImageFileExecOptions
+0x002 BeingDebugged
+0x003 BitField
+0x003 ImageUsesLargePages
+0x003 IsProtectedProcess
+0x003 IsLegacyProcess
+0x003 IsImageDynamicallyRelocated
+0x003 SkipPatchingUser32Forwarders
+0x003 SpareBits
+0x004 Mutant
+0x008 ImageBaseAddress
+0x00C Ldr
+0x010 ProcessParameters
+0x014 SubSystemData
+0x018 ProcessHeap
+0x01C FastPebLock
+0x020 AtlThunkSListPtr
+0x024 IFEOKey
+0x028 CrossProcessFlags
+0x028 ProcessInJob
+0x028 ProcessInitializing
+0x028 ProcessUsingVEH
+0x028 ProcessUsingVCH
+0x028 ProcessUsingFTH
+0x028 ReservedBits0
+0x02C KernelCallbackTable
+0x02C UserSharedInfoPtr
+0x030 SystemReserved
+0x034 AtlThunkSListPtr32
+0x038 ApiSetMap
+0x03C TlsExpansionCounter
+0x040 TlsBitmap
+0x044 TlsBitmapBits
+0x04C ReadOnlySharedMemoryBase
+0x050 HotpatchInformation
+0x054 ReadOnlyStaticServerData
+0x058 AnsiCodePageData
+0x05C OemCodePageData
+0x060 UnicodeCaseTableData
+0x064 NumberOfProcessors
+0x068 NtGlobalFlag
+0x070 CriticalSectionTimeout
+0x078 HeapSegmentReserve
+0x07C HeapSegmentCommit
+0x080 HeapDeCommitTotalFreeThreshold
+0x084 HeapDeCommitFreeBlockThreshold
+0x088 NumberOfHeaps
+0x08C MaximumNumberOfHeaps
+0x090 ProcessHeaps
+0x094 GdiSharedHandleTable
+0x098 ProcessStarterHelper
+0x09C GdiDCAttributeList
+0x0A0 LoaderLock
+0x0A4 OSMajorVersion
+0x0A8 OSMinorVersion
+0x0AC OSBuildNumber
+0x0AE OSCSDVersion
+0x0B0 OSPlatformId
+0x0B4 ImageSubsystem
+0x0B8 ImageSubsystemMajorVersion
+0x0BC ImageSubsystemMinorVersion
+0x0C0 ActiveProcessAffinityMask
+0x0C4 GdiHandleBuffer
+0x14C PostProcessInitRoutine
+0x150 TlsExpansionBitmap
+0x154 TlsExpansionBitmapBits
+0x1D4 SessionId
+0x1D8 AppCompatFlags
+0x1E0 AppCompatFlagsUser
+0x1E8 pShimData
+0x1EC AppCompatInfo
+0x1F0 CSDVersion
+0x1F8 ActivationContextData
+0x1FC ProcessAssemblyStorageMap
+0x200 SystemDefaultActivationContextData
+0x204 SystemAssemblyStorageMap
+0x208 MinimumStackCommit
+0x20C FlsCallback
+0x210 FlsListHead
+0x218 FlsBitmap
+0x21C FlsBitmapBits
+0x22C FlsHighIndex
+0x230 WerRegistrationData
+0x234 WerShipAssertPtr
+0x238 pContextData
+0x23C pImageHeaderHash
+0x240 TracingFlags
+0x240 HeapTracingEnabled
+0x240 CritSecTracingEnabled
+0x240 SpareTracingBits

Теперьперейдите к следующему шагу: используйте RTTI Delphi 2010 и используйте этот механизм для сравнения смещений (это помогает мне конвертировать заголовки для Jedi ApiLib).

0 голосов
/ 22 июня 2010

Я не совсем разбираюсь в этих вещах, но иногда предполагается, что лидирующее подчеркивание в именах C является частью двоичного формата.

Это работает, если удалить лидирующее подчеркивание?*

...