LordDoskias
LordDoskias

Reputation: 3191

DRIVER_OBJECT.DriverSection

Does anyone have an idea what is the structure of the DriverSection pointer in the x64 bit version of win7. In 32 bit I used the following:

typedef struct _KLDR_DATA_TABLE_ENTRY {
   LIST_ENTRY InLoadOrderLinks;
   PVOID ExceptionTable;
   ULONG ExceptionTableSize;
   //ULONG padding1;
   PVOID GpValue;
   PVOID NonPagedDebugInfo;
   PVOID DllBase;
   PVOID EntryPoint;
   ULONG SizeOfImage;
   UNICODE_STRING FullDllName;
   UNICODE_STRING BaseDllName;
   ULONG Flags;
   USHORT LoadCount;
   USHORT __Unused5;
   PVOID SectionPointer;
   ULONG CheckSum;
   //ULONG Padding2;
   PVOID LoadedImports;
   PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY; 

And everything was working but on x64 it is crashing when trying to dereference the LIST_ENTRY. Any pointers/tips would be greatly appreciated

Upvotes: 1

Views: 3388

Answers (1)

user257111
user257111

Reputation:

And everything was working but on x64 it is crashing when trying to dereference the LIST_ENTRY. Any pointers/tips would be greatly appreciated

If you can hook up a kernel debugger, you can verify whether or not the DriverSection object matches your definition. To do this, pick a driver you wish to debug - I tend to use a simple one I have. Load its symbols by fixing the symbol path to include its pdb, then break into windbg or kd and type:

.reload

To reload the symbols. Then you can load the driver with:

sc start drivername

having created its service assuming it is a legacy driver. Type:

bu drivername!DriverEntry

to set a breakpoint on the DriverEntry for this module. The difference between bp and bu is that bu breakpoints are evaluated and set on module load. Currently, of course, DriverEntry won't be called, but if we reload the driver it will:

sc stop drivername
sc start drivername

Now your breakpoint should be hit and rcx will contain the DRIVER_OBJECT structure, since it is a pointer argument and pointer/integer arguments are passed in rcx,rdx,r8,r9 according to the Windows ABI. So, you can print out the driver object structure with:

dt _DRIVER_OBJECT (address of rcx)

Which will give you a pointer to the driver section. Then, type:

dt _LDR_DATA_TABLE_ENTRY (driver section object pointer)

This should give you your driver section object. _LDR_DATA_TABLE_ENTRY is actually present in the Windows symbols, so this will work.

Using the debugger, you should be able to dereference the LIST_ENTRY pointers (.flink and .blink) successfully (try dpps on the address of the _LDR_DATA_TABLE_ENTRYstructure, for example). If you do it successfully, one of those addresses will resolve tont!PsLoadedModuleList`.


What I'm trying to say is that in a roundabout way, is that:

  1. Either there is a bug in your code somewhere, or
  2. You've hit upon a synchronisation issue. Remember, this structure is supposed to be opaque and we're not supposed to be modifying it in any way. It's also liable to change on us, and we don't know where the lock for synchronising access to it is.

If you are certain 1 is not the case, it is likely 2 is. Luckily, Microsoft actually provided a function to get the information from these structures called AuxKlibQueryModuleInformation(). You do need to add an extra library to your driver, but that's not the end of the world. Include Aux_klib.h. There's also a code sample on the MSDN page showing how to use it - it's pretty straightforward.

Upvotes: 1

Related Questions