#ifdef USE_PAGETABLE_TO_OBTAIN_TEXTMODE_VIDEOADDRESS
PhysAddressToLinearAddresses( & extension->pvTextVideoBuffer, 1, NULL, 0xB8000 );
#else
{
PHYSICAL_ADDRESS paPhysAddr;
paPhysAddr.QuadPart = 0xB8000;
extension->dglLayouts.pvTextVideoBuffer = MmMapIoSpace( paPhysAddr, 1, MmNonCached );
}
#endif
NTSTATUS PhysAddressToLinearAddresses( OUT PVOID* ppvOutputVector, IN ULONG ulOutputVectorSize, OUT ULONG* pulOutputVectorRetItemsNum, IN DWORD dwPhysAddress )
NTSTATUS nsRetVal = STATUS_SUCCESS;
DWORD* pdwPageDir = (DWORD*) 0xC0300000;
ULONG i, j;
DWORD dwPageDirEntry, dwPageTblEntry;
DWORD* pdwPageTable;
DWORD dwPageTblEntryPhysAddress[ 2 ];
ULONG ulOutputVectorPos = 0;
if ( pulOutputVectorRetItemsNum )
* pulOutputVectorRetItemsNum = 0;
// Search in the Page Directory for the Specified Address.
for ( i=0; i<1024; i++ )
dwPageDirEntry = pdwPageDir[ i ];
// Check if this Page Table has an Address and if its Present bit is set to 1.
if ( ( dwPageDirEntry >> 12 ) &&
( dwPageDirEntry & 0x1 ) )
pdwPageTable = (DWORD*) ( (BYTE*) 0xC0000000 + i * 0x1000 );
for ( j=0; j<1024; j++ )
dwPageTblEntry = pdwPageTable[ j ];
// Check if this Page Table Entry has an associated Physical Address.
if ( dwPageTblEntry >> 12 )
// Calculate the MIN and MAX Phys Address of the Page Table Entry.
dwPageTblEntryPhysAddress[ 0 ] = dwPageTblEntry & 0xFFFFF000;
dwPageTblEntryPhysAddress[ 1 ] = dwPageTblEntryPhysAddress[ 0 ] + 0x1000 - 1;
// Check if our Address is between the Interval.
if ( dwPhysAddress >= dwPageTblEntryPhysAddress[ 0 ] &&
dwPhysAddress <= dwPageTblEntryPhysAddress[ 1 ] )
// Add this Linear Address.
if ( ulOutputVectorPos < ulOutputVectorSize )
ppvOutputVector[ ulOutputVectorPos ++ ] = (PVOID)
( i * 0x400000 + j * 0x1000 +
( dwPhysAddress - dwPageTblEntryPhysAddress[ 0 ] ) );
else
* pulOutputVectorRetItemsNum = ulOutputVectorPos;
return STATUS_SUCCESS;
// Return to the Caller.
return nsRetVal;
PVOID LoadFile( IN PCWSTR pszFileName, IN POOL_TYPE ptPoolType, OUT ULONG* pulSize )
PVOID retval = NULL;
NTSTATUS ntStatus;
HANDLE handle = NULL;
OBJECT_ATTRIBUTES attrs;
UNICODE_STRING unicode_fn;
IO_STATUS_BLOCK iosb;
FILE_STANDARD_INFORMATION info;
ULONG size = 0;
PVOID mem;
LARGE_INTEGER zeropos;
memset( & zeropos, 0, sizeof( zeropos ) );
// Load the File.
RtlInitUnicodeString( & unicode_fn, pszFileName );
InitializeObjectAttributes( & attrs,
& unicode_fn,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
ntStatus = ZwCreateFile( & handle,
FILE_READ_DATA | GENERIC_READ | SYNCHRONIZE,
& attrs,
& iosb,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS | FILE_SYNCHRONOUS_IO_NONALERT,
0 );
if ( ntStatus == STATUS_SUCCESS && handle )
ntStatus = ZwQueryInformationFile(
handle,
& info,
sizeof( info ),
FileStandardInformation );
if ( ntStatus == STATUS_SUCCESS )
size = info.EndOfFile.LowPart;
mem = ExAllocatePool( ptPoolType, size );
if ( mem )
ntStatus = ZwReadFile(
mem,
size,
& zeropos,
if ( ntStatus != STATUS_SUCCESS || iosb.Information != size )
ExFreePool( mem );
retval = mem;
ZwClose( handle );
// Return.
if ( pulSize && retval )
* pulSize = size;
return retval;
lkd> dt _LDR_DATA_TABLE_ENTRY
+0×000 InLoadOrderLinks : _LIST_ENTRY
+0×008 InMemoryOrderLinks : _LIST_ENTRY
+0×010 InInitializationOrderLinks : _LIST_ENTRY
+0×018 DllBase : Ptr32 Void
+0×01c EntryPoint : Ptr32 Void
+0×020 SizeOfImage : Uint4B
+0×024 FullDllName : _UNICODE_STRING
+0×02c BaseDllName : _UNICODE_STRING
+0×034 Flags : Uint4B
+0×038 LoadCount : Uint2B
+0×03a TlsIndex : Uint2B
static CHAR g_szDiscoverNtoskrnlDriverSectionTempBuffer[ 2 * 1024 ]; // NOTE: sizeof < sizeof( System Page Size )
VOID* DiscoverNtoskrnlDriverSection( IN VOID* pvDriverSection )
LIST_ENTRY* pleListNodePtr;
WORD* pwImageNameLengthPtr;
WORD wImageNameLength;
WORD* pwImageNameUnicodePtr;
DWORD* pdwImageNameUnicodePtrPtr;
WORD* pwWordPtr;
CHAR* pcCharPtr;
ULONG ulI;
// Do the Requested Operation.
pleListNodePtr = (LIST_ENTRY*) pvDriverSection;
while( TRUE )
// Get the Pointer to the Previous Node.
if ( pleListNodePtr == NULL ||
IsPagePresent_DWORD( (DWORD*) ( ( (BYTE*) pleListNodePtr ) + FIELD_OFFSET( LIST_ENTRY, Blink ) ) ) == FALSE )
return NULL;
pleListNodePtr = pleListNodePtr->Blink;
pleListNodePtr == (LIST_ENTRY*) pvDriverSection ||
IsPagePresent( pleListNodePtr ) == FALSE )
// Get the Name of the Module.
pwImageNameLengthPtr = (WORD*) ( ( (BYTE*) pleListNodePtr ) + MACRO_IMAGENAME_FIELDOFFSET_IN_DRVSEC );
if ( IsPagePresent_WORD( pwImageNameLengthPtr ) == FALSE )
wImageNameLength = * pwImageNameLengthPtr / sizeof( WORD );
if ( wImageNameLength == 0 ||
wImageNameLength > sizeof( g_szDiscoverNtoskrnlDriverSectionTempBuffer ) - 1 )
pdwImageNameUnicodePtrPtr = (DWORD*) ( ( (BYTE*) pleListNodePtr ) +
MACRO_IMAGENAME_FIELDOFFSET_IN_DRVSEC + FIELD_OFFSET( UNICODE_STRING, Buffer ) );
if ( IsPagePresent_DWORD( pdwImageNameUnicodePtrPtr ) == FALSE )
pwImageNameUnicodePtr = (WORD*) * pdwImageNameUnicodePtrPtr;
if ( pwImageNameUnicodePtr == NULL ||
IsPagePresent( pwImageNameUnicodePtr ) == FALSE )
if ( IsPagePresent_WORD( pwImageNameUnicodePtr + wImageNameLength - 1 ) == FALSE )
pwWordPtr = pwImageNameUnicodePtr;
pcCharPtr = g_szDiscoverNtoskrnlDriverSectionTempBuffer;
for ( ulI = 0; ulI < wImageNameLength; ulI ++ )
* pcCharPtr ++ = (CHAR) ( ( * pwWordPtr ++ ) & 0xFF );
* pcCharPtr = '\0';
_strupr( g_szDiscoverNtoskrnlDriverSectionTempBuffer );
// Check for the Presence of the NTOSKRNL Module Name.
if ( strstr( g_szDiscoverNtoskrnlDriverSectionTempBuffer, MACRO_NTOSKRNL_MODULENAME_UPPERCASE ) )
return pleListNodePtr;
#pragma pack(push, 1)
typedef struct _VAD
VOID* pvStartingAddress;
VOID* pvEndingAddress;
struct _VAD* pvadParentLink;
struct _VAD* pvadLeftLink;
struct _VAD* pvadRightLink;
DWORD dwFlags;
DWORD dwUndocumented_DWORD;
} VAD, *PVAD;
#pragma pack(pop)
//====================================
// IsPagePresent Function Definition.
BOOLEAN IsPagePresent( IN PVOID pvVirtAddress )
DWORD dwPageDirEntry;
DWORD* pdwPageTables = (DWORD*) 0xC0000000;
DWORD dwPageTableEntry;
// Check the Page Tables.
dwPageDirEntry = pdwPageDir[ ( (DWORD) pvVirtAddress ) / 0x400000 ];
if ( dwPageDirEntry & (1<<7) )
return TRUE;
dwPageTableEntry = pdwPageTables[ ( (DWORD) pvVirtAddress ) / 0x1000 ];
if ( ( dwPageTableEntry >> 12 ) &&
( dwPageTableEntry & 0x1 ) )
return FALSE;