Tech Support > Microsoft Windows > Drivers > obtain driver checksum and timestamp?
obtain driver checksum and timestamp?
Posted by Hannes on April 5th, 2005


My driver needs to find out checksum & timestamp for other drivers in the
system. Is there *any* way to do this from within a driver?

[I'm happy to hear about both documented, and undocumented ways.
We need this to generate minidumps from our driver crashes.]


Any input appreciated,

/ Hannes.

Posted by James Antognini [MSFT] on April 5th, 2005


The !lmi extension in WinDbg seems capable of this, so the information is
somewhere.

--
James Antognini
Windows DDK Support


This posting is provided "AS IS" with no warranties, and confers no rights.



"Hannes" <hannes.news@nospam.nospam> wrote in message
news:C211046B-C553-424B-9668-A30B7B26E8A7@microsoft.com...


Posted by Steve on April 6th, 2005


Register a callback using PsSetLoadImageNotifyRoutine().
Callback is called when exe,sys,dll is loaded and in this
function you can obtain filename and path. From here the
only way I know how is to open the driver file and then
get checksum, etc. from PE header. One drawback is that
the filename and path is in the
form "Device\HardiskVolume1\Windows\System\driver.s ys" so
you must figure out drive letter. Perhaps there is a way
of getting to PE header that is loaded in memory instead
of opening file.

I use image load callback with a user mode app and give
the user mode app the process id and it uses OpenProcess
(), EnumProcessModules() and GetModuleFileNameEx() to get
a filename (with a driver letter in it) that I can then
open!

Search ddk help for Nerditorium articals on procview
and "Signaling Using Event Handles"


Steve.
Remove _ZXXZ_ for valid email address.


Posted by Hannes on April 20th, 2005


The solution was to find the PE header, near the beginning of each module in
memory. The PE structure holds information on both checksum and timestamp.

I have noticed, however, that we for a few drivers can NOT access the module
memory, which causes an exception. Probes do not seem to work in kernel mode.
Is there any other way to know what modules our driver has the permission to
access?


/ Hannes.

Posted by Maxim S. Shatskih on April 20th, 2005


Try to access the memory on PASSIVE_LEVEL under __try/__except. This is
what Probe does, but they also check for the address to be user mode, which is
not needed for you.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com

"Hannes" <hannes.news@nospam.nospam> wrote in message
news:34DB19D3-6A96-4182-AE12-E6C36D7AD0DB@microsoft.com...


Posted by Hannes on April 21st, 2005


KeGetCurrentIrql returns 0 (PASSIVE_LEVEL), but I'm still crashing instead of
entering the __except, when trying to access a "bad" address.

All this actually occurs inside the exception handler for my driver - is it
possible to put this suggested __try/__except block inside another
__try/__except block of mine?

/ Hannes.

Posted by Hannes on April 21st, 2005


Just to show you what I'm doing, inside my exception handler:

KIRQL oldIrql = KeGetCurrentIrql(); // returns 0, no need to change IRQL
__try {
IMAGE_NT_HEADERS32 *pPeHdr = (IMAGE_NT_HEADERS32*)
((UINT8*)pModule->Base + pDosHdr->e_lfanew);
} __except(EXCEPTION_EXECUTE_HANDLER) {
DbgPrint("failed to access module at irql %d\n", oldIrql);
PsTerminateSystemThread(0);
}


I get a crash when trying to access 0xbf80003c, which is within module
memory for win32k.sys (start 0xbf800000 - end bf9de000).

Crash analysis below. [The stack trace appears to be my forced crash (NULL
pointer access) inside ProcessIpPacket(), which I'm using to execute my
exception handler.]

My exception handler is in turn generating a minidump, and therefore needs
to figure out information onloaded modules. I can get to almost all modules,
except for 3-4 modules that cause this problematic crash in WriteMinidump().


/ Hannes.



3
kd> !analyze -v
************************************************** *****************************
*
*
* Bugcheck Analysis
*
*
*
************************************************** *****************************

PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced. This cannot be protected by try-except,
it must be protected by a Probe. Typically the address is just plain bad or
it
is pointing at freed memory.
Arguments:
Arg1: bf80003c, memory referenced.
Arg2: 00000000, value 0 = read operation, 1 = write operation.
Arg3: b9b8e3c0, If non-zero, the instruction address which referenced the
bad memory
address.
Arg4: 00000002, (reserved)

Debugging Details:
------------------

OVERLAPPED_MODULE: rdbss

READ_ADDRESS: bf80003c Nonpaged pool

FAULTING_IP:
spm!WriteMiniDump+580 [f:\projects\shoutdev\spm\minidump.cpp @ 258]
b9b8e3c0 03503c add edx,[eax+0x3c]

MM_INTERNAL_CODE: 2

IMAGE_NAME: spm.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 42682647

MODULE_NAME: spm

FAULTING_MODULE: b9b1b000 spm

DEFAULT_BUCKET_ID: INTEL_CPU_MICROCODE_ZERO

BUGCHECK_STR: 0x50

CURRENT_IRQL: 0

LAST_CONTROL_TRANSFER: from b9b435da to b9b6375d

TRAP_FRAME: ba6a0488 -- (.trap ffffffffba6a0488)
ErrCode = 00000000
eax=bf800000 ebx=00000000 ecx=8484653c edx=bf800000 esi=84847818 edi=84880000
eip=b9b8e3c0 esp=ba6a04fc ebp=ba6a06b0 iopl=0 nv up ei pl zr na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246
spm!WriteMiniDump+0x580:
b9b8e3c0 03503c add edx,[eax+0x3c]
Resetting default scope

STACK_TEXT:
ba6a0cb0 b9b435da 85d95230 845c5fac 0000004a spm!ProcessIpPacket+0x5d
[f:\projects\shoutdev\spm\spm.c @ 7760]
ba6a0cf8 b9b66689 85d95230 839cb010 badcfe01 spm!RouteDatagram+0x36a
[f:\projects\shoutdev\spm\spm.c @ 3824]
ba6a0d64 b9b65942 00000000 85f0e2b0 00000000 spm!ProcessAllPackets+0x799
[f:\projects\shoutdev\spm\spm.c @ 8334]
ba6a0dac 808b864d 00000000 00000000 00000000 spm!SPMMain+0xa2
[f:\projects\shoutdev\spm\spm.c @ 8191]
ba6a0ddc 8080fda6 b9b658a0 00000000 00000000 nt!PspSystemThreadStartup+0x2e
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16


FOLLOWUP_IP:
spm!WriteMiniDump+580 [f:\projects\shoutdev\spm\minidump.cpp @ 258]
b9b8e3c0 03503c add edx,[eax+0x3c]

SYMBOL_STACK_INDEX: 0

FOLLOWUP_NAME: MachineOwner

SYMBOL_NAME: spm!WriteMiniDump+580

STACK_COMMAND: .trap ffffffffba6a0488 ; kb

FAILURE_BUCKET_ID: 0x50_spm!WriteMiniDump+580

BUCKET_ID: 0x50_spm!WriteMiniDump+580

Followup: MachineOwner
---------


Posted by Jerry Schneider on April 28th, 2005


Hannes wrote:
In most production drivers, the initialization code is marked for discard after
driverEntry because it won't be needed again. The PE header info seems to be
a similar target for discard since the module has loaded (thus import/export
tables, header info, etc. are no longer needed).

What do you see from a 'dd' in windbg at the offending address? My guess is
a bunch of ?????s, indicating unmapped, freed memory.

Then again, I don't know why some drivers seem to keep their PE headers around
in memory because you can apparently access them without faulting.

Anyone know what the "rule" is on freeing portions of the image file map after
a driver has loaded?

Jerry Schneider

Posted by Hannes on April 28th, 2005


One data point here might be that WinDbg is capable of accessing the PE
header, at least I assume so, since it can report timestamp & checksum for
ALL loaded modules.

The same goes for memory.dmp files generated by Windows.

How do they get this information? Do they not read it from the module itself?

/ Hannes.