用HOOK来修改API函数的功能(4)-环境搭建

简介:
上面的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程序和这个驱动程序进行通信。
本文转自狗窝博客51CTO博客,原文链接http://blog.51cto.com/fxh7622/33142如需转载请自行联系原作者

fxh7622
相关文章
|
15天前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
31 4
|
22天前
|
机器学习/深度学习 算法 Java
通过 Java Vector API 利用 SIMD 的强大功能
通过 Java Vector API 利用 SIMD 的强大功能
33 10
|
2月前
|
API
本地hook API MessageBoxA的masm32源代码[07-10更新]
本地hook API MessageBoxA的masm32源代码[07-10更新]
|
13天前
|
移动开发 前端开发 JavaScript
前端开发实战:利用Web Speech API之speechSynthesis实现文字转语音功能
前端开发实战:利用Web Speech API之speechSynthesis实现文字转语音功能
72 0
|
3月前
|
JSON 前端开发 API
构建前端防腐策略问题之更新getMemoryUsagePercent函数以适应新的API返回格式的问题如何解决
构建前端防腐策略问题之更新getMemoryUsagePercent函数以适应新的API返回格式的问题如何解决
构建前端防腐策略问题之更新getMemoryUsagePercent函数以适应新的API返回格式的问题如何解决
|
2月前
|
网络协议 API Windows
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
|
2月前
|
存储 程序员 API
【收藏】非API函数检测操作系统类型
【收藏】非API函数检测操作系统类型
|
2月前
|
JSON 搜索推荐 API
深入了解亚马逊商品详情API:功能、作用与实例
亚马逊商品详情API接口由官方提供,允许开发者通过程序调用获取商品详细信息,如标题、价格等,适用于电商数据分析、搜索及个性化推荐等场景。接口名称包括ItemLookup、GetMatchingProductForId等,支持HTTP POST/GET请求,需提供商品ID、API密钥及其他可选参数。返回数据格式通常为JSON或XML,涵盖商品详情、分类、品牌、价格、图片URL及用户评价等。该接口对数据收集、实时推荐、营销活动及数据分析至关重要,有助于提升电商平台的数据处理能力、用户体验及商家运营效率。使用时需注册亚马逊开发者账号并申请API访问权限,获取API密钥后按文档构建请求并处理响应数据。
|
3月前
|
存储 JavaScript 前端开发
探索React状态管理:Redux的严格与功能、MobX的简洁与直观、Context API的原生与易用——详细对比及应用案例分析
【8月更文挑战第31天】在React开发中,状态管理对于构建大型应用至关重要。本文将探讨三种主流状态管理方案:Redux、MobX和Context API。Redux采用单一存储模型,提供预测性状态更新;MobX利用装饰器语法,使状态修改更直观;Context API则允许跨组件状态共享,无需第三方库。每种方案各具特色,适用于不同场景,选择合适的工具能让React应用更加高效有序。
67 0
|
22小时前
|
JSON API 数据格式
店铺所有商品列表接口json数据格式示例(API接口)
当然,以下是一个示例的JSON数据格式,用于表示一个店铺所有商品列表的API接口响应