Ntstatus
Readkernelmemory (in pvoid baseaddress,
Out pvoid buffer,
In ulong length)
{
Ntstatus status;
Sysdbg_virtual dbgmemory;
//
// Setup the request
//
Dbgmemory. Address = baseaddress;
Dbgmemory. Buffer = buffer;
Dbgmemory. Request = length;
//
// Do the read
//
Status = ntsystemdebugcontrol (sysdbgreadvirtual,
& Dbgmemory,
Sizeof (dbgmemory ),
Null,
0,
Null );
Return status;
}
Pchar
Finddriverforaddress (in pvoid pointer)
{
Ntstatus status;
Prtl_process_modules moduleinfo;
Prtl_process_module_information moduleentry;
Ulong returnedlength;
Ulong I;
//
// Figure out how much size we need
//
Status = ntquerysysteminformation (systemmoduleinformation,
Null,
0,
& Returnedlength );
If (status! = Status_info_length_mismatch) return NULL;
//
// Allocate a buffer large enough
//
Moduleinfo = rtlallocateheap (rtlgetprocessheap (), 0, returnedlength );
If (! Moduleinfo) return NULL;
//
// Now query the data again
//
Status = ntquerysysteminformation (systemmoduleinformation,
Moduleinfo,
Returnedlength,
& Returnedlength );
If (! Nt_success (Status) return NULL;
//
// Loop all the drivers
//
For (I = 0; I <moduleinfo-> numberofmodules; I ++)
{
//
// Get the current entry and check if the pointer is within it
//
Moduleentry = & moduleinfo-> modules [I];
If (pointer> moduleentry-> imagebase )&&
(Pointer <(pvoid) (ulong_ptr) moduleentry-> imagebase +
Moduleentry-> imagesize ))))
{
//
// Found a match, return it
//
Return moduleentry-> fullpathname;
}
}
}
Pchar
Detectdriver (void)
{
Boolean old;
Ntstatus status;
Ulong_ptr mappedaddress;
Pvoid kernelbase, tablebase;
Unicode_string kernelname;
Ansi_string tablename = rtl_constant_string ("keservicedescriptortable ");
Rtl_process_modules moduleinfo;
Ulong flags;
Kservice_table_descriptor servicetable;
//
// Give our thread the debug privilege
//
Status = rtladjustprivilege (se_debug_privilege, true, false, & old );
If (! Nt_success (Status) return NULL;
//
// Query the kernel's module entry
//
Status = ntquerysysteminformation (systemmoduleinformation,
& Moduleinfo,
Sizeof (moduleinfo ),
Null );
If (status! = Status_info_length_mismatch) return NULL;
//
// Initialize the kernel's full path name
//
Status = rtlcreateunicodestringfromasciiz (& kernelname,
Moduleinfo. modules [0]. fullpathname );
If (! Status) return NULL;
//
// Keep only the short name
//
Kernelname. Buffer = kernelname. Buffer +
(Kernelname. Length/sizeof (wchar ))-
12;
//
// Map the kernel
//
Flags = image_file_executable_image;
Status = ldrloaddll (null, & flags, & kernelname, & kernelbase );
If (! Nt_success (Status) return NULL;
//
// Find the address of keservicedescriptortable
//
Status = ldrgetprocedureaddress (kernelbase, & tablename, 0, & tablebase );
If (! Nt_success (Status) return NULL;
//
// Unload the kernel image, we're re done with it
//
Status = ldrunloaddll (kernelbase );
If (! Nt_success (Status) return NULL;
//
// Get the virtual address we need
//
Mappedaddress = (ulong_ptr) moduleinfo. modules [0]. imagebase;
Mappedaddress-= (ulong_ptr) kernelbase;
Mappedaddress + = (ulong_ptr) tablebase;
//
// Now read the ssdt
//
Status = readkernelmemory (pvoid) mappedaddress,
& Servicetable,
Sizeof (servicetable ));
If (! Nt_success (Status) return NULL;
//
// Setup the argument table
//
Argumenttable = rtlallocateheap (rtlgetprocessheap (),
0,
Servicetable. Limit * sizeof (ulong_ptr ));
If (! Argumenttable) return NULL;
//
// Now fill it up
//
Status = readkernelmemory (servicetable. Base,
Argumenttable,
Servicetable. Limit * sizeof (ulong_ptr ));
If (! Nt_success (Status) return NULL;
//
// Now scan it
//
For (I = 0; I <servicetable. limit; I ++)
{
//
// Make sure no pointer is outside the kernel Area
//
If (argumenttable [I]> 0x8fffffff)
{
//
// Find the driver file that this belongs
//
Return finddriverforaddress (ulongtoptr (argumenttable [I]);
}
}
//
// If we got here, then you don't have any Rootkit
//
Return NULL;
}