SymLoadModuleEx() with IMAGE_DEBUG_DIRECTORY data

Hi

This is pretty off-topic but that’s the only place I know there are people
bright enough to have an idea of solution. :slight_smile: If there’s a better place to
ask this kind of question, just tell me.

I have a logging system. For each PE I save in a log file:

  • base name
  • base address
  • IMAGE_DEBUG_DIRECTORY +
  • its pointed data directly got from the file in memory. (Begins with
    “RSDS”)

Then I save some EIP to be able to translate them back to source file/line
number latter.

Later, in another program, I’d like to be able to use the symbol server to
find back the right PDB and be able to do the translation of EIP -> source
file/line number. So I read the info I saved in my log file and calls
SymLoadModuleExW():
MODLOAD_DATA md;
md.ssize = sizeof(md);
md.ssig = DBHHEADER_DEBUGDIRS;
md.data = pImageDebugDir;
md.size = sizeof(IMAGE_DEBUG_DIRECTORY);
md.flags = 0;
SymLoadModuleExW(GetCurrentProcess(), NULL, BaseName, NULL, BaseAddress,
0, &md, 0);

Here’s the debug output I get:
DBGHELP: unrecognized OMF sig: 0
DBGHELP: TestEventLog - no symbols loaded

I was wondering if AddressOfRawData must be relative to some other pointer
or not (pImageDebugDir or BaseAddress). The documentation seems to say so
but I’m not sure in reality. Currently I set it to the value of a pointer
that I allocated to contain the data collected from the file. So it is not
relative. But I tried almost every way and except some exception, I’ve been
unable to get anything from this function. Except AddressOfRawData,
everything else is kept “stock” from the PE.

Thanks

M-A

Try setting AddressOfRawData to zero and set PointerToRawData to be the
offset from the beginning of the struct to the codeview record.

Jason

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Marc-Antoine
Ruel
Sent: Wednesday, July 20, 2005 1:58 PM
To: Kernel Debugging Interest List
Subject: [windbg] SymLoadModuleEx() with IMAGE_DEBUG_DIRECTORY data

Hi

This is pretty off-topic but that’s the only place I know there are
people
bright enough to have an idea of solution. :slight_smile: If there’s a better place
to
ask this kind of question, just tell me.

I have a logging system. For each PE I save in a log file:

  • base name
  • base address
  • IMAGE_DEBUG_DIRECTORY +
  • its pointed data directly got from the file in memory. (Begins with
    “RSDS”)

Then I save some EIP to be able to translate them back to source
file/line
number latter.

Later, in another program, I’d like to be able to use the symbol server
to
find back the right PDB and be able to do the translation of EIP ->
source
file/line number. So I read the info I saved in my log file and calls
SymLoadModuleExW():
MODLOAD_DATA md;
md.ssize = sizeof(md);
md.ssig = DBHHEADER_DEBUGDIRS;
md.data = pImageDebugDir;
md.size = sizeof(IMAGE_DEBUG_DIRECTORY);
md.flags = 0;
SymLoadModuleExW(GetCurrentProcess(), NULL, BaseName, NULL,
BaseAddress,
0, &md, 0);

Here’s the debug output I get:
DBGHELP: unrecognized OMF sig: 0
DBGHELP: TestEventLog - no symbols loaded

I was wondering if AddressOfRawData must be relative to some other
pointer
or not (pImageDebugDir or BaseAddress). The documentation seems to say
so
but I’m not sure in reality. Currently I set it to the value of a
pointer
that I allocated to contain the data collected from the file. So it is
not
relative. But I tried almost every way and except some exception, I’ve
been
unable to get anything from this function. Except AddressOfRawData,
everything else is kept “stock” from the PE.

Thanks

M-A


You are currently subscribed to windbg as: xxxxx@winse.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Thanks for the idea.

But, I have the mixed feeling that I’m the first one to try this function
this way.

I worked after some tweaking. So I share my observations since it took me a
while to find out how to use this beast.

So here are my observations:

  • As you said Jason, pImageDebugDir->AddressOfRawData is unused. So
    pImageDebugDir->AddressOfRawData = 0;
  • You MUST have colagulated the debug data from the PE just after the
    IMAGE_DEBUG_DIRECTORY.
  • You MUST use
    pImageDebugDir->PointerToRawData = sizeof(IMAGE_DEBUG_DIRECTORY);
  • You MUST use
    md.size = sizeof(IMAGE_DEBUG_DIRECTORY)+pImageDebugDir->SizeOfData;
    Contrary to what the doc says, data member is *NOT* an array of
    IMAGE_DEBUG_DIRECTORY structures but instead a pointer to the
    IMAGE_DEBUG_DIRECTORY and the debug data colagulated in one block and .size
    must be the total size of this otherwise it crashes in
    RetrievePdbInfo(_IMGHLP_DEBUG_DATA *)+0x2D (0x0303DE9D) when it try to load
    a DWORD to compare it to ‘01BN’ and ‘SDSR’.
  • So please update the doc.

