用HOOK来修改API函数的功能(1)-注册表

简介:
我们知道编程实际上是使用各种API函数来达到我们想要的目的。换句话说就是API函数是我们通常编程时使用到的最底层函数。很多人也觉得除了API函数微软没有在提供其它的编程接口。其实微软出了提供API函数意外还提供了另外的一套函数,不过这些函数会随着操作系统的不同有细微的改变。由于这些函数是如此的“不稳定”,所以微软并没有将它们文档化。我们称之为“未文档化函数”。我们通常使用的API函数其实都是使用这些函数来实现的。所以如果我们使用HOOK来修改这些函数的某些执行特征,那么我们就可以实现一些特殊的功能,例如注册表的禁止修改,禁止删除等等。
从今天开始我会连续的写出如何使用HOOK的方法来修改API函数的一些特性。
首先我来说说如何做到注册表的禁止修改。
在“未文档化函数”中有这样一个函数ZWSETVALUEKEY它的定义是这样的:
ZWSETVALUEKEY)(
 IN HANDLE  KeyHandle,
 IN PUNICODE_STRING  ValueName,
 IN ULONG  TitleIndex  OPTIONAL,
 IN ULONG  Type,
 IN PVOID  Data,
 IN ULONG  DataSize
 );
ZWSETVALUEKEY ZwSetValueKey;
这个函数就是用来使用对注册表内容的修改的,也就是说如果我们打开注册表以后对任何的一个键值的修改,系统都会调用这个函数来实现。如果我们将这个函数修改成“如果用户想修改制定的键值的时候,我们不予执行”,那么我们就实现了对这个注册表键值的保护。那如何来实现呢?下面是我实现的代码和讲解,希望对大家有所帮助。
#include "ntddk.h"
#include "bugcodes.h"
#include "ntstatus.h"
#include <ntddkbd.h>
#include <stdio.h>
#include "stdarg.h"
#include "ntiologc.h"
#define MAXPATHLEN 1024
#define MaxBuf 1024
#define MIN(x,y) ((x) < (y) ? (x) : (y))
.....

//(1).声明原有函数
typedef NTSTATUS (*REALZWSETVALUEKEY)(
 IN HANDLE  KeyHandle,
 IN PUNICODE_STRING  ValueName,
 IN ULONG  TitleIndex  OPTIONAL,
 IN ULONG  Type,
 IN PVOID  Data,
 IN ULONG  DataSize
 );
REALZWSETVALUEKEY RealZwSetValueKey;
//(2).定义HOOK注册表设置内容的函数
NTSTATUS HookZwSetValueKey(
 IN HANDLE  KeyHandle,
 IN PUNICODE_STRING  ValueName,
 IN ULONG  TitleIndex  OPTIONAL,
 IN ULONG  Type,
 IN PVOID  Data,
 IN ULONG  DataSize
 );
...
//驱动的入口函数
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) 
{
......
RealZwSetValueKey=(REALZWSETVALUEKEY)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwSetValueKey")]);
  (REALZWSETVALUEKEY)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwSetValueKey")])=HookZwSetValueKey;
// 上面的2行代码就是我们将函数ZwSetValueKey替换成我们自己定义的函数HookZwSetValueKey,这个时候如果有系统要调用函数ZwSetValueKey的时候就会调用我们定义的函数HookZwSetValueKey。而在这个函数中所做的就是我们对修改键值的判断。
}
PVOID GetPointer( HANDLE handle )
{
  PVOID         pKey;
  if(!handle) return NULL;
  //取得指针.
  if( ObReferenceObjectByHandle( handle, 0, NULL, KernelMode, &pKey, NULL ) != STATUS_SUCCESS ) 
  {
      pKey = NULL;
  } 
  return pKey;
}
//HOOK设置注册表键值的函数
NTSTATUS HookZwSetValueKey(
  IN HANDLE  KeyHandle,
  IN PUNICODE_STRING  ValueName,
  IN ULONG  TitleIndex  OPTIONAL,
  IN ULONG  Type,
  IN PVOID  Data,
  IN ULONG  DataSize)
{
 NTSTATUS rc;
 UNICODE_STRING *pUniName;  //定义得到修改注册表的UNI路径
 ULONG actualLen;
 ANSI_STRING keyname,
    akeyname,
    m_keyname,
    m_akeyname;       //定义得到修改注册表的UNI路径
 PVOID pKey;
 RtlUnicodeStringToAnsiString( &akeyname, ValueName, TRUE);
 RtlUnicodeStringToAnsiString( &m_akeyname, ValueName, TRUE);
 RtlUpperString(&akeyname,&m_akeyname);
 RtlFreeAnsiString(&m_akeyname);
 if( pKey = GetPointer( KeyHandle))
 {
  pUniName = ExAllocatePool( NonPagedPool, 512*2+2*sizeof(ULONG));
  pUniName->MaximumLength = 512*2;
  if( NT_SUCCESS( ObQueryNameString( pKey, pUniName, MAXPATHLEN, &actualLen)))
  {
   RtlUnicodeStringToAnsiString( &keyname, pUniName, TRUE);
   keyname.Buffer=_strupr(keyname.Buffer);
   akeyname.Buffer=_strupr(akeyname.Buffer);
   RtlUnicodeStringToAnsiString( &m_keyname, pUniName, TRUE);
   RtlUpperString(&keyname,&m_keyname);
   RtlFreeAnsiString(&m_keyname);
   if (strcmp(keyname.Buffer,\\REGISTRY\\MACHINE\\SOFTWARE\\TEST) == 0)
   {
    if(strcmp(akeyname.Buffer,"TEST") ==0)
    {
     RtlFreeAnsiString(&akeyname); 
     RtlFreeAnsiString(&keyname); 
     return 0;
    }
   }
   else if (strcmp(keyname.Buffer," \\REGISTRY\\MACHINE\\SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN") == 0)
   {
    if(strcmp(akeyname.Buffer,"TEST2") ==0)
    {
     RtlFreeAnsiString(&akeyname); 
     RtlFreeAnsiString(&keyname); 
     return 0;
    }
   }
   RtlFreeAnsiString(&keyname); 
  }
 }
 RtlFreeAnsiString(&akeyname); 
 rc=RealZwSetValueKey(KeyHandle,ValueName,TitleIndex,Type,Data,DataSize);
 return (rc);
}
上面的代码就是实现了对注册表中TEST下的Test键值和对RUN下的TEST2键值进行保护。
以上的代码是我自己开发的一个软件中实际使用的代码,是经过测试的!
本文转自狗窝博客51CTO博客,原文链接http://blog.51cto.com/fxh7622/30324如需转载请自行联系原作者

