我们都知道ZwSetSystemInformation可以用参数SystemExtendServiceTableInformation(38号)加载驱动~但是这个加载驱动有很多很多麻烦与问题~
今天我来介绍的是一种全新的加载驱动的模式~~当然只能在Kernel mode来加载~只有断断的一个KernelAPI的使用哦~亲~
现在目前说来在内核里加载驱动的方式基本都是ZwLoadDriver,Patch 38号的Load参数,搜索使用MmLoadSystemImage,自己实现peloader等不方便不给力,有遗憾的方法~
现在呢,正式介绍一种全新的加载方式,使用ZwSetSystemInformation的
SystemLoadGdiDriverInSystemSpace(54号)来加载驱动,然后调用之~~
这个infoclass的结构定义,不知道DDK上有没有~~
typedef struct _SYSTEM_GDI_DRIVER_INFORMATION {
UNICODE_STRING DriverName;
PVOID ImageAddress;
PVOID SectionPointer;
PVOID EntryPoint;
PIMAGE_EXPORT_DIRECTORY ExportSectionPointer;
ULONG ImageLength;
} SYSTEM_GDI_DRIVER_INFORMATION, *PSYSTEM_GDI_DRIVER_INFORMATION;
然后就是怎么使用了鸟~只要对DriverName用RtlInitUnicodeString赋值就行了
(\\??\\XXXXX形式的参数或者是\\SystemRoot\\XXX形式)
具体请看代码,代码如下~~
NTSTATUS SysLoad(const WCHAR *wcsFileName)
{
SYSTEM_GDI_DRIVER_INFORMATION gdiinfo;
NTSTATUS ns;
PDRIVER_OBJECT pBeepObj;
RtlZeroMemory(&gdiinfo,sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
RtlInitUnicodeString(&gdiinfo.DriverName,wcsFileName);
ns=ZwSetSystemInformation(SystemLoadGdiDriverInSystemSpace,&gdiinfo,sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
if (NT_SUCCESS(ns))
{
PDRIVER_INITIALIZE InitRoutine;
UNICODE_STRING pRegPath;
UNICODE_STRING NameBuffer;
UNICODE_STRING DevName;
WCHAR buffer[60];
InitRoutine = (PDRIVER_INITIALIZE)gdiinfo.EntryPoint;
if (InitRoutine)
{
PDRIVER_OBJECT pDriverObject;
_snwprintf(buffer, (sizeof(buffer) / sizeof(WCHAR)) - 1, L"\\Driver\\%08u", PsGetCurrentThreadId());
RtlInitUnicodeString(&NameBuffer,buffer);
RtlInitUnicodeString(&DevName, L"\\Driver\\Beep");
RtlInitUnicodeString(&pRegPath,wcsFileName);
ns = ObReferenceObjectByName(&DevName, OBJ_CASE_INSENSITIVE, NULL,
0, *IoDriverObjectType, KernelMode, NULL, &pBeepObj);
if (NT_SUCCESS(ns))
{
ns=MakeFakeDriverObject(&NameBuffer,&pDriverObject);
if(NT_SUCCESS(ns))
{
pDriverObject->DriverStart=InitRoutine;
pDriverObject->DriverInit=InitRoutine;
pDriverObject->DriverSection=pBeepObj->DriverSection;
pDriverObject->DriverSize=gdiinfo.ImageLength;
ns= InitRoutine(pDriverObject,&pRegPath);
}
}
}
}
return ns;
}
在上面代码里使用了MakeFakeDriverObject来创建一个虚拟的DriverObject
这个函数代码在这里也贴一下~
NTSTATUS
IopInvalidDeviceRequest(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
if ((IoGetCurrentIrpStackLocation(Irp))->MajorFunction == IRP_MJ_POWER) {
PoStartNextPowerIrp(Irp);
}
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_INVALID_DEVICE_REQUEST;
}
NTSTATUS MakeFakeDriverObject(IN PUNICODE_STRING driverName,OUT PDRIVER_OBJECT* ppdriverObject)
{
NTSTATUS status;
ULONG i;
OBJECT_ATTRIBUTES objectAttributes;
PDRIVER_OBJECT driverObject;
InitializeObjectAttributes( &objectAttributes,
driverName,
OBJ_PERMANENT,
(HANDLE) NULL,
(PSECURITY_DESCRIPTOR) NULL );
status = ObCreateObject( ExGetPreviousMode(),
*IoDriverObjectType,
&objectAttributes,
KernelMode,
(PVOID) NULL,
//(ULONG) (sizeof( DRIVER_OBJECT ) + sizeof ( DRIVER_EXTENSION )),//this will crash
//because DRIVER_OBJECT is fixed but DRIVER_EXTENSION are growing bigger than ddk declared
(ULONG) (sizeof( DRIVER_OBJECT ) + sizeof ( DRIVER_EXTENSION ) + 256),
0,
0,
(PVOID *) ppdriverObject );
if (!NT_SUCCESS( status ))
{
*ppdriverObject = NULL;
return status;
}
driverObject=*ppdriverObject;
RtlZeroMemory( driverObject, sizeof( DRIVER_OBJECT ) + sizeof ( DRIVER_EXTENSION) + 256 );
driverObject->DriverExtension = (PDRIVER_EXTENSION) (driverObject + 1);
driverObject->DriverExtension->DriverObject = driverObject;//这个DriverExtension常用,如果没有直接惨死
driverObject->Type = IO_TYPE_DRIVER;
driverObject->Size = sizeof( DRIVER_OBJECT );
driverObject->Flags = DRVO_BUILTIN_DRIVER;
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
_asm
{
push eax
push ebx
mov eax,driverObject
mov eax,[eax+0x14]
mov ebx,[eax+0x34]
shr ebx,19
or ebx,1
shl ebx,19
mov [eax+0x34],ebx
pop ebx
pop eax
}
driverObject->DriverName.Buffer = ExAllocatePool( PagedPool,driverName->MaximumLength );
if (driverObject->DriverName.Buffer)
{
driverObject->DriverName.MaximumLength = driverName->MaximumLength;
driverObject->DriverName.Length = driverName->Length;
RtlCopyMemory( driverObject->DriverName.Buffer,driverName->Buffer,driverName->MaximumLength );
}
return status;
}
ok这样子就行鸟~~这些代码只能在kernel mode加载sys哦~~亲~~
就这样子!
SysLoad(L"\\??\\C:\\123\\killdisk.sys");
[课程]Android-CTF解题方法汇总!