From this point, I was able to see this:
DBGHELP: .\PE.pdb - file not found
DBGHELP: .\symbols\dll\PE.pdb - file not found
DBGHELP: .\dll\PE.pdb - file not found
DBGHELP: SymSrv load failure: symsrv.dll
DBGHELP: PE - private symbols & lines
DBGHELP: d:[my build path]\Debug\PE.pdb
DBGHELP: PE - no symbols loaded

Well, my _NT_SYMBOL_PATH=SRV*S:*T:\ and it never searched there! But
symsrv.dll is in the path.
So I copied symsrv.dll in the same directory even though my path contains
“C:\Program Files\Debugging Tools for Windows”

And now:
DBGHELP: .\PE.pdb - file not found
DBGHELP: .\symbols\dll\PE.pdb - file not found
DBGHELP: .\dll\PE.pdb - file not found
‘MyExe.exe’: Loaded ‘D:[my exe path]\debug\symsrv.dll’, Exports loaded.
DBGHELP: PE - private symbols & lines
S:\PE.pdb\8EB639163A9A4D16994C528035BB2A211\PE.pdb

Well… It Worked! It happens sometimes when you take more than an hour to
write a mail. :slight_smile: I’ll try to verify why it didn’t find symsrv.dll but for
now I’ll just copy it with my exe.

Thanks to have set me on the right path.

M-A

“Jason Shay” a écrit dans le message de news:
xxxxx@windbg…
Try setting AddressOfRawData to zero and set PointerToRawData to be the
offset from the beginning of the struct to the codeview record.

Jason

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Marc-Antoine
Ruel
Sent: Wednesday, July 20, 2005 1:58 PM
To: Kernel Debugging Interest List
Subject: [windbg] SymLoadModuleEx() with IMAGE_DEBUG_DIRECTORY data

Hi

This is pretty off-topic but that’s the only place I know there are
people
bright enough to have an idea of solution. :slight_smile: If there’s a better place
to
ask this kind of question, just tell me.

I have a logging system. For each PE I save in a log file:
- base name
- base address
- IMAGE_DEBUG_DIRECTORY +
- its pointed data directly got from the file in memory. (Begins with
“RSDS”)

Then I save some EIP to be able to translate them back to source
file/line
number latter.

Later, in another program, I’d like to be able to use the symbol server
to
find back the right PDB and be able to do the translation of EIP ->
source
file/line number. So I read the info I saved in my log file and calls
SymLoadModuleExW():
MODLOAD_DATA md;
md.ssize = sizeof(md);
md.ssig = DBHHEADER_DEBUGDIRS;
md.data = pImageDebugDir;
md.size = sizeof(IMAGE_DEBUG_DIRECTORY);
md.flags = 0;
SymLoadModuleExW(GetCurrentProcess(), NULL, BaseName, NULL,
BaseAddress,
0, &md, 0);

Here’s the debug output I get:
DBGHELP: unrecognized OMF sig: 0
DBGHELP: PE - no symbols loaded

I was wondering if AddressOfRawData must be relative to some other
pointer
or not (pImageDebugDir or BaseAddress). The documentation seems to say
so
but I’m not sure in reality. Currently I set it to the value of a
pointer
that I allocated to contain the data collected from the file. So it is
not
relative. But I tried almost every way and except some exception, I’ve
been
unable to get anything from this function. Except AddressOfRawData,
everything else is kept “stock” from the PE.

Thanks

M-A


You are currently subscribed to windbg as: xxxxx@winse.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

I think I answered too fast. My calls to SymFromAddr() and
SymGetLineFromAddr64() are returning ERROR_MOD_NOT_FOUND (126)

In documentation for:
BOOL SymInitialize(HANDLE hProcess, PCTSTR UserSearchPath, BOOL
fInvadeProcess);

hProcess: [in] Handle that identifies the caller. This value should be
unique, *but need not be a process handle*. However, if you do use a process
handle, be sure to use the correct handle. (…)

I was using as handle GetCurrentProcess() but I think I should use NULL
since I’m not really playing with my own process. So it gives
SymInitialize(NULL, NULL, FALSE);

