A forum for reverse engineering, OS internals and malware analysis 

Ask your beginner questions here.
 #11271  by lorddoskias
 Wed Jan 25, 2012 9:36 pm
The following code I wrote works perfectly on 32 bit win 7 :
Code: Select all
PVOID GetNtosBaseAddr(PDRIVER_OBJECT DriverObject) {

	PKLDR_DATA_TABLE_ENTRY driverSection;
	PKLDR_DATA_TABLE_ENTRY ldrDataTableEntry;
	PVOID kernelBase = NULL;
	PLIST_ENTRY headEntry;
	PLIST_ENTRY currentEntry;
	UNICODE_STRING ntosString = {0};
	driverSection = (PKLDR_DATA_TABLE_ENTRY) DriverObject->DriverSection;
	RtlInitUnicodeString(&ntosString, L"ntoskrnl.exe");

	headEntry = driverSection->InLoadOrderLinks.Blink; //header points to prev entry

	currentEntry = headEntry->Flink;

	while(currentEntry != headEntry) {

		ldrDataTableEntry = CONTAINING_RECORD(currentEntry, KLDR_DATA_TABLE_ENTRY, InLoadOrderLinks);

		if(RtlCompareUnicodeString(&ntosString, &ldrDataTableEntry->BaseDllName, TRUE) == 0) {
			DbgPrint("Found base address of NTOSKRNL: 0x%p\n", ldrDataTableEntry->DllBase );

			kernelBase = ldrDataTableEntry->DllBase;

			break;
		}

		currentEntry = currentEntry->Flink;
	}

	return kernelBase;

}
However on x64 bit win7 with PG disabled by fyyre's method it crashes when it tries to dereference ldrDataTableEntry->BaseDllName ON THE SECOND RUN. So the first time I'm in the loop ldrDataTableEntry points to the data_table_entry of my driver, but then on the second pass ldrDataTableEntry points to erroneous memory location and when RtlCompareUnicodeString tries to compare I get bugcheck invalid_memory?
Code: Select all
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;  
I have tried the following combination:
1. All LIST_ENTRIES were redefined as LIST_ENTRIES64 (respectively PLIST_ENTRIES64) - same result
2. Uncommented Padding1 and Padding2 since in the WRK sources they have put up comments that there should be ULONG paddings on IA64 (doubt it will work) - same result.


It is strange because even before I get into the loop I do list_entry manipulation by first setting the header to the previous entries, and then utilising the linked=list to point to the current (my driver) but on the second pass in the loop it crashes? :?:
 #11283  by EP_X0FF
 Thu Jan 26, 2012 9:50 am
It is time to finally start using well documented and absolutely no-problem x86-amd64-ia64 portable methods.
However on x64 bit win7 with PG disabled
Absolutely unneeded, unless you are not hacking system tables, which is strictly permitted.

If you need to load unsigned driver - select special test boot mode (F8 while windows startup).