Programming/Kernel / Driver2008. 12. 3. 10:56

이번에는 직접 후킹드라이버의 기본 프레임을 작성해 보겠습니다.
 

여러분이 WDM에 어느정도 기본 지식이 있다는 가정하에 진행되겠습니다.


아래는 일반적인 드라이버의 엔트리 부분입니다.
 

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
    UINT i;
 
    UNREFERENCED_PARAMETER (RegistryPath);
 
    for (i = 0 ; i <= IRP_MJ_MAXIMUM_FUNCTION ; i++)
        DriverObject->MajorFunction[i] = OnStubDispatch;
 
   
    DriverObject->MajorFunction [IRP_MJ_CREATE] = CreateHandler;
    DriverObject->MajorFunction [IRP_MJ_CLOSE] = CloseHandler;
    DriverObject->MajorFunction [IRP_MJ_PNP] = PNPHandler
    DriverObject->MajorFunction [IRP_MJ_POWER] = PowerHandler;
    DriverObject->MajorFunction [IRP_MJ_INTERNAL_DEVICE_CONTROL] = ControlHandler;
   
 
    DriverObject->DriverUnload = OnUnload;
    DriverObject->DriverExtension->AddDevice = AddDevice;
 
    return STATUS_SUCCESS;
}
 
하지만 우리가 시도하려는 후킹드라이버는 드라이버 엔트리를 진입하기는 하지만 정상적인 시작이 아니기 때문에
대부분의 함수 포인터를 채울 필요가 없습니다.
 
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DrvClose;
DriverObject->DriverUnload = DrvUnload;
 
를 남기고 모두 지워 버리세요. SCM을 이용해서 드라이버를 생성시키고 시작하는 과정에는
IRP_MJ_CREATE, DriverObject->DriverExtension->AddDevice 함수포인터에 접근하지 않습니다.

그리고 드라이버엔트리에 직접 IoCreateDevice 으로 디바이스를 생성시킵니다.
 
 
한가지 재미있는 점은 드라이버엔트리는 DSP = 0 , Ring 0 의 권한을 가지고 있습니다.
때에 따라서 악명높은 CIH바이러스와 같이 바이오스를 지워버릴수도 직접 제어 할 수도 있습니다.
 
이야기를 다시 돌려서 생성시킨 장치는 IoCreateSymbolicLink로 등록 시킵니다.
 
 
 
이제 드라이버를 다시 작성하면
 
 
 
const WCHAR devicename[]=L"\\Device\\HookDriver";
const WCHAR devicelink[]=L"\\DosDevices\\HOOKDRIVER";
 
 
NTSTATUS DriverEntry(IN PDRIVER_OBJECT  DriverObject, IN PUNICODE_STRING RegistryPath)
{
    PDEVICE_OBJECT devobject = 0;
    UNICODE_STRING devlink,devname;
 
    RtlInitUnicodeString(&devname,devicename);
    RtlInitUnicodeString(&devlink,devicelink);
 
    IoCreateDevice(DriverObject, 256, &devname, FILE_DEVICE_UNKNOWN, 0, FALSE, &devobject);
    IoCreateSymbolicLink(&devlink,&devname);
 
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = DrvClose;
    DriverObject->DriverUnload = DrvUnload;
 
    return STATUS_SUCCESS;
}
 
void DrvUnload(IN PDRIVER_OBJECT driver)
{
    UNICODE_STRING devlink;
 
    RtlInitUnicodeString(&devlink,devicelink);
 
    IoDeleteSymbolicLink(&devlink);
    IoDeleteDevice(driver->DeviceObject);
}
 
NTSTATUS DrvClose(IN PDEVICE_OBJECT device,IN PIRP Irp)
{
    Irp->IoStatus.Information=0;
    Irp->IoStatus.Status=0;
    IoCompleteRequest(Irp,IO_NO_INCREMENT);
 
    return 0;
}
 
과 같이 작성이 되겠습니다. 이제 후킹드라이버의 기본 프레임이 완성되었습니다.
 
드라이버 작성내용은 되도록 DDK관련 문서를 참고하셔서 보시는 편이 도움이 되십겁니다.

출처 : 데브피아

Posted by skensita