一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现1
因为我们沙箱注入了一个DLL到了目标进程,并且Hook了一系列NtXX(NtOpenKey)函数,所以我们在注入的代码中是不能使用RegXX(RegOpenKey等)这类函数的。因为RegXX系列函数在底层使用了NtXX系列函数,如果在注入DLL执行Hook后的逻辑中使用了RegXX系列函数,将会导致递归调用的问题,就让程序产生“蛋生鸡,鸡生蛋”这样的“思考”,可是程序不知道停止,最终脑袋用完了就挂了。于是使用Nt函数实现我们曾经习惯使用的RegXX函数是必要的。(转载请指明出处)
编写这块代码时,我参考了reactos注册表相关的源码。它的源码写的很好,但是也存在一定的漏洞,我会在之后介绍。
列出一个比较简单的RegXX函数的实现:
LONG WINAPI RegOpenKeyExW(HKEY hKey,LPCWSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult)
{OBJECT_ATTRIBUTES ObjectAttributes;UNICODE_STRING SubKeyString;HANDLE KeyHandle;NTSTATUS Status;LONG ErrorCode = ERROR_SUCCESS;if (!phkResult){return ERROR_INVALID_PARAMETER;}Status = MapDefaultKey(&KeyHandle, hKey);if (!NT_SUCCESS(Status)){return RtlNtStatusToDosError(Status);}if (lpSubKey != NULL)RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey);elseRtlInitUnicodeString(&SubKeyString, (LPWSTR)L"");InitializeObjectAttributes(&ObjectAttributes,&SubKeyString,OBJ_CASE_INSENSITIVE,KeyHandle,NULL);Status = NtOpenKey((PHANDLE)phkResult,samDesired,&ObjectAttributes);if (!NT_SUCCESS(Status)){ErrorCode = RtlNtStatusToDosError(Status);}ClosePredefKey(KeyHandle);return ErrorCode;
}
总的来说,该函数的实现流程是:
- 参数合法性判断
- 用MapDefaultKey将HKEY转换成HANDLE
- 组装ObjectAttributes
- 调用Nt式函数
- 关闭第一步获得的HANDLE
我们发现其他很多Reg函数都是走这个套路的,比如RegSetKeyValue和RegEnumKeyEx等。
因为我们Hook的是Nt式函数,我们在函数中可以获取键对应的HANDLE,而不会得到HKEY。于是我们关心的是HKEY和HANDLE转换的过程。我们查看MapDefaultKey
#define MAX_DEFAULT_HANDLES 6
static HANDLE DefaultHandleTable[MAX_DEFAULT_HANDLES];
#define IsPredefKey(HKey) \(((ULONG_PTR)(HKey) & 0xF0000000) == 0x80000000)
#define GetPredefKeyIndex(HKey) \((ULONG_PTR)(HKey) & 0x0FFFFFFF)
static NTSTATUS MapDefaultKey(OUT PHANDLE RealKey, IN HKEY Key)
{PHANDLE Handle;ULONG Index;BOOLEAN DoOpen, DefDisabled;NTSTATUS Status = STATUS_SUCCESS;if (!IsPredefKey(Key)) {*RealKey = (HANDLE)((ULONG_PTR)Key & ~0x1);return STATUS_SUCCESS;}/* Handle special cases here */Index = GetPredefKeyIndex(Key);if (Index >= MAX_DEFAULT_HANDLES) {return STATUS_INVALID_PARAMETER;}RegInitialize(); /* HACK until delay-loading is implemented */RtlEnterCriticalSection (&HandleTableCS);if (Key == HKEY_CURRENT_USER)DefDisabled = DefaultHandleHKUDisabled;elseDefDisabled = DefaultHandlesDisabled;if (!DefDisabled) {Handle = &DefaultHandleTable[Index];DoOpen = (*Handle == NULL);}else {Handle = RealKey;DoOpen = TRUE;}if (DoOpen) {/* create/open the default handle */Status = OpenPredefinedKey(Index,Handle);}if (NT_SUCCESS(Status)) {if (!DefDisabled)*RealKey = *Handle;else*(PULONG_PTR)Handle |= 0x1;}RtlLeaveCriticalSection (&HandleTableCS);return Status;
}
我来解释下上述代码,我们先来看一些定义
#define HKEY_CLASSES_ROOT (( HKEY ) (ULONG_PTR)((LONG)0x80000000) )
#define HKEY_CURRENT_USER (( HKEY ) (ULONG_PTR)((LONG)0x80000001) )
#define HKEY_LOCAL_MACHINE (( HKEY ) (ULONG_PTR)((LONG)0x80000002) )
#define HKEY_USERS (( HKEY ) (ULONG_PTR)((LONG)0x80000003) )
#define HKEY_PERFORMANCE_DATA (( HKEY ) (ULONG_PTR)((LONG)0x80000004) )
#define HKEY_PERFORMANCE_TEXT (( HKEY ) (ULONG_PTR)((LONG)0x80000050) )
#define HKEY_PERFORMANCE_NLSTEXT (( HKEY ) (ULONG_PTR)((LONG)0x80000060) )
#if(WINVER >= 0x0400)
#define HKEY_CURRENT_CONFIG (( HKEY ) (ULONG_PTR)((LONG)0x80000005) )
#define HKEY_DYN_DATA (( HKEY ) (ULONG_PTR)((LONG)0x80000006) )
看到这些主键的值都是0x80000000+,IsPredefKey(Key)函数就是判断hKey是否为这些主键。如果不是主键,则可能是我们通过RegOpenKey等函数打开的主键下的子键(RegOpenKey(HKEY_CLASS_ROOT,L".txt",&hKey); hKey可能是形如0x000003AB这样的值),对于这样的子键Hkey,其通过(HANDLE)((ULONG_PTR)Key & ~0x1)就可以转换为HANDLE了。
如果是以上主键,这些主键的后28位是一个数组的Index,该数组保存的其对应的HANDLE。但是这个版本的Reactos只保存了MAX_DEFAULT_HANDLES(6)个元素,于是HKEY_PERFORMANCE_TEXT、HKEY_DYN_DATA和HKEY_PERFORMANCE_NLSTEXT这样主键就会被认为不合法了。
if (Index >= MAX_DEFAULT_HANDLES){//HKEY_PERFORMANCE_TEXT、HKEY_PERFORMANCE_NLSTEXT、HKEY_DYN_DATAreturn STATUS_INVALID_PARAMETER;}
拿到Index后使用OpenPredefinedKey打开这些主键的HANDLE
static NTSTATUS
OpenPredefinedKey(IN ULONG Index,OUT HANDLE Handle)
{NTSTATUS Status;switch (Index){case 0: /* HKEY_CLASSES_ROOT */Status = OpenClassesRootKey (Handle);break;case 1: /* HKEY_CURRENT_USER */Status = RtlOpenCurrentUser (MAXIMUM_ALLOWED,Handle);break;case 2: /* HKEY_LOCAL_MACHINE */Status = OpenLocalMachineKey (Handle);break;case 3: /* HKEY_USERS */Status = OpenUsersKey (Handle);break;
#if 0case 4: /* HKEY_PERFORMANCE_DATA */Status = OpenPerformanceDataKey (Handle);break;
#endifcase 5: /* HKEY_CURRENT_CONFIG */Status = OpenCurrentConfigKey (Handle);break;case 6: /* HKEY_DYN_DATA */Status = STATUS_NOT_IMPLEMENTED;break;default:WARN("MapDefaultHandle() no handle creator\n");Status = STATUS_INVALID_PARAMETER;break;}return Status;
这些获取HANDLE的方法在底层都是通过NtOpenKey实现的,如获取HKEY_CURRENT_USER键的路径的函数
NTSTATUS
NTAPI
RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess,OUT PHANDLE KeyHandle)
{OBJECT_ATTRIBUTES ObjectAttributes;UNICODE_STRING KeyPath;NTSTATUS Status;PAGED_CODE_RTL();/* Get the user key */Status = RtlFormatCurrentUserKeyPath(&KeyPath);if (NT_SUCCESS(Status)){/* Initialize the attributes and open it */InitializeObjectAttributes(&ObjectAttributes,&KeyPath,OBJ_CASE_INSENSITIVE,NULL,NULL);Status = ZwOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);/* Free the path and return success if it worked */RtlFreeUnicodeString(&KeyPath);if (NT_SUCCESS(Status)) return STATUS_SUCCESS;}/* It didn't work, so use the default key */RtlInitUnicodeString(&KeyPath, RtlpRegPaths[RTL_REGISTRY_USER]);InitializeObjectAttributes(&ObjectAttributes,&KeyPath,OBJ_CASE_INSENSITIVE,NULL,NULL);Status = ZwOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);/* Return status */return Status;
}
经过以上各步的转换,我们就可以获得HKEY和HANDLE对应的关系了。但是实际我们却不会去关心这个过程,因为我们在Nt式函数里获得就是HANDLE,我们不用去执行这个转换过程。但是作为知识,既然研究到这儿,就得好好研究透。
相关文章:
面试大厂背怼!这都搞不定,你只能做“搬运工”!
每一个面试过大厂的程序员似乎总会有种种困境:毕业季参加大厂校招面试,我本以为做过一些真实项目就不错了,没想到根本没问什么项目,都是基础知识,数学、算法,然而平时只喜欢学程序设计。小公司工作3年&…

