日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

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

發(fā)布時間:2023/11/27 生活经验 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现2 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

? ? ? ? 上一篇博文中主要介紹了Reactos中大部分函數(shù)的思路和HKEY和HANDLE之間的關(guān)系,本文將介紹一些Reactos中有意思的函數(shù)和存在bug的函數(shù)。(轉(zhuǎn)載請指明出處)

? ? ? ??CreateNestedKey是一個輔助創(chuàng)建鍵的函數(shù),比如我們要創(chuàng)建\Regsitry\User\3\2\1,而我們只是存在\Regsitry\User\,我們最終將調(diào)用此函數(shù)將在User下創(chuàng)建鍵3,然后在3鍵下創(chuàng)建鍵2,最后在2鍵下創(chuàng)建鍵1。假如你是這個函數(shù)的實現(xiàn)者,你要思考這個函數(shù)的實現(xiàn)思路。最容易的辦法是將\Regsitry\User\3\2\1路徑拆成一系列鍵名(\Regsitry\User、3、2、1),然后從根鍵一步一步的調(diào)用NtCreateKey,這樣就可以保證路徑上的所有鍵都被創(chuàng)建。這個方法的優(yōu)點是簡單。但是Reactos實現(xiàn)的思路卻不是這樣的。我列一下我改寫的該函數(shù)。

NTSTATUS OriCreateNestedKey(PHANDLE pKeyHandle,POBJECT_ATTRIBUTES ObjectAttributes,PUNICODE_STRING ClassString,DWORD dwOptions,REGSAM samDesired,DWORD *lpdwDisposition )
{UNICODE_STRING LocalKeyName;NTSTATUS lRes = STATUS_INVALID_PARAMETER;do {if ( NULL == ObjectAttributes || NULL == ObjectAttributes->ObjectName ) {break;}lRes = RtlCreateUnicodeString_( &LocalKeyName, ObjectAttributes->ObjectName->Buffer );CHECKRESULT(lRes);lRes = GETORIFUNC(CreateKey)( pKeyHandle, samDesired,ObjectAttributes, 0, ClassString, dwOptions, (PULONG)lpdwDisposition );if ( STATUS_OBJECT_NAME_NOT_FOUND != lRes ) {return lRes;}OBJECT_ATTRIBUTES LocalObjectAttributes;RtlCopyMemory( &LocalObjectAttributes, ObjectAttributes, sizeof(OBJECT_ATTRIBUTES));LocalObjectAttributes.ObjectName = &LocalKeyName;ULONG FullNameLength = LocalKeyName.Length / sizeof(WCHAR);HANDLE LocalKeyHandle = NULL;PWCHAR Ptr = NULL;ULONG Disposition = 0;// 通過將\\改成結(jié)尾符,逐個去掉最后一個鍵名,查看什么路徑的注冊表鍵存在while ( STATUS_OBJECT_NAME_NOT_FOUND == lRes ) {Ptr = wcsrchr(LocalKeyName.Buffer, '\\');if ( NULL == Ptr || Ptr == LocalKeyName.Buffer ) {lRes = STATUS_UNSUCCESSFUL;break;}// 通過將\\改成結(jié)尾符,通過長度去掉鍵名*Ptr = (WCHAR)0;LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR);lRes = GETORIFUNC(CreateKey)( &LocalKeyHandle, KEY_CREATE_SUB_KEY,&LocalObjectAttributes, 0, NULL, 0, &Disposition );}CHECKRESULT(lRes);// 通過將結(jié)尾符改成\\,重新拼接上鍵名,逐個創(chuàng)建鍵ULONG Length = wcslen(LocalKeyName.Buffer);while ( TRUE ) {if ( NULL != LocalKeyHandle ) {GETORIFUNC(Close) (LocalKeyHandle);}// 通過將結(jié)尾符改成\\,重新拼接上鍵名LocalKeyName.Buffer[Length] = L'\\';Length = wcslen (LocalKeyName.Buffer);LocalKeyName.Length = Length * sizeof(WCHAR);if ( Length == FullNameLength ) {// 如果已經(jīng)拼接回以前的鍵名了,則執(zhí)行完后就退出lRes = GETORIFUNC(CreateKey)( pKeyHandle, samDesired,ObjectAttributes, 0, ClassString, dwOptions, (PULONG)lpdwDisposition);break;}// 創(chuàng)建祖宗鍵lRes = GETORIFUNC(CreateKey)( &LocalKeyHandle, KEY_CREATE_SUB_KEY,&LocalObjectAttributes, 0, NULL, 0, &Disposition);if ( NT_FAILED(lRes) ) {break;}}} while (0);RtlFreeUnicodeString_(&LocalKeyName);return lRes;
}

? ? ? ? 大致說下這個函數(shù)的流程:

  1. 使用NtCreateKey函數(shù)調(diào)用傳入的參數(shù)。如果不是返回STATUS_OBJECT_NAME_NOT_FOUND,則說明要創(chuàng)建的路徑上的鍵的父鍵是存在的,直接返回創(chuàng)建的結(jié)果;否則說明父鍵就不存在,得依賴之后的步驟將父鍵創(chuàng)建起來。
  2. 聲明個變量OBJECT_ATTRIBUTES LocalObjectAttributes;將作為參數(shù)傳入的ObjectAttributes全部拷貝到LocalObjectAttributes,同時記錄下路徑的長度FullNameLength。
  3. 將LocalObjectAttributes.LocalKeyName中的記錄路徑的Buffer字段,從后向前尋找“\”符號,找到一個,就將其改為空,同時再計算LocalObjectAttributes中LocalKeyName的長度。得到修改后的LocalObjectAttributes后,再調(diào)用NtCreateKey。以上面的例子為例,就是用NtCreateKey創(chuàng)建\Regsitry\User\3\2。查看返回結(jié)果,如果結(jié)果還是STATUS_OBJECT_NAME_NOT_FOUND,說明父鍵還是不存在的,于是要重復(fù)3的步驟,一直到NtCreateKey執(zhí)行成功。如例子中,一直到用NtCreateKey創(chuàng)建\Regsitry\User\3就停止這個循環(huán),因為3鍵可以創(chuàng)建成功。
  4. 比較LocalObjectAttributes.LocalKeyName的長度和FullNameLength,如果相等,則說明我們應(yīng)該創(chuàng)建的鍵都創(chuàng)建完了。如果不等,則我們將LocalObjectAttributes.LocalKeyName的最前一個空改成“\”,得到修改后的LocalObjectAttributes,再調(diào)用NtCreateKey。在我們的例子中,就是創(chuàng)建\Regsitry\User\3\2。一直重復(fù)4,一直到LocalObjectAttributes.LocalKeyName的長度和FullNameLength相等。

? ? ? ?我很欣賞這樣的思路,通過改改內(nèi)存達到目的,效率方面會好很多。 ? ??

總結(jié)

以上是生活随笔為你收集整理的一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现2的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。