一种注册表沙箱的思路、实现——注册表的一些基础知识
来源:互联网 发布:知乐作品合集网盘下载 编辑:程序博客网 时间:2024/04/30 15:27
要做注册表沙箱,就必须要了解部分注册表知识。而注册表的知识很多,本文主要讲述如何在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 // 下所有子键,确定哪个是SID do { 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 ); // 检查项值是否大于0 if ( 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了。
- 一种注册表沙箱的思路、实现——注册表的一些基础知识
- 一种注册表沙箱的思路、实现
- 一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现1
- 一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现2
- 一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现3
- 一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现4
- 一种注册表沙箱的思路、实现——Hook Nt函数
- 注册表的相关基础知识
- 注册表的一些命令
- HIVE注册表的实现
- 进入注册表的一些常用命令
- 一些有用的注册表片段
- 注册表修复的一些知识
- 注册表的一些操作介绍
- 关于注册表的一些问题
- 注册表Explore的一些选项
- Reg注册表的一些使用方法
- HIVE保存注册表的实现
- 中国四大名著翻译
- 练习笔记5
- JQuery插件 - Uploadify (简单易用的上传插件)配置详解
- 《深入计算机系统》(第九章)
- LoadRunner 11(LR11) 下载链接及破解方法
- 一种注册表沙箱的思路、实现——注册表的一些基础知识
- 一不小心就中国区第一了,顺便说说感想
- SQL Server 2012将与Hadoop无缝集成
- 利用ST提供的USB例程实现USB IAP功能
- 解开Android应用程序组件Activity的"singleTask"之谜
- StringBuffer的使用陷阱
- jdk1.4的下载地址
- eclipse 快捷键
- 保持好奇心!