But when I use NULL, during the SymLoadModuleExW(NULL, …) call, it crashes
in ReadImageData() (0x0303E1A5) during a memcpy. It tries to load data at
BaseAddress value I passed to it! But this base adress is invalid because
the DLL that logged is not loaded in my log reader. I just want it to find
my symbols back, not play with my process’ memory.

So I don’t know what to do since the only way I’m able to get my symbols is
when I use GetCurrentProcess() as handle and LoadLibrary(“PE”) before the
SymLoadModuleExW() call. But obviously I don’t want to load the DLL into
memory, since the version in the log may be different from the one that I
loaded.

ps: I’m using
SymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_EXACT_SYMBOLS|SYMOPT_DEBUG);
and latest dbghelp.dll

But still, it should be doable since the minidumps are exactly this.

As you may have found out, I’m doing this for user land but I don’t know how
it could work for kernel drivers since you can’t LoadLibrary() a .SYS
anyway.

As a note, in google, “SymInitialize(GetCurrentProcess())” gives many hits
but “SymInitialize(NULL” (or 0) gives no hit.

Thanks

M-A

“Marc-Antoine Ruel” a écrit dans le message de news:
xxxxx@windbg…
> Thanks for the idea.
>
> But, I have the mixed feeling that I’m the first one to try this function
> this way.
>
> I worked after some tweaking. So I share my observations since it took me
> a while to find out how to use this beast.
>
> So here are my observations:
> - As you said Jason, pImageDebugDir->AddressOfRawData is unused. So
> pImageDebugDir->AddressOfRawData = 0;
> - You MUST have colagulated the debug data from the PE just after the
> IMAGE_DEBUG_DIRECTORY.
> - You MUST use
> pImageDebugDir->PointerToRawData = sizeof(IMAGE_DEBUG_DIRECTORY);
> - You MUST use
> md.size = sizeof(IMAGE_DEBUG_DIRECTORY)+pImageDebugDir->SizeOfData;
> Contrary to what the doc says, data member is NOT an array of
> IMAGE_DEBUG_DIRECTORY structures but instead a pointer to the
> IMAGE_DEBUG_DIRECTORY and the debug data colagulated in one block and
> .size must be the total size of this otherwise it crashes in
> RetrievePdbInfo(_IMGHLP_DEBUG_DATA )+0x2D (0x0303DE9D) when it try to
> load a DWORD to compare it to ‘01BN’ and ‘SDSR’.
> - So please update the doc.
>
> From this point, I was able to see this:
> DBGHELP: .\PE.pdb - file not found
> DBGHELP: .\symbols\dll\PE.pdb - file not found
> DBGHELP: .\dll\PE.pdb - file not found
> DBGHELP: SymSrv load failure: symsrv.dll
> DBGHELP: PE - private symbols & lines
> DBGHELP: d:[my build path]\Debug\PE.pdb
> DBGHELP: PE - no symbols loaded
>
> Well, my _NT_SYMBOL_PATH=SRV
S:*T:\ and it never searched there! But
> symsrv.dll is in the path.
> So I copied symsrv.dll in the same directory even though my path contains
> “C:\Program Files\Debugging Tools for Windows”
>
> And now:
> DBGHELP: .\PE.pdb - file not found
> DBGHELP: .\symbols\dll\PE.pdb - file not found
> DBGHELP: .\dll\PE.pdb - file not found
> ‘MyExe.exe’: Loaded ‘D:[my exe path]\debug\symsrv.dll’, Exports loaded.
> DBGHELP: PE - private symbols & lines
> S:\PE.pdb\8EB639163A9A4D16994C528035BB2A211\PE.pdb
>
> Well… It Worked! It happens sometimes when you take more than an hour to
> write a mail. :slight_smile: I’ll try to verify why it didn’t find symsrv.dll but for
> now I’ll just copy it with my exe.
>
> Thanks to have set me on the right path.
>
> M-A
>
> “Jason Shay” a écrit dans le message de news:
> xxxxx@windbg…
> Try setting AddressOfRawData to zero and set PointerToRawData to be the
> offset from the beginning of the struct to the codeview record.
>
> Jason
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Marc-Antoine
> Ruel
> Sent: Wednesday, July 20, 2005 1:58 PM
> To: Kernel Debugging Interest List
> Subject: [windbg] SymLoadModuleEx() with IMAGE_DEBUG_DIRECTORY data
>
> Hi
>
> This is pretty off-topic but that’s the only place I know there are
> people
> bright enough to have an idea of solution. :slight_smile: If there’s a better place
> to
> ask this kind of question, just tell me.
>
>
> I have a logging system. For each PE I save in a log file:
> - base name
> - base address
> - IMAGE_DEBUG_DIRECTORY +
> - its pointed data directly got from the file in memory. (Begins with
> “RSDS”)
>
> Then I save some EIP to be able to translate them back to source
> file/line
> number latter.
>
>
> Later, in another program, I’d like to be able to use the symbol server
> to
> find back the right PDB and be able to do the translation of EIP ->
> source
> file/line number. So I read the info I saved in my log file and calls
> SymLoadModuleExW():
> MODLOAD_DATA md;
> md.ssize = sizeof(md);
> md.ssig = DBHHEADER_DEBUGDIRS;
> md.data = pImageDebugDir;
> md.size = sizeof(IMAGE_DEBUG_DIRECTORY);
> md.flags = 0;
> SymLoadModuleExW(GetCurrentProcess(), NULL, BaseName, NULL,
> BaseAddress,
> 0, &md, 0);
>
>
> Here’s the debug output I get:
> DBGHELP: unrecognized OMF sig: 0
> DBGHELP: PE - no symbols loaded
>
>
> I was wondering if AddressOfRawData must be relative to some other
> pointer
> or not (pImageDebugDir or BaseAddress). The documentation seems to say
> so
> but I’m not sure in reality. Currently I set it to the value of a
> pointer
> that I allocated to contain the data collected from the file. So it is
> not
> relative. But I tried almost every way and except some exception, I’ve
> been
> unable to get anything from this function. Except AddressOfRawData,
> everything else is kept “stock” from the PE.
>
> Thanks
>
> M-A
>
>
> —
> You are currently subscribed to windbg as: xxxxx@winse.microsoft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>

Hello,
Can you send along a little app/source/target pdb that reproduces the crashes to xxxxx@microsoft.com so we can have a look?

Thanks,
Jason

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Marc-Antoine Ruel
Sent: Thursday, July 21, 2005 9:11 AM
To: Kernel Debugging Interest List
Subject: Re:[windbg] SymLoadModuleEx() with IMAGE_DEBUG_DIRECTORY data

I think I answered too fast. My calls to SymFromAddr() and
SymGetLineFromAddr64() are returning ERROR_MOD_NOT_FOUND (126)

In documentation for:
BOOL SymInitialize(HANDLE hProcess, PCTSTR UserSearchPath, BOOL
fInvadeProcess);

hProcess: [in] Handle that identifies the caller. This value should be
unique, *but need not be a process handle*. However, if you do use a process
handle, be sure to use the correct handle. (…)

I was using as handle GetCurrentProcess() but I think I should use NULL
since I’m not really playing with my own process. So it gives
SymInitialize(NULL, NULL, FALSE);

But when I use NULL, during the SymLoadModuleExW(NULL, …) call, it crashes
in ReadImageData() (0x0303E1A5) during a memcpy. It tries to load data at
BaseAddress value I passed to it! But this base adress is invalid because
the DLL that logged is not loaded in my log reader. I just want it to find
my symbols back, not play with my process’ memory.

So I don’t know what to do since the only way I’m able to get my symbols is
when I use GetCurrentProcess() as handle and LoadLibrary(“PE”) before the
SymLoadModuleExW() call. But obviously I don’t want to load the DLL into
memory, since the version in the log may be different from the one that I
loaded.

ps: I’m using
SymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_EXACT_SYMBOLS|SYMOPT_DEBUG);
and latest dbghelp.dll

