@ -150,6 +150,178 @@ namespace driver_util
return NULL ;
}
PDRIVER_OBJECT get_drv_obj ( PUNICODE_STRING driver_name )
{
HANDLE handle { } ;
OBJECT_ATTRIBUTES attributes { } ;
UNICODE_STRING directory_name { } ;
PVOID directory { } ;
BOOLEAN success = FALSE ;
RtlInitUnicodeString ( & directory_name , L " \\ Driver " ) ;
InitializeObjectAttributes (
& attributes ,
& directory_name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL
) ;
// open OBJECT_DIRECTORY for \\Driver
auto status = ZwOpenDirectoryObject (
& handle ,
DIRECTORY_ALL_ACCESS ,
& attributes
) ;
if ( ! NT_SUCCESS ( status ) )
{
DBG_PRINT ( " ZwOpenDirectoryObject Failed " ) ;
return NULL ;
}
// Get OBJECT_DIRECTORY pointer from HANDLE
status = ObReferenceObjectByHandle (
handle ,
DIRECTORY_ALL_ACCESS ,
nullptr ,
KernelMode ,
& directory ,
nullptr
) ;
if ( ! NT_SUCCESS ( status ) )
{
DBG_PRINT ( " ObReferenceObjectByHandle Failed " ) ;
ZwClose ( handle ) ;
return NULL ;
}
const auto directory_object = POBJECT_DIRECTORY ( directory ) ;
if ( ! directory_object )
return NULL ;
ExAcquirePushLockExclusiveEx ( & directory_object - > Lock , 0 ) ;
// traverse hash table with 37 entries
// when a new object is created, the object manager computes a hash value in the range zero to 36 from the object name and creates an OBJECT_DIRECTORY_ENTRY.
// http://www.informit.com/articles/article.aspx?p=22443&seqNum=7
for ( auto entry : directory_object - > HashBuckets )
{
if ( ! entry )
continue ;
while ( entry & & entry - > Object )
{
auto driver = PDRIVER_OBJECT ( entry - > Object ) ;
if ( ! driver )
continue ;
if ( wcscmp ( driver - > DriverExtension - > ServiceKeyName . Buffer , driver_name - > Buffer ) = = 0 )
return driver ;
}
}
ExReleasePushLockExclusiveEx ( & directory_object - > Lock , 0 ) ;
// Release the acquired resources back to the OS
ObDereferenceObject ( directory ) ;
ZwClose ( handle ) ;
//TODO remove
return NULL ;
}
void copy_driver ( PUNICODE_STRING image_path )
{
HANDLE h_file ;
OBJECT_ATTRIBUTES attr ;
IO_STATUS_BLOCK status_block ;
LARGE_INTEGER offset ;
UNICODE_STRING name ;
FILE_STANDARD_INFORMATION standard_info ;
RtlZeroMemory ( & standard_info , sizeof ( standard_info ) ) ;
InitializeObjectAttributes (
& attr ,
image_path ,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE ,
NULL , NULL
) ;
NTSTATUS status = ZwCreateFile (
& h_file ,
GENERIC_READ ,
& attr ,
& status_block ,
NULL ,
FILE_ATTRIBUTE_NORMAL ,
NULL ,
FILE_OPEN_IF ,
FILE_SYNCHRONOUS_IO_NONALERT ,
NULL ,
NULL
) ;
ZwQueryInformationFile (
h_file ,
& status_block ,
& standard_info ,
sizeof ( FILE_STANDARD_INFORMATION ) ,
FileStandardInformation
) ;
void * drv_buffer = ExAllocatePool (
NonPagedPool ,
standard_info . AllocationSize . QuadPart
) ;
status = ZwReadFile (
h_file ,
NULL ,
NULL ,
NULL ,
& status_block ,
drv_buffer ,
standard_info . AllocationSize . QuadPart ,
& offset ,
NULL
) ;
RtlInitUnicodeString ( & name , L " \\ DosDevices \\ C: \\ last_load_drv.sys " ) ;
InitializeObjectAttributes ( & attr , & name ,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE ,
NULL , NULL
) ;
ZwCreateFile (
& h_file ,
GENERIC_WRITE ,
& attr ,
& status_block ,
NULL ,
FILE_ATTRIBUTE_NORMAL ,
NULL ,
FILE_OVERWRITE_IF ,
FILE_SYNCHRONOUS_IO_NONALERT ,
NULL ,
NULL
) ;
ZwWriteFile (
h_file ,
NULL ,
NULL ,
NULL ,
& status_block ,
drv_buffer ,
standard_info . AllocationSize . QuadPart ,
& offset ,
NULL
) ;
ZwClose ( h_file ) ;
ExFreePool ( drv_buffer ) ;
}
void mem_dump ( void * base_addr , unsigned len )
{
if ( ! base_addr | | ! len )