net程序架构开发
< DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd> 程序架构,功能的划分: 数据库(包括存储过程) 数据访问(包括Microsoft Application Blocks for .NET的2.0版) 数据结构(等价于强类型DataSet) 业务逻辑层 业务表现层 数据库:不用说…

Java面向对象学习笔记 -- 6(内部类、Timer)
1. 内部类内部类就是在一个类的内部定义的类,有:静态内部类、成员内部类,局部内部类、匿名内部类。-1) 静态内部类:使用static修饰,声明在类体中, 静态内部类中可以访问外部类的静态成员,开发很…
30年间,软件开发行业为何Bug纷飞?
作者 | Chris Fox译者 | 弯月,责编 | 屠敏出品 | CSDN(ID:CSDNnews)【导语】在时间的推移历程中,软件行业早已发生了天翻地覆的变化。和曾经大家习以为常的编码日常相比,越多越多的开发者发现,如…

去掉字符串两端的全角空格和半角空格(含源代码)
昨天,遇到了一个技术问题。本来我在程序中用的trim()方法来处理从JSP页面传来的值,后来在测试时,发现当我输入的是全角空格时,trim()方法失效。需求是这样的,只是去掉字符串两端的空格(不论是全角空格还是半角空格&…

一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现2
上一篇博文中主要介绍了Reactos中大部分函数的思路和HKEY和HANDLE之间的关系,本文将介绍一些Reactos中有意思的函数和存在bug的函数。(转载请指明出处)CreateNestedKey是一个辅助创建键的函数,比如我们要创建\Regsitry\User\3\2\1…

云计算安全解决方案白皮书(一)
云计算安全解决方案白皮书Jack zhai研究云的安全有两三年了,但形成完整的安全思路,还是去年的事,这也是“流安全”思路形成的主要阶段。云计算的安全问题之所以突出,是因为虚拟机的动态迁移,以及多业务系统交织在一起&…

一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现3
这篇我们看一个”容错“”节省“的实例。一下是一个Win32API的声明(转载请指明出处) LONG WINAPI RegEnumKeyEx(__in HKEY hKey,__in DWORD dwIndex,__out LPTSTR lpName,__inout LPDWORD lpcName,__reserved LPDWORD lp…
腾讯Angel升级:加入图算法,支持十亿节点、千亿边规模!中国首个毕业于Linux AI基金会的开源项目...
出品 | AI科技大本营(ID:rgznai100)【导语】Angel 是腾讯的首个AI开源项目,于 2016 年底推出、2017年开源。近日,快速发展的 Angel 完成了从 2.0 版本到 3.0 版本的跨越,从一个单纯的模型训练系统进化成包…

如何在JSP页面中获取当前系统时间转
出自:http://hi.baidu.com/itfuck_/item/803662469cdf7baa61d7b945 1: import java.util.*; int y,m,d,h,mm; Calendar c Calendar.getInstance(); y c.get(Calendar.YEAR); //年 m c.get(Calendar.MONTH) 1; //月 d c.get(Calendar.DAY_OF_MONTH); //日 …
如何用Python实现超级玛丽的界面和状态机?
作者 | marble_xu编辑 | 郭芮来源 | CSDN博客小时候的经典游戏,代码参考了github上的项目Mario-Level-1(https://github.com/justinmeister/Mario-Level-1),使用pygame来实现,从中学习到了横版过关游戏实现中的一些处理…

一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现4
今天为了KPI,搞了一天的PPT,搞得恶心想吐。最后还是回到这儿,这儿才是我的净土,可以写写我的研究。 这儿讲一些Reactos中一些明显的错误。(转载请指明出处) 在Reactos的RegQueryInfoKeyW中有段这样的实现 i…

Netscaler 认证,访问报http 5000 内部错误
在VDI项目中,Netscaler经常与AD不在同一网络,有时在icaprofile中写的SF或WI的FQDN,访问VDI,会报http 5000 内部错误;解决办法如下:1.NS无法解析Storefont或WI的主机名,需要修改icaprofile 中SF或…
解读 | 2019年10篇计算机视觉精选论文(中)
导读:2019 年转眼已经接近尾声,我们看到,这一年计算机视觉(CV)领域又诞生了大量出色的论文,提出了许多新颖的架构和方法,进一步提高了视觉系统的感知和生成能力。因此,我们精选了 20…
PE文件和COFF文件格式分析--概述
刚工作的时候,我听说某某大牛在做病毒分析时,只是用notepad打开病毒文件,就能大致猜到病毒的工作原理。当时我是佩服的很啊,同时我也在心中埋下了一个种子:我也得有这天。随着后来的工作进行,一些任务的和这…

2015第22周六Java反射、泛型、容器简介
Java的反射非常强大,传递class, 可以动态的生成该类、取得这个类的所有信息,包括里面的属性、方法以及构造函数等,甚至可以取得其父类或父接口里面的内容。 obj.getClass().getDeclaredMethods();//取得obj类中自己定义的方法&…

中服公司企业信息化的ERP系统选择
中服公司企业信息化的ERP系统选择一、 中服公司概况 1. 组织概况 中服公司创建于1950年9月,是国家120家企业集团试点单位之一,主要经营各类纺织原料、半成品、服装、针棉毛织品以及其他商品的进出口业务,同时通过合资、联营等方…
PE文件和COFF文件格式分析--MS-DOS 2.0兼容Exe文件段
MS 2.0节是PE文件格式中第一个“节”。其大致结构如下:(转载请指明来源于breaksoftware的csdn博客) 在VC\PlatformSDK\Include\WinNT.h文件中有对MS-DOS 2.0兼容EXE文件头的完整定义 typedef struct _IMAGE_DOS_HEADER { // DOS .EXE h…
时间可以是二维的?基于二维时间图的视频内容片段检测 | AAAI 2020
作者 | 彭厚文、傅建龙来源 | 微软研究院AI头条(ID: MSRAsia)编者按:当时间从一维走向二维,时序信息处理问题中一种全新的建模思路由此产生。根据这种新思路及其产生的二维时间图概念,微软亚洲研究院提出一种新的解决时…

《燃烧的岁月》
温含着优美的文句中,字里行间,透过一层薄薄的纸,牵挂起往事如烟,曾经的努力和成长,透过那以视频同时走过的路,默默无闻,牵挂着的是一句句唯美的文笔,留下情感的诗句文笔,…

PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头1
本文将讨论PE文件中非常重要的一部分信息。(转载请指明来源于breakSoftware的CSDN博客) 首先说一下VC中对应的数据结构。“签名、COFF文件头和可选文件头”这三部分信息组合在一起是一个叫IMAGE_NT_HEADERS的结构体。 typedef struct _IMAGE_NT_HEADERS6…
遇到bug心寒了?用Enter键即可解决!
本文图片来自网络做程序员难不难?很难!做个程序员压力大不大?超级大!!测试bug时(图片来自网络)当找到Bug,开始修改的你……(图片来自网络)那怎么办࿱…

8月第1周安全回顾 0Day漏洞成企业最大威胁 应重视网络监听
文章同时发表在:[url]http://netsecurity.51cto.com/art/200708/52822.htm[/url]本周(0730至0805)安全方面值得关注的新闻集中在安全管理、安全威胁和安全产品方面。安全管理:0Day漏洞***成为企业信息安全的最大威胁新闻ÿ…

最大匹配、最小顶点覆盖、最大独立集、最小路径覆盖(转)
在讲述这两个算法之前,首先有几个概念需要明白: 二分图: 二分图又称二部图,是图论中的一种特殊模型。设G(V,E)是一个无向图,如果顶点V可以分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个…
一种在注入进程中使用WTL创建无焦点不在任务栏出现“吸附”窗口的方法和思路
最近一直在做沙箱项目,在项目快接近结尾的时候,我想给在我们沙箱中运行的程序界面打上一个标记——标识其在我们沙箱中运行的。我大致想法是:在被注入程序的顶层窗口上方显示一个“标题性”窗口,顶层窗口外框外显示一个“异形”的…

转:ASP.NET状态保存方法
ASP.NET状态保存分为客户端保存和服务器端保存两种:使用客户端选项存储页信息而不使用服务器资源的这些选项往往具有最低的安全性但具有最快 的服务器性能,因为对服务器资源的要求是适度的。但是,由于必须将信息发送到客户端来进行存储&#…
时至今日,NLP怎么还这么难!
作者 | 刘知远在微博和知乎上关注自然语言处理(NLP)技术的朋友,应该都对#NLP太难了#、#自然语言理解太难了#两个话题标签不陌生,其下汇集了各种不仅难煞计算机、甚至让人也发懵的费解句子或歧义引起的笑话。然而,这些例…
Quartz定时任务学习(四)调度器
org.quartz.Scheduler 类层次 作为一个 Quartz 用户,你要与实现了 org.quartz.Scheduler 接口的类交互。在你调用它的任何 API 之前,你需要知道如何创建一个 Scheduler 的实例。取而代之的是用了某个工厂方法来确保了构造出 Sheduler 实例并正确的得到初…

反汇编算法介绍和应用——线性扫描算法分析
做过逆向的朋友应该会很熟悉IDA和Windbg这类的软件。IDA的强项在于静态反汇编,Windbg的强项在于动态调试。往往将这两款软件结合使用会达到事半功倍的效果。可能经常玩这个的朋友会发现IDA反汇编的代码准确度要高于Windbg,深究其原因,是因为I…

项目计划书的内容
1.引言 1.1计划的目的 1.2项目的范围和目标 1.2.1范围描述 1.2.2主要功能 1.2.3性能 1.2.4管理和技术约束 2.项目估算 2.1使用的历史数据 2.2使用的评估技术 2.3工作量、成本、时间估算 3.风险管理战略 3.1风险识别 3.2有关风险的讨论 3.3风险管理计划 3.3.1风险计划 3.3.2风险…