Is there a way to access the Jedi Debug Information (JDBG) contained in an executable?
Microsoft debugging tools have pointed me to a stack chain in my binary, and i want to know what methods/procedures/functions these offsets correspond to:
user32.dll!SendMessageA+0x4c
StackOverflow.exe+0x179263
StackOverflow.exe+0x2315b5
StackOverflow.exe+0x1fc82
StackOverflow.exe+0x50388
StackOverflow.exe+0x541fe
user32.dll!gapfnScSendMessage+0x332
Obviously i'm calling SendMessage, but i don't know from where. The executable was built with Jcl Debug info embedded in the executable; but i can't figure out how to read it.
Looking at some of the functions and classes in JclDebug.pas, everything seems to be geared around getting debug information for inside the current process, e.g.:
function GetLocationInfo(const Addr: Pointer; var Info: TJclLocationInfo): Boolean;
takes an address in my current process's address space. It the figures out which HMODULE the address is in, e.g.:
- Stackoverflow.exe
- GDI32.dll
- USER32.dll
- KERNELBASE.dll
- dwmapi.dll
- UxTheme.dll
i was thinking i could use LoadLibrary (which returns an HMODULE) to manually load a module, then feed it to some of the classes that dig through module images for debug info:
module := LoadLibrary('C:\Users\Ian\Desktop\StackOverflow.exe');
and
TJclDebugInfoList = class(TObjectList)
private
function GetItemFromModule(const Module: HMODULE): TJclDebugInfoSource;
...
protected
function CreateDebugInfo(const Module: HMODULE): TJclDebugInfoSource;
...
end;
except it's protected.
i'm trying (hoping) i can write a tool where i pick the binary (*.exe), enter an address, and get returned the
- function
- method
- file
- line number
of the offset.
e.g.
[002315B5] FMain.TfrmMain.lvQuestions (Line 158, "FMain.pas" + 1) + $11
Possible?
Edit: My first, rough and ready approach, was to just extract the compressed map file so i could look at it. But it's not saved as a resource (?):

Although a general tool would be more useful:

Update:
i tried using TJclDebugInfoList; i realized that the array property ItemFromModule would access the protected method:
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;
Except that the code in one of the TJclDebugInfoSource descendant classes gets an underflow when it tries to convert what it assumes is a virtual address to an offset address.
