<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                在Windows NT中,80386保護模式的“保護”比Windows 95中更堅固,這個“鍍金的籠子”更加結實,更加難以打破。在Windows 95中,至少應用程序I/O操作是不受限制的,而在Windows NT中,我們的應用程序連這點權限都被剝奪了。在NT中幾乎不太可能進入真正的ring0層。? 在Windows NT中,存在三種Device Driver: ? 1.“Virtual device Driver” (VDD)。通過VDD,16位應用程序,如DOS 和Win16應用程序可以訪問特定的I/O端口(注意,不是直接訪問,而是要通過VDD來實現訪問)。 ? 2.“GDI Driver”,提供顯示和打印所需的GDI函數。 ? 3.“Kernel Mode Driver”,實現對特定硬件的操作,比如說CreateFile, CloseHandle (對于文件對象而言), ReadFile, WriteFile, DeviceIoControl 等操作。“Kernel Mode Driver”還是Windows NT中唯一可以對硬件中斷和DMA進行操作的Driver。SCSI 小端口驅動和 網卡NDIS 驅動都是Kernel Mode Driver的一種特殊形式。 Visual studio11與Windows8帶來格外不同的新體驗 1.啟動Vs11 ![](https://box.kancloud.cn/2016-04-01_56fdf153bac99.png) 2.看見滿目的驅動開發模板 ![](https://box.kancloud.cn/2016-04-01_56fdf151a72a9.png) 3.選擇一個驅動模式,有內核模式與用戶模式兩種的驅動 ![](https://box.kancloud.cn/2016-04-01_56fdf151e0f15.png) ? 4.創建一個驅動程序,KMDF DriverMVP ![](https://box.kancloud.cn/2016-04-01_56fdf152053f8.png) ? 5.我們選擇的是內核模式的驅動程序,下面是創建成功后的界面,分別是驅動程序本身,與驅動安裝包 ![](https://box.kancloud.cn/2016-04-01_56fdf15221ca7.png) 6.按下F5,選擇驅動編譯, ? ![](https://box.kancloud.cn/2016-04-01_56fdf15236a2b.png) 插入下列代碼實現基于callback的注冊表監控和過濾技術,請見代碼分析 ~~~ #include "ntifs.h" #include "RegistryCallBack.h" #include <ntstrsafe.h> NTSTATUS st; LARGE_INTEGER g_CallbackCookie; ANSI_STRING astr; VOID UnloadDriver(PDRIVER_OBJECT DriverObject); NTSTATUS RegistryCallback(IN PVOID CallbackContext, IN PVOID Argument1, IN PVOID Argument2); BOOLEAN GetRegistryObjectCompleteName(PUNICODE_STRING pRegistryPath, PUNICODE_STRING pPartialRegistryPath,PVOID pRegistryObject); NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { DbgPrint("[RegRoutine]Loading!\n"); DriverObject->DriverUnload = UnloadDriver; st = CmRegisterCallback(RegistryCallback,NULL,&g_CallbackCookie); if ( !NT_SUCCESS(st) ) { DbgPrint("[RegRoutine]CmRegisterCallback Failed!\n"); return st; } DbgPrint("[RegRoutine]RegistryCallback Addr:0x%08X\n",RegistryCallback); DbgPrint("[RegRoutine]Cookie.LowPart:0x%08X Cookie.HighPart:0x%08X\n",g_CallbackCookie.LowPart,g_CallbackCookie.HighPart); return st; } VOID UnloadDriver(PDRIVER_OBJECT DriverObject) { CmUnRegisterCallback(g_CallbackCookie); DbgPrint("[RegRoutine]UnLoading!\n"); } NTSTATUS RegistryCallback( IN PVOID CallbackContext, IN PVOID Argument1, IN PVOID Argument2 ) { int type; BOOLEAN exception = FALSE; BOOLEAN registryEventIsValid = FALSE; UNICODE_STRING registryPath; UCHAR* registryData = NULL; ULONG registryDataLength = 0; ULONG registryDataType = 0; registryPath.Length = 0; registryPath.MaximumLength = NTSTRSAFE_UNICODE_STRING_MAX_CCH * sizeof(WCHAR); registryPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, registryPath.MaximumLength, 'ConT'); if(registryPath.Buffer == NULL) { DbgPrint("[RegRoutine]Allocate registryPath failed!\n"); return STATUS_SUCCESS; } type = (REG_NOTIFY_CLASS)Argument1; try { switch(type) { case RegNtPostCreateKey: { PREG_POST_CREATE_KEY_INFORMATION createKey = (PREG_POST_CREATE_KEY_INFORMATION)Argument2; if( NT_SUCCESS(createKey->Status) || createKey->Status == STATUS_PENDING ) //創建注冊表項狀態為成功和未決的都記錄一下 { PVOID* registryObject = createKey->Object; registryEventIsValid = GetRegistryObjectCompleteName(?istryPath, createKey->CompleteName,*registryObject); if ( registryEventIsValid ) { RtlUnicodeStringToAnsiString(&astr,?istryPath,TRUE); DbgPrint("[RegCreated]KeyName:%s!\n",astr.Buffer); //如果創建的是自啟動項,則警告一下 if ( strstr(astr.Buffer,"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run") ) { DbgPrint("[RegCreated]Forbin!\n"); DbgPrint("[RegCreated]ForbinKeyName:%s!\n",astr.Buffer); RtlFreeAnsiString(&astr); } RtlFreeAnsiString(&astr); } else DbgPrint("[RegCreated]Get Key Name Failed!\n"); } } break; //使用PreCreateKey可以阻止key的創建,但是能夠作為判斷依據的只有一個key的CompleteName,無法得到完整路徑來判斷 case RegNtPreCreateKey: { PREG_PRE_CREATE_KEY_INFORMATION createKey = (PREG_PRE_CREATE_KEY_INFORMATION)Argument2; RtlCopyUnicodeString(?istryPath,createKey->CompleteName); RtlUnicodeStringToAnsiString(&astr,?istryPath,TRUE); DbgPrint("[RegRoutine]PreCreate:%s!\n",astr.Buffer); if ( !strcmp(astr.Buffer,"新項 #1") ) { DbgPrint("[RegRoutine]Forbin!\n"); DbgPrint("[RegRoutine]ForbinKeyName:%s!\n",astr.Buffer); RtlFreeAnsiString(&astr); return STATUS_INVALID_PARAMETER; } RtlFreeAnsiString(&astr); } break; case RegNtDeleteKey: { PREG_DELETE_KEY_INFORMATION deleteKey = (PREG_DELETE_KEY_INFORMATION)Argument2; registryEventIsValid = GetRegistryObjectCompleteName(?istryPath, NULL, deleteKey->Object); if ( registryEventIsValid ) { RtlUnicodeStringToAnsiString(&astr,?istryPath,TRUE); DbgPrint("[RegDeletedKey]KeyName:%s!\n",astr.Buffer); if ( !strcmp(astr.Buffer,"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\ljh00001") ) { DbgPrint("[RegDeletedKey]Forbin!\n"); DbgPrint("[RegDeletedKey]ForbinKeyName:%s!\n"); RtlFreeAnsiString(&astr); return STATUS_INVALID_PARAMETER; } RtlFreeAnsiString(&astr); } } break; case RegNtSetValueKey: { PREG_SET_VALUE_KEY_INFORMATION setvalue = (PREG_SET_VALUE_KEY_INFORMATION)Argument2; if( MmIsAddressValid(setvalue->ValueName) ) { registryEventIsValid = GetRegistryObjectCompleteName(?istryPath, NULL, setvalue->Object); if ( registryEventIsValid ) { RtlUnicodeStringToAnsiString(&astr,?istryPath,TRUE); DbgPrint("[RegSetValue]ValueParentPath:%s!\n",astr.Buffer); RtlFreeAnsiString(&astr); } RtlUnicodeStringToAnsiString(&astr,setvalue->ValueName,TRUE); DbgPrint("[RegSetValue]ValueName:%s!\n",astr.Buffer); RtlFreeAnsiString(&astr); //輸出設置的鍵值的數據類型和大小,如果類型是REG_SZ則data是一個unicode_string,而數據大小為buffer長度 //加上4字節長度的length和MaxLength再加上2個字節的結尾00的長度 DbgPrint("[RegSetValue]ValueDataType:%X,DataSize:%X\n",setvalue->Type,setvalue->DataSize); if ( setvalue->Type == 1 ) //Type為REG_SZ,其它類型的數據暫時忽略 { DbgPrint("[RegSetValue]Data:%ws\n",setvalue->Data); } } } break; case RegNtDeleteValueKey: { PREG_DELETE_VALUE_KEY_INFORMATION deletevalue = (PREG_DELETE_VALUE_KEY_INFORMATION)Argument2; if( MmIsAddressValid(deletevalue->ValueName) ) { registryEventIsValid = GetRegistryObjectCompleteName(?istryPath, NULL, deletevalue->Object); if ( registryEventIsValid ) { RtlUnicodeStringToAnsiString(&astr,?istryPath,TRUE); DbgPrint("[RegDelValue]ValueParentPath:%s!\n",astr.Buffer); RtlFreeAnsiString(&astr); } RtlUnicodeStringToAnsiString(&astr,deletevalue->ValueName,TRUE); DbgPrint("[RegDelValue]ValueName:%s!\n",astr.Buffer); if ( !strcmp(astr.Buffer,"ljh00001") ) { DbgPrint("[RegDelValue]Forbin!\n"); DbgPrint("[RegDelValue]ForbinKeyName:%s!\n"); RtlFreeAnsiString(&astr); return STATUS_INVALID_PARAMETER; } RtlFreeAnsiString(&astr); } } break; case RegNtRenameKey: { PREG_RENAME_KEY_INFORMATION renamevalue = (PREG_RENAME_KEY_INFORMATION)Argument2; if( MmIsAddressValid(renamevalue->NewName) ) { registryEventIsValid = GetRegistryObjectCompleteName(?istryPath, NULL, renamevalue->Object); if ( registryEventIsValid ) { RtlUnicodeStringToAnsiString(&astr,?istryPath,TRUE); DbgPrint("[RegRenameKey]KeyPath:%s!\n",astr.Buffer); RtlFreeAnsiString(&astr); } RtlUnicodeStringToAnsiString(&astr,renamevalue->NewName,TRUE); DbgPrint("[RegRenameKey]KeyName:%s!\n",astr.Buffer); RtlFreeAnsiString(&astr); } } break; default: break; } } except( EXCEPTION_EXECUTE_HANDLER ) { DbgPrint("[RegRoutine]Catch a Expection!\n"); exception = TRUE; registryEventIsValid = FALSE; } if(registryPath.Buffer != NULL) { ExFreePoolWithTag(registryPath.Buffer, 'ConT'); } return STATUS_SUCCESS; } BOOLEAN GetRegistryObjectCompleteName(PUNICODE_STRING pRegistryPath, PUNICODE_STRING pPartialRegistryPath, PVOID pRegistryObject) { BOOLEAN foundCompleteName = FALSE; BOOLEAN partial = FALSE; NTSTATUS status; ULONG returnedLength; PUNICODE_STRING pObjectName = NULL; //判斷object的有效性 if( (!MmIsAddressValid(pRegistryObject)) || (pRegistryObject == NULL) ) { DbgPrint("[RegRoutine]pRegistryObject Invalid!\n"); return FALSE; } //使用ObQueryNameString來得到object對應的名稱 status = ObQueryNameString(pRegistryObject, (POBJECT_NAME_INFORMATION)pObjectName, 0, &returnedLength ); if(status == STATUS_INFO_LENGTH_MISMATCH) //第一次傳的buffer長度為0,ObQueryNameString返回的結果必定是緩沖區大小不足 { pObjectName = ExAllocatePoolWithTag(NonPagedPool, returnedLength, 'ConT'); //申請內存 if ( pObjectName == NULL ) //申請內存失敗則返回FALSE { DbgPrint("[RegRoutine]AllocatePool Failed!\n"); return FALSE; } //查詢名稱 status = ObQueryNameString(pRegistryObject, (POBJECT_NAME_INFORMATION)pObjectName, returnedLength, &returnedLength ); if(NT_SUCCESS(status)) { RtlUnicodeStringCopy(pRegistryPath, pObjectName); //拷貝名稱 foundCompleteName = TRUE; } ExFreePoolWithTag(pObjectName, 'ConT'); //無論查詢是否成功都應該釋放內存 } return foundCompleteName; } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看