이번에는 직접 후킹드라이버의 기본 프레임을 작성해 보겠습니다.
여러분이 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관련 문서를 참고하셔서 보시는 편이 도움이 되십겁니다.
출처 : 데브피아