gpt4 book ai didi

delphi - 访问可执行文件中包含的 JCL 调试信息?

转载 作者:行者123 更新时间:2023-12-03 15:53:15 25 4
gpt4 key购买 nike

有没有办法访问可执行文件中包含的Jedi调试信息(JDBG)?

微软调试工具向我指出了二进制文件中的堆栈链,我想知道这些偏移量对应的方法/过程/函数:

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文件,以便我可以查看它。但它没有保存为资源 (?):

enter image description here

虽然通用工具会更有用:

enter image description here

<小时/>

更新:

我尝试使用TJclDebugInfoList;我意识到数组属性 ItemFromModule 将访问 protected 方法:

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 后代类之一中的代码在尝试将其假定的虚拟地址转换为偏移地址时会发生下溢。

最佳答案

使用从 LoadLibrary 获取的 HModule 句柄创建一个 TJclDebugInfoBinary 对象。然后对其调用GetLocationInfo。这就是 TJclDebugInfoList 无论如何都会做的,除了它有一些辅助方法来将地址从当前地址空间映射到它们对应的模块,而当您手动执行此操作时,您必须已经知道地址属于哪个模块。 (但是故障转储已经告诉了您这部分,因此您不需要列表类的帮助。)

您可能需要修改地址,因为崩溃时模块的基地址与您使用 LoadLibrary 加载模块时的基地址不同。

JCL 调试信息未存储在资源中。它存储在名为 JCLDEBUG 的 PE 节中。请参阅 JclDebug.pasPeMapImgFindSection32PeMapImgFindSectionFromModule 的使用。

关于delphi - 访问可执行文件中包含的 JCL 调试信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6019698/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com