用HOOK来修改API函数的功能(4)-环境搭建
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处 、作者信息和本声明。否则将追究法律责任。
http://fxh7622.blog.51cto.com/63841/33142
|
上面的3篇文章已经大概的讲述了HOOK API的编写方法,可是如何让它们真正的运行起来呢?
这就需要搭建环境,而这个环境你必须使用DDK。我在这里假设你已经安装了DDK,并且会使用DDK来编译一个 WDM驱动程序。这里我要说的是如何在代码中将我上面的3篇文章中讲到的功能串在一起,以及编写WDM驱动程序所需要的Sources文件。 我的Sources文件是这样写的: TARGETNAME=TestDriver TARGETTYPE=DRIVER TARGETPATH=obj BROWSER_INFO=1 C_DEFINES=-DDRIVER INCLUDES=c:/ntddk/inc; USER_C_FLAGS=/FAcs SOURCES=My.c
其中TARGETNAME=TestDriver指明编译出来的文件名称叫做TestDriver。
TARGETTYPE=DRIVER指明生成的文件类型是*.sys。 SOURCES=My.c指明需要编译的源代码文件。
下面来看看My.c文件内容。
作为一个WDM驱动,首先运行的应该是DriverEntry例程。该例程类似于C语言中的Main函数。 NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { UNICODE_STRING nameString, linkString; UNICODE_STRING *InstallDir=NULL; PDEVICE_OBJECT deviceObject; NTSTATUS status; WCHAR wBuffer[200]; nameString.Buffer = wBuffer; nameString.MaximumLength = 200; //DriverUnload例程用来处理驱动卸载时所做的恢复工作. DriverObject->DriverUnload = DriverUnload; RtlInitUnicodeString(&nameString, L" //Device//MyDriver"); status = IoCreateDevice(DriverObject, 0,&nameString, FILE_DEVICE_UNKNOWN, 0, TRUE, &deviceObject ); if (!NT_SUCCESS( status )) { return status; } deviceObject->Flags |= DO_BUFFERED_IO; RtlInitUnicodeString(&linkString, L" //??//MyDriver"); status = IoCreateSymbolicLink (&linkString, &nameString); if (!NT_SUCCESS( status )) { IoDeleteDevice (DriverObject->DeviceObject); return status; } //MydrvDispatch例程是一个IRP的分发例程(在我的代码中没有怎么用到它) DriverObject->MajorFunction[IRP_MJ_CREATE] = MydrvDispatch; DriverObject->MajorFunction[IRP_MJ_CLOSE] = MydrvDispatch; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = MydrvDispatch; //MydrvDispatchIoctl例程比较重要,该例程可以接受来自外界EXE程序发送给它的参数。例如在我的项目中,由一个外界exe程序 //发送过来需要保护的文件名称、注册表键值等数据,都是使用这个例程来接收的。 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MydrvDispatchIoctl; __asm{ mov eax, cr0 mov CR0VALUE, eax and eax, 0fffeffffh mov cr0, eax }
看过我文章的朋友一定不会对下面的代码陌生。
//文件删除 RealZwSetInformationFile=(ZWSETINFORMATIONFILE)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwSetInformationFile")]); (ZWSETINFORMATIONFILE)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwSetInformationFile")])=HookZwSetInformationFile; //注册表删除 RealZwDeleteKey=(REALZWDELETEKEY)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwDeleteKey")]); (REALZWDELETEKEY)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwDeleteKey")])=HookZwDeleteKey; //删除注册表内容 RealZwDeleteValueKey=(REALZWDELETEVALUEKEY)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwDeleteValueKey")]); (REALZWDELETEVALUEKEY)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwDeleteValueKey")])=HookZwDeleteValueKey; //设置注册表键值 RealZwSetValueKey=(REALZWSETVALUEKEY)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwSetValueKey")]); (REALZWSETVALUEKEY)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwSetValueKey")])=HookZwSetValueKey; //创建文件 RealZwCreateFile=(REALZWCREATEFILE)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwCreateFile")]); (REALZWCREATEFILE)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwCreateFile")])=HookZwCreateFile; __asm{ mov eax, CR0VALUE mov cr0, eax } return STATUS_SUCCESS; } 在卸载驱动的时候使用的DriverUnload例程代码如下: VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject) { UNICODE_STRING nameString; RtlInitUnicodeString(&nameString, L" //??//MyDriver"); IoDeleteSymbolicLink(&nameString); IoDeleteDevice(pDriverObject->DeviceObject); //卸载设置文件属性 (ZWSETINFORMATIONFILE)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwSetInformationFile")])=RealZwSetInformationFile; //删除注册表键值 (REALZWDELETEKEY)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwDeleteKey")])=RealZwDeleteKey; //删除注册表内容 (REALZWDELETEVALUEKEY)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwDeleteValueKey")])=RealZwDeleteValueKey; //设置注册表键值 (REALZWSETVALUEKEY)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwSetValueKey")])=RealZwSetValueKey; //创建文件 (REALZWCREATEFILE)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwCreateFile")])=RealZwCreateFile; return; }
这样就搭建出了一个完整的WDM驱动框架。编译后可以生成一个具有一定功能的驱动程序。
下次我将会写如何将我们编写好的驱动进行安装,并通过外界的EXE程序和这个驱动程序进行通信。 本文出自 “狗窝” 博客,请务必保留此出处http://fxh7622.blog.51cto.com/63841/33142 |