首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

Windows 2000 下操作受權限限制的登錄機碼完整指南

     編輯:VC 教學

前言

在 Windows 2000 系統中,某些登錄機碼因安全性考量被設置了嚴格的存取控制清單(ACL),導致普通應用程式無法直接讀寫。本文將詳細介紹如何透過 Windows API 動態調整登錄機碼權限,實現對受保護機碼的合法操作,並提供完整的 C++ Builder 代碼範例。

核心原理

Windows 使用安全描述符(Security Descriptor)與存取控制清單(ACL)來管理物件權限。要修改登錄機碼權限,需遵循以下步驟:

  1. 取得目標機碼現有的 DACL(Discretionary ACL)
  2. 建立新的 ACE(Access Control Entry),授予特定用戶(如 Everyone)完整控制權限
  3. 將新 ACE 合併至新的 DACL
  4. 應用新 DACL 至目標機碼
  5. 完成登錄操作後,恢復原始 DACL 以維持系統安全

關鍵 API 函數

  • GetNamedSecurityInfo - 取得物件安全資訊
  • SetNamedSecurityInfo - 設定物件安全資訊
  • BuildExplicitAccessWithName - 建立明確存取結構
  • SetEntriesInAcl - 建立/修改 ACL
  • LocalFree - 釋放系統分配的記憶體

完整代碼實現

// 開始重新配置使用登錄的權限------------------------------------------------
LPTSTR lpObjectName;
SE_OBJECT_TYPE ObjectType; // #include <aclapi.h>
PACL OldDACL, NewDACL;
PSECURITY_DESCRIPTOR SD;
EXPLICIT_ACCESS ea;

lpObjectName = "MACHINE\\SYSTEM\\ControlSet001\\Enum\\Root";
ObjectType = SE_REGISTRY_KEY;

// 建立空的 ACL
if (SetEntriesInAcl(0, NULL, NULL, &OldDACL) != ERROR_SUCCESS) return;
if (SetEntriesInAcl(0, NULL, NULL, &NewDACL) != ERROR_SUCCESS) return;

// 獲取現有的 ACL 列表到 OldDACL
if (GetNamedSecurityInfo(lpObjectName, ObjectType,
    DACL_SECURITY_INFORMATION,
    NULL, NULL,
    &OldDACL,
    NULL, &SD) != ERROR_SUCCESS) {
    Application->MessageBox("指定的鍵不存在!", "提示", MB_OK);
    return;
}

// 設置用戶名 "Everyone" 對指定的鍵有所有操作權到結構 ea
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
BuildExplicitAccessWithName(&ea,
    "Everyone",           // 受信任者名稱
    GENERIC_ALL,          // 存取類型:完整控制
    SET_ACCESS,           // 存取模式:設定
    SUB_CONTAINERS_AND_OBJECTS_INHERIT); // 讓子鍵繼承權限

// 合併結構 ea 和 OldDACL 的權限列表到新的 NewDACL
if (SetEntriesInAcl(1, &ea, NULL, &NewDACL) != ERROR_SUCCESS)
    goto Cleanup;

// 把新的 ACL 寫入到指定的鍵
SetNamedSecurityInfo(lpObjectName, ObjectType,
    DACL_SECURITY_INFORMATION,
    NULL, NULL,
    NewDACL,
    NULL);

/////// 開始操作登錄表 //////////////////////////////////////////////////////////
// ................................................... (在此處進行實際的登錄讀寫操作)
//////////////////////////////////////////////////////////////////////////////

// 恢復登錄表的權限
BuildExplicitAccessWithName(&ea,
    "Everyone",
    GENERIC_READ,         // 僅保留讀取權限
    SET_ACCESS,
    NO_INHERITANCE);      // 不繼承

if (SetEntriesInAcl(1, &ea, NULL, &OldDACL) != ERROR_SUCCESS)
    goto Cleanup;

// 把舊的 ACL 寫入到指定的鍵
SetNamedSecurityInfo(lpObjectName, ObjectType,
    DACL_SECURITY_INFORMATION,
    NULL, NULL,
    OldDACL,
    NULL);

// 釋放指針
Cleanup:
if (SD != NULL) LocalFree((HLOCAL)SD);
if (NewDACL != NULL) LocalFree((HLOCAL)NewDACL);
if (OldDACL != NULL) LocalFree((HLOCAL)OldDACL);

重要注意事項

  • 權限最小化原則:操作完成後務必恢復原始權限,避免造成安全漏洞
  • 錯誤處理:所有 API 呼叫都應檢查返回值,妥善處理失敗情況
  • 記憶體管理:使用 LocalFree 釋放 GetNamedSecurityInfo 分配的安全描述符與 ACL
  • 繼承設定:SUB_CONTAINERS_AND_OBJECTS_INHERIT 確保子機碼繼承權限變更
  • 執行權限:程式需以管理員權限執行,否則無法修改系統機碼 ACL

適用場景

此技術適用於需存取系統關鍵機碼的合法應用場景,如:硬體驅動安裝、系統監控工具、企業級部署腳本等。嚴禁用於繞過安全機制的惡意用途。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved