要做注册表沙箱,就必须要了解部分注册表知识。而注册表的知识很多,本文主要讲述如何在win32系统是上识别注册表映射的。(转载请指明出处)

在我的xp 32bit系统上,Win+R regedit之后打开注册表管理器。我们可以看到如下主键:HKEY_CLASSES_ROOT、HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE、HKEY_USERS和HKEY_CURRENT_CONFIG。如果关注过注册表的同学可能发现过一个现象:修改HKEY_CURRENT_USER下某键项值为A,搜索A,可以搜索到1~3个结果,不仅值相同,其项的父键名等都一样。这种被“同步”的功能是不是很有意思。其实这个现象是因为HKEY_CURRENT_USER键是HKEY_USERS下某键的映射。同样的HKEY_CLASSES_ROOT和HKEY_CURRENT_CONFIG是HKEY_LOCAL_MACHINE下某键的映射。

如果Hook过NtOpenKey的同学可能发现过一个现象,我们参数中的注册表路径往往是\Registry\User\……或者\Registry\Machine\……的形式,而没有见过其他形式的路径。\Registry\User对应于HKEY_USERS,\Registry\Machine对应于HKEY_LOCAL_MACHINE。HKEY_CLASSES_ROOT 和HKEY_CURRENT_CONFIG对应的注册表也是很固定的,分别是\Registry\Machine\SOFTWARE\Classes和\Registry\Machine\CurrentControlSet\Hardware Profiles\Current。最捉摸不定的是HKEY_CURRENT_USER的真实路径,我在网上找了一种方法,该方法仅适用于win32系统,我验证过,该方法在win64系统上是不正确的。下面我用程序描述这种思路:

1 枚举所有ProfileList键下子键

BOOL CConvertRegPath::GetSIDOnWin32( ATL::CString & cstrSid )
{BOOL bSuc = FALSE;// 通过枚举HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList// 下所有子键,确定哪个是SIDdo {HKEY hKey = NULL; if ( ERROR_SUCCESS != RegOpenKey( HKEY_LOCAL_MACHINE, ProfileList, &hKey ) ) {break;}WCHAR wszKey[MaxKeyName] = {0}; DWORD nIndex = 0;DWORD dwLen = MaxKeyName;ATL::CString cstrKeyPath;ATL::CString cstrTmpSid;while ( ERROR_SUCCESS == RegEnumKey( hKey, nIndex++, wszKey, dwLen ) ) { cstrSid = wszKey; // 拼接完整的注册表DOS路径cstrKeyPath = ProfileList;cstrKeyPath += L"\\";cstrKeyPath += cstrSid;cstrKeyPath += L"\\"; 

2  判断SID是否为当前用户的SID

            if ( IsSidKey( cstrKeyPath ) && cstrSid.GetLength() > CurrentUserSidMinLength ) {bSuc = TRUE;break;}cstrSid.Empty();dwLen  = MaxKeyName; wmemset( wszKey, 0, MaxKeyName );} 

其中IsSidKey函数的实现如下

BOOL CConvertRegPath::IsSidKey( const ATL::CString & cstrKeyPath )
{// 该函数通过判断项RefCount值是否大于0来判断该项名是否是SID值BOOL bSidKey = FALSE;do {DWORD dwRefCount = 0;DWORD dwLength = sizeof(DWORD);LONG lRes = RegQueryValueEx( HKEY_LOCAL_MACHINE, cstrKeyPath.GetString(), NULL, NULL, (LPBYTE)&dwRefCount, &dwLength );// 检查项值是否大于0if ( dwRefCount > 0 ){bSidKey = TRUE;}} while (0);return bSidKey;
}

该函数就是判断诸如HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-21-73586283-2049760794-839522115-1003键下项RefCount的值是否大于0(一般为1)。其实符合这样的键可能不止一个,比如本机上HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-18键的RefCount就是1。于是就又要加个判断,就是键名长度要大于一定的长度(我定义为20)。
      类源码

2012-6-11 追加

今天看了别人转载SUDAMI的一篇关于获取SID的方法,个人觉得那个方法比以上经验之谈要靠谱,故贴出他的代码,也没找到他博客的地址,就不列出他博文地址了。

int GetUserName ()
{HANDLE hProcess = GetCurrentProcess();if(!hProcess) {return 0;}HANDLE hToken;if( !OpenProcessToken(hProcess, TOKEN_QUERY, &hToken) || !hToken ){CloseHandle(hProcess);return 0;}DWORD dwTemp = 0;char tagTokenInfoBuf[256] = {0};PTOKEN_USER tagTokenInfo = (PTOKEN_USER)tagTokenInfoBuf;if( !GetTokenInformation( hToken, TokenUser, tagTokenInfoBuf, sizeof(tagTokenInfoBuf), &dwTemp ) ) {CloseHandle(hToken);CloseHandle(hProcess);return 0;}typedef BOOL (WINAPI* PtrConvertSidToStringSid)(PSID Sid,LPTSTR* StringSid );PtrConvertSidToStringSid dwPtr = (PtrConvertSidToStringSid)GetProcAddress( GetModuleHandle(L"Advapi32.dll"), "ConvertSidToStringSidA" );LPTSTR MySid = NULL;dwPtr( tagTokenInfo->User.Sid, (LPTSTR*)&MySid );printf("sudami's PC Name:\n%s\n", MySid);getchar ();LocalFree( (HLOCAL)MySid );CloseHandle(hToken);CloseHandle(hProcess);return 0;
}

在内核里有个函数RtlFormatCurrentUserKeyPath也可以获得SID,在Ntdll中也可以导出这个函数。我做了下实验,发现在Ring3不能直接使用该函数获取SID,因为会报错

错误原因应该很明显了,这个函数内部应该要访问系统空间地址(0x7FFFFFFF以上)上的地址,于是就C0000005了。

一种注册表沙箱的思路、实现——注册表的一些基础知识相关推荐

  1. 一种注册表沙箱的思路、实现

    从今年4月份开始,我接触到一个沙箱项目.该项目的需求要求我们的沙箱具有良好的安全性和兼容性.当时我们研究了SandBoxIE和360的沙箱,基本确定通过"重定向"思路来实现这款沙箱 ...

  2. 一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现2

    上一篇博文中主要介绍了Reactos中大部分函数的思路和HKEY和HANDLE之间的关系,本文将介绍一些Reactos中有意思的函数和存在bug的函数.(转载请指明出处) CreateNestedKe ...

  3. 一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现1

    因为我们沙箱注入了一个DLL到了目标进程,并且Hook了一系列NtXX(NtOpenKey)函数,所以我们在注入的代码中是不能使用RegXX(RegOpenKey等)这类函数的.因为RegXX系列函数 ...

  4. 一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现3

    这篇我们看一个"容错""节省"的实例.一下是一个Win32API的声明(转载请指明出处) LONG WINAPI RegEnumKeyEx(__in HKEY ...

  5. 一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现4

    今天为了KPI,搞了一天的PPT,搞得恶心想吐.最后还是回到这儿,这儿才是我的净土,可以写写我的研究. 这儿讲一些Reactos中一些明显的错误.(转载请指明出处) 在Reactos的RegQuery ...

  6. 一种注册表沙箱的思路、实现——Hook Nt函数

    Nt函数是在Ring3层最底层的函数了,选择此类函数进行Hook,是为了提高绕过门槛.我的Hook方案使用的是微软的Detours.(转载请指明出处) Detours的Hook和反Hook的写入如下: ...

  7. 一种多层级机构数据库表设计的思路及组织机构树数据库表设计

    在实际开发过程中,经常存在多个层级结构的设计,而且多个层级结构还需要排序.这里通过将多级结构的数据在同一张表中(无需多张表进行关联),并通过level的巧妙设计来实现单表查询. level的设计原则: ...

  8. 一种新的攻击方式:使用Outlook 表单进行横向渗透和常驻

    本文讲的是一种新的攻击方式:使用Outlook 表单进行横向渗透和常驻, 背景 最近我们针对CrowdStrike服务进行例行调查,发现了一种攻击方法,其主要用于横向渗透和系统常驻,而且是以前我们没有 ...

  9. 【特征提取+分类模型】4种常见的NLP实践思路

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:陈琰钰,清华大学,Datawhale成员 越来越多的人选择参加算法 ...

最新文章

  1. LEMP+memcached
  2. 进击的UI--------------------GETPOST
  3. Spring Boot 2.4 对多环境配置的支持更改
  4. FFmpeg options
  5. 聋人工学院计算机老师,聋人工学院12位手语老师用双手传递声音
  6. 那些牛逼的数据分析师,SQL用的到底有多溜
  7. python理论知识选择题_python基础知识练习题(二)
  8. 《Python编程实战:运用设计模式、并发和程序库创建高质量程序》—— 2.7 代理模式...
  9. 手机做linux启动盘,教你制作Linux操作系统的USB启动盘
  10. 一台主机接两个显示器并独立使用_一台电脑如何满足多人同时使用?试试这招!...
  11. 计算机中word音乐符号在哪里找,word音乐符号怎么打出来|word音乐符号怎么打
  12. 使用阿里云服务器搭建自己的个人网站
  13. 有雌雄一对兔子,假定过两个月便可繁殖雌雄各一的一对小兔子。问过n个月后共有多少对兔子?递归函数解决
  14. CorelDRAW2022(CDR2022-64位),Win7 、Win10通用\免激活注册中文版安装图文教程
  15. brctl配置linux bridge及虚拟bridge实现
  16. HTML之基础标签_思维导图版
  17. k8s集群中部署kong网关与konga
  18. Linux 学习 第六单元
  19. 西南大学计算机学院读博咋样,专硕想读博士,难吗?北大学长如是说!
  20. 小米电池温度测试软件,MIUI12怎么看电池温度 小米手机电池损耗寿命查看方法...

热门文章

  1. 使用Python,EoN模拟网络中的疾病扩散模型,并结合matplotlib绘图
  2. PyCharm导入numpy包遇到的问题
  3. STM32CubeMX简介、下载及安装(NB-IoT专栏—基础篇3)
  4. Linux下视频截取命令
  5. Linux下代码运行不了?看这里设置环境变量
  6. c语言已知先序还原二叉树,(c++ 递归)先序 中序 还原二叉树
  7. 给python点颜色青少年学编程_早晨送给自己的句子,句句经典励志!
  8. python什么模块动态调用链接库_Python调用C/C++动态链接库的方法详解
  9. Udacity机器人软件工程师课程笔记(二十一) - 对点云进行集群可视化 - 聚类的分割 - K-means|K均值聚类, DBSCAN算法
  10. Pip install: ImportError: cannot import name IncompleteRead