Is there a way to access the Jugi Debug Information (JDBG) contained in the executable?
Microsoft's debugging tools pointed me to the stack chain in my binary, and I want to know which methods / procedures / functions correspond to these offsets:
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 where from. The executable was created with Jcl Debug information 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 focused on getting debug information inside the current process, for example:
function GetLocationInfo(const Addr: Pointer; var Info: TJclLocationInfo): Boolean;
accepts an address in my current process address space. These are the numbers in which HMODULE is the address, for example:
- Stackoverflow.exe
- Gdi32.dll
- USER32.dll
- KERNELBASE.dll
- dwmapi.dll
- UXTheme.dll
I thought I could use LoadLibrary (which returns an HMODULE ) to manually load a module, and then pass it to some classes that look at module images for debugging information:
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 protected.
I try (hopefully), I can write a tool where I select the binary (* .exe), enter the address and return
- Function
- method
- file
- line number
displacement.
eg.
[002315B5] FMain.TfrmMain.lvQuestions (Line 158, "FMain.pas" + 1) + $11
Possible?
Edit: My first, rough and off-the-shelf approach was to simply extract the compressed map file so that I can look at it. But it is not saved as a resource (?):

Although a general tool would be more useful:

Update
I tried using TJclDebugInfoList ; I realized that the property of the ItemFromModule array will gain access to 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 TJclDebugInfoSource receives a lower thread when it tries to translate what it assumes is a virtual address to an offset address.