But still, it should be doable since the minidumps are exactly this.

As you may have found out, I’m doing this for user land but I don’t know how
it could work for kernel drivers since you can’t LoadLibrary() a .SYS
anyway.

As a note, in google, “SymInitialize(GetCurrentProcess())” gives many hits
but “SymInitialize(NULL” (or 0) gives no hit.

Thanks

M-A

“Marc-Antoine Ruel” a ?crit dans le message de news:
xxxxx@windbg…
> Thanks for the idea.
>
> But, I have the mixed feeling that I’m the first one to try this function
> this way.
>
> I worked after some tweaking. So I share my observations since it took me
> a while to find out how to use this beast.
>
> So here are my observations:
> - As you said Jason, pImageDebugDir->AddressOfRawData is unused. So
> pImageDebugDir->AddressOfRawData = 0;
> - You MUST have colagulated the debug data from the PE just after the
> IMAGE_DEBUG_DIRECTORY.
> - You MUST use
> pImageDebugDir->PointerToRawData = sizeof(IMAGE_DEBUG_DIRECTORY);
> - You MUST use
> md.size = sizeof(IMAGE_DEBUG_DIRECTORY)+pImageDebugDir->SizeOfData;
> Contrary to what the doc says, data member is NOT an array of
> IMAGE_DEBUG_DIRECTORY structures but instead a pointer to the
> IMAGE_DEBUG_DIRECTORY and the debug data colagulated in one block and
> .size must be the total size of this otherwise it crashes in
> RetrievePdbInfo(_IMGHLP_DEBUG_DATA )+0x2D (0x0303DE9D) when it try to
> load a DWORD to compare it to ‘01BN’ and ‘SDSR’.
> - So please update the doc.
>
> From this point, I was able to see this:
> DBGHELP: .\PE.pdb - file not found
> DBGHELP: .\symbols\dll\PE.pdb - file not found
> DBGHELP: .\dll\PE.pdb - file not found
> DBGHELP: SymSrv load failure: symsrv.dll
> DBGHELP: PE - private symbols & lines
> DBGHELP: d:[my build path]\Debug\PE.pdb
> DBGHELP: PE - no symbols loaded
>
> Well, my _NT_SYMBOL_PATH=SRV
S:*T:\ and it never searched there! But
> symsrv.dll is in the path.
> So I copied symsrv.dll in the same directory even though my path contains
> “C:\Program Files\Debugging Tools for Windows”
>
> And now:
> DBGHELP: .\PE.pdb - file not found
> DBGHELP: .\symbols\dll\PE.pdb - file not found
> DBGHELP: .\dll\PE.pdb - file not found
> ‘MyExe.exe’: Loaded ‘D:[my exe path]\debug\symsrv.dll’, Exports loaded.
> DBGHELP: PE - private symbols & lines
> S:\PE.pdb\8EB639163A9A4D16994C528035BB2A211\PE.pdb
>
> Well… It Worked! It happens sometimes when you take more than an hour to
> write a mail. :slight_smile: I’ll try to verify why it didn’t find symsrv.dll but for
> now I’ll just copy it with my exe.
>
> Thanks to have set me on the right path.
>
> M-A
>
> “Jason Shay” a ?crit dans le message de news:
> xxxxx@windbg…
> Try setting AddressOfRawData to zero and set PointerToRawData to be the
> offset from the beginning of the struct to the codeview record.
>
> Jason
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Marc-Antoine
> Ruel
> Sent: Wednesday, July 20, 2005 1:58 PM
> To: Kernel Debugging Interest List
> Subject: [windbg] SymLoadModuleEx() with IMAGE_DEBUG_DIRECTORY data
>
> Hi
>
> This is pretty off-topic but that’s the only place I know there are
> people
> bright enough to have an idea of solution. :slight_smile: If there’s a better place
> to
> ask this kind of question, just tell me.
>
>
> I have a logging system. For each PE I save in a log file:
> - base name
> - base address
> - IMAGE_DEBUG_DIRECTORY +
> - its pointed data directly got from the file in memory. (Begins with
> “RSDS”)
>
> Then I save some EIP to be able to translate them back to source
> file/line
> number latter.
>
>
> Later, in another program, I’d like to be able to use the symbol server
> to
> find back the right PDB and be able to do the translation of EIP ->
> source
> file/line number. So I read the info I saved in my log file and calls
> SymLoadModuleExW():
> MODLOAD_DATA md;
> md.ssize = sizeof(md);
> md.ssig = DBHHEADER_DEBUGDIRS;
> md.data = pImageDebugDir;
> md.size = sizeof(IMAGE_DEBUG_DIRECTORY);
> md.flags = 0;
> SymLoadModuleExW(GetCurrentProcess(), NULL, BaseName, NULL,
> BaseAddress,
> 0, &md, 0);
>
>
> Here’s the debug output I get:
> DBGHELP: unrecognized OMF sig: 0
> DBGHELP: PE - no symbols loaded
>
>
> I was wondering if AddressOfRawData must be relative to some other
> pointer
> or not (pImageDebugDir or BaseAddress). The documentation seems to say
> so
> but I’m not sure in reality. Currently I set it to the value of a
> pointer
> that I allocated to contain the data collected from the file. So it is
> not
> relative. But I tried almost every way and except some exception, I’ve
> been
> unable to get anything from this function. Except AddressOfRawData,
> everything else is kept “stock” from the PE.
>
> Thanks
>
> M-A
>
>
> —
> You are currently subscribed to windbg as: xxxxx@winse.microsoft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>


You are currently subscribed to windbg as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com