注册表分键值对
REG_BINARY | 二进制 |
REG_DWORD | 四字节 |
REG_EXPAND_SZ | 可扩展字符串,可以引用系统变量 比如%temp% %systemroot% (ExpandEnvironmentStrings 展开%systemroot%,函数可查询系统变量 ) |
REG_SZ | 字符串 |
REG_MULTI_SZ | 多文本字符串 这个可以多个字符组合 中间以\0隔开 最后以\0\0结尾 |
驱动中只有\\Registry\\Machine\\software和REGISTRY\\User\\
REG_MULTI_SZ 补充:
“str1\0str2\0str3\0\0“多字符串,(str1,str2,str3本身不含’\0’了,也可理解为str1str2str3\0,str1,str2,str3为NULL结尾)
组合方法:
sprintf(buf,"%s%c%s%c%c","1.1.1.1",0,"2.2.2.2",0,0);
遍历方式
for(p=multistrz;*p==L'\0';p=p+wcslen(p)+1)
{
}
多字符串应用可以在删除与重命名:
BOOL WINAPI MoveFileEx(
__in LPCTSTR lpExistingFileName,
__in_opt LPCTSTR lpNewFileName,//第二个参数NULL就是删除,其他事重命名,发生在系统重启之后
__in DWORD dwFlags
);
//其实就是操作注册表,在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations
上面一般用在删除文件,文件正在被占用,或者更新卸载软件。
还有就是UNC应用(Universal Naming Convention)通用命名规则,比如网络访问文件UNC路径就是
\\servername\sharename\directory\filename比如就是\\\\192.168.0.1\\mydocs\\x.txt对应本地路径D:\\tete\\x.txt,这个就是在注册表
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServe\Shares里有映射关系。mydocs映射着本地路径D:\\tete,通俗就是一个文件夹被共享。一般在安全软件下规则在本地路径,所以要把UNC路径转换成本地路径。
思路
在第三个和第四个"\"之间的就是share的valuekey名字,然后把期求出,然后遍历判断多字符串是否是path
开头,然后拼接起来,找到。那把注册表中的数据读入到一个buffer,解析这个buffer可以用一个指针指向buffer,可以用
for(p=multistrz;*p==L'\0';p=p+wcslen(p)+1)
注册表的存储
以文件形式存放在%systemroot%SYSTEM32/CONFIG目录下的6个HIVE文件,DEFAULT,SAM(用户名密码),SECURITY,SOFTWARE,USERDIFF和SYSTEM中。用户配置信息存在磁盘users/user中,ntuser.dat,ntuser.ini,ntuser.dat.log,每个文件路径由注册表HKLM/SYSTEM/currentControlSet/Control/HIVElist键值指出。
reghive注册表解析:
https://www.52pojie.cn/thread-41492-1-1.html
常用API
KEY就是左边的相当于文件夹,valuekey就是里面的内容,相当与文件。
ZwCreateKey 创建KEY
ZwEnumerateKey 枚举KEY
ZwQueryKey 查询KEY
ZwDeleteKey 删除KEY
ZwEnumerateValueKey 枚举valuekey
ZwQueryValueKey 查询valuekey
ZwSetValueKey 设置创建valuekey
ZwDeleteValueKey 删除valuekey
相关函数
ntStatus = ZwCreateKey(
&hRegister,
KEY_ALL_ACCESS,
&objectAttributes,
0,
NULL,
REG_OPTION_NON_VOLATILE,//参数这样才能保留,如REG_OPTION_VOLATILE关机消失,只在内存中,不在文件中
&ulResult);
如果要枚举流程是zwopenkey,然后zwquerykey查询,有多少个key和subkey,要查询两遍,第一次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的长度,所以buffer为null,长度0,返回的是实际需要的大小,然后根据返回值分配内存,然后就可以查询了,然后ZwEnumerateKey也需要两次,第一次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的长度,第二次为了获取数据。
总体来说就是查询注册表不知道大小,要先传null得到大小,然后根据大小查询。