作 者: cvcvxk
時 間: 2011-08-07,21:22:23
我們都知道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");
没有评论:
发表评论