Есть ли способ получить доступ к информации отладки джедая (JDBG), содержащейся в исполняемом файле?
Инструменты отладки Microsoft указали мне на цепочку стеков в моем двоичном файле, и я хочу знать, каким методам / процедурам / функциям соответствуют эти смещения:
user32.dll!SendMessageA+0x4c
StackOverflow.exe+0x179263
StackOverflow.exe+0x2315b5
StackOverflow.exe+0x1fc82
StackOverflow.exe+0x50388
StackOverflow.exe+0x541fe
user32.dll!gapfnScSendMessage+0x332
Очевидно, я звоню SendMessage
, но я не знаю откуда. Исполняемый файл был собран с информацией отладки Jcl, встроенной в исполняемый файл; но я не могу понять, как это читать.
Глядя на некоторые функции и классы в JclDebug.pas
, кажется, что все ориентировано на получение отладочной информации внутри текущего процесса, например ::
function GetLocationInfo(const Addr: Pointer; var Info: TJclLocationInfo): Boolean;
принимает адрес в адресном пространстве моего текущего процесса. Это определяет, в каком HMODULE
адресе находится, например ::
- Stackoverflow.exe
- GDI32.dll
- USER32.dll
- KERNELBASE.dll
- dwmapi.dll
- UXTheme.dll
я думал, что мог бы использовать LoadLibrary
(который возвращает HMODULE
), чтобы вручную загрузить модуль, а затем передать его некоторым классам, которые копают образы модулей для отладочной информации:
module := LoadLibrary('C:\Users\Ian\Desktop\StackOverflow.exe');
и
TJclDebugInfoList = class(TObjectList)
private
function GetItemFromModule(const Module: HMODULE): TJclDebugInfoSource;
...
protected
function CreateDebugInfo(const Module: HMODULE): TJclDebugInfoSource;
...
end;
кроме случаев, когда он защищен.
Я пытаюсь (надеюсь), я могу написать инструмент, где я выбираю двоичный файл (* .exe), введите адрес и получить
- функция
- метод
- файл
- номер строки
смещения.
например.
[002315B5] FMain.TfrmMain.lvQuestions (Line 158, "FMain.pas" + 1) + $11
возможно?
Редактировать: Моим первым грубым и готовым подходом было просто извлечь сжатый файл map
, чтобы я мог посмотреть на него. Но он не сохраняется как ресурс (? ):
Хотя общий инструмент был бы более полезен:
Update :
я пытался использовать TJclDebugInfoList
; я понял, что свойство массива ItemFromModule
будет обращаться к защищенному методу:
function GetModuleLocationInfo(filename: string; Addr: Pointer): TJclLocationInfo;
var
module: HMODULE;
infoList: TJclDebugInfoList;
infoSource: TJclDebugInfoSource;
Address: Pointer;
locationInfo: TJclLocationInfo;
AddressOffset: Integer;
begin
module := LoadLibrary(filename);
if module = 0 then
RaiseLastWin32Error;
try
infoList := TJclDebugInfoList.Create;
try
infoSource := infoList.ItemFromModule[module];
if source = nil then
raise Exception.Create('Could not find debug info source for module '+IntToStr(module));
if not source.GetLocationInfo(Addr, {var}locationInfo) then
raise Exception.Create('Could not get location info for address $'+IntToHex(Integer(Address), 8));
Result := locationInfo;
finally
infoList.Free;
end;
finally
FreeLibrary(module);
end;
end;
За исключением того, что код в одном из классов-потомков TJclDebugInfoSource
получает недостаточное значение, когда пытается преобразовать виртуальный адрес в адрес смещения.