fxh7622
相关文章
|
3月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
66 4
|
18天前
|
人工智能 数据可视化 API
自学记录鸿蒙API 13:Calendar Kit日历功能从学习到实践
本文介绍了使用HarmonyOS的Calendar Kit开发日程管理应用的过程。通过API 13版本,不仅实现了创建、查询、更新和删除日程等基础功能,还深入探索了权限请求、日历配置、事件添加及查询筛选等功能。实战项目中,开发了一个智能日程管理工具,具备可视化管理、模糊查询和智能提醒等特性。最终,作者总结了模块化开发的优势,并展望了未来加入语音助手和AI推荐功能的计划。
134 1
|
1月前
|
JSON 供应链 搜索推荐
某东API接口:开启电商数据交互与功能调用的新篇章
在当今的数字化时代,电商平台的开放API(Application Programming Interface,应用程序编程接口)已经成为连接开发者与电商平台之间的重要桥梁。京东作为中国领先的电商平台之一,其开放平台提供的API接口更是为开发者们带来了无限可能。本文将深入探讨京东API接口的功能、应用场景、使用流程以及其在电商领域的重要价值。
|
2月前
|
API 开发工具 开发者
探究亚马逊国际获得AMAZON商品详情 API 接口功能、作用与实际应用示例
亚马逊提供的Amazon Product Advertising API或Selling Partner API,使开发者能编程访问亚马逊商品数据,包括商品标题、描述、价格等。支持跨境电商和数据分析,提供商品搜索和详情获取等功能。示例代码展示了如何使用Python和boto3库获取特定商品信息。使用时需遵守亚马逊政策并注意可能产生的费用。
|
3月前
|
机器学习/深度学习 算法 Java
通过 Java Vector API 利用 SIMD 的强大功能
通过 Java Vector API 利用 SIMD 的强大功能
115 10
|
4月前
|
API
本地hook API MessageBoxA的masm32源代码[07-10更新]
本地hook API MessageBoxA的masm32源代码[07-10更新]
|
4月前
|
网络协议 API Windows
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
|
3月前
|
移动开发 前端开发 JavaScript
前端开发实战:利用Web Speech API之speechSynthesis实现文字转语音功能
前端开发实战:利用Web Speech API之speechSynthesis实现文字转语音功能
464 0
|
4月前
|
存储 程序员 API
【收藏】非API函数检测操作系统类型
【收藏】非API函数检测操作系统类型
|
6天前
|
JSON 前端开发 搜索推荐
关于商品详情 API 接口 JSON 格式返回数据解析的示例
本文介绍商品详情API接口返回的JSON数据解析。最外层为`product`对象,包含商品基本信息(如id、name、price)、分类信息(category)、图片(images)、属性(attributes)、用户评价(reviews)、库存(stock)和卖家信息(seller)。每个字段详细描述了商品的不同方面,帮助开发者准确提取和展示数据。具体结构和字段含义需结合实际业务需求和API文档理解。

热门文章

最新文章