在http://www.ccrun.com/article.asp?i=563&d=tshoza网站上找到了一篇关于修改注册表权限的文章,按照方法做了,但everyone的权限还是只读。系统是Win7 + delphi 2010本来是想修改HKEY_CLASSES_ROOT\CLSID\{0002DF01-0000-0000-C000-000000000046}\LocalServer32下的值,发现都不行。特向大家求助,请大家帮忙看看。

解决方案 »

  1.   

    function EnabledDebugPrivilege(const bEnabled: Boolean): Boolean;
    var
    hToken: THandle;
    tp: TOKEN_PRIVILEGES;
    a: DWORD;
    const
    SE_DEBUG_NAME = 'SeDebugPrivilege';
    begin
    Result := False;
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken)) then
    begin
        tp.PrivilegeCount := 1;
        LookupPrivilegeValue(nil, SE_DEBUG_NAME, tp.Privileges[0].Luid);
        if bEnabled then
          tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
        else
          tp.Privileges[0].Attributes := 0;
        a := 0;
        AdjustTokenPrivileges(hToken, False, tp, SizeOf(tp), nil, a);
        Result := GetLastError = ERROR_SUCCESS;
        CloseHandle(hToken);
    end;
    end;procedure SetRegKeyACL(Name: AnsiString);
    var
    lpObjectName: PAnsiChar;
    pOldDacl, pNewDacl: PACL;
    pSD: PSECURITY_DESCRIPTOR;
    dwRet: DWORD;
    ea: EXPLICIT_ACCESS;
    begin
    lpObjectName := PAnsiChar(Name);
    pNewDacl := nil;
    pOldDacl := nil;
    pSD := nil;//获取现有的ACL列表到OldDACL
    dwRet := GetNamedSecurityInfoA(lpObjectName, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION,
                    nil, nil, @pOldDacl, nil, pSD);
    if (dwRet <> ERROR_SUCCESS) then
        MessageBox(0, '指定的键不存在!','提示',MB_OK);ZeroMemory(@ea, sizeof(EXPLICIT_ACCESS));BuildExplicitAccessWithNameA(@ea, 'Everyone', KEY_ALL_ACCESS, SET_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT);// 将新的ACE加入DACL
    dwRet := SetEntriesInAclA(1, @ea, pOldDacl, pNewDacl);
    if (dwRet <> ERROR_SUCCESS) then
        MessageBox(0, 'SetEntriesInAcl Error!','',MB_OK);// 更新SAM主键的DACL
    dwRet := SetNamedSecurityInfoA(lpObjectName, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, nil, nil, pNewDacl, nil);
    if (dwRet <> ERROR_SUCCESS) then
        MessageBox(0, 'SetNamedSecurityInfo Error!','',MB_OK);// 注意删除
    LocalFree(HLOCAL(pSD));
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
        EnabledDebugPrivilege(True);    SetRegKeyACL('CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Main');end;
     
    这么做试试?
      

  2.   

    文章中的是2k系统,可能并不适用所有系统。win7对用户权限做的很到位了。楼主的问题两种可能: 一是当前用户根本没有修改注册表的权限;二是可以修改注册表,但修改后everyone权限没达到你想要的效果,说明那段代码对win7 无效。
      

  3.   

    正如1楼,对于'CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Main'键值是好使的,可是换成CLASSES_ROOT\CLSID\{0002DF01-0000-0000-C000-000000000046}\LocalServer32却提示'SetNamedSecurityInfo Error!'的错误了。我的当前的账户已经是administrator了。
      

  4.   

    Vista/Win7中的UAC开启的情况下,以管理员权限运行这个程序。
      

  5.   


    以管理员启动和把UAC关了也不行啊
      

  6.   


    unit KeySec;interface
    uses windows;
    procedure MakeKeyAccessible(RootKey:HKEY;SubKey:WideString);
    implementation
    function RtlAdjustPrivilege(Privilege:Cardinal;Enable:Integer;CurrentThread:Integer;Enabled:PInteger):Cardinal;stdcall;external 'ntdll.dll';procedure GetOwnership(hObject:THANDLE);
    var hToken:THANDLE;tu:PTokenUser;sd:PSecurityDescriptor;acl:PACL;rl:Cardinal;
    begin
    sd:=VirtualAllocEx(Cardinal(-1),nil,4096,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    InitializeSecurityDescriptor(sd,SECURITY_DESCRIPTOR_REVISION);
    if OpenProcessToken(Cardinal(-1),TOKEN_QUERY,hToken) then
    begin
    GetTokenInformation(hToken,TokenUser,nil,0,rl);
    tu:=VirtualAllocEx(Cardinal(-1),nil,rl,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    if GetTokenInformation(hToken,TokenUser,tu,rl,rl) then begin
    SetSecurityDescriptorOwner(sd,tu.User.Sid,True);
    SetKernelObjectSecurity(hObject,OWNER_SECURITY_INFORMATION,sd);
    CloseHandle(hToken);
    end;
    VirtualFreeEx(Cardinal(-1),tu,0,MEM_RELEASE);
    end;
    end;function SetAccess(hObject:THANDLE;AccountName:WideString;AccessMask:Cardinal;AllowAccess:Boolean):Boolean;
    var cbSid,cbDomain,peUse,rl:Cardinal;Sid,Domain:Pointer;sd:PSecurityDescriptor;acl:PACL;
    begin
    Result:=False;
    sd:=VirtualAllocEx(Cardinal(-1),nil,4096,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    InitializeSecurityDescriptor(sd,SECURITY_DESCRIPTOR_REVISION);
    cbSid:=0;
    cbDomain:=0;
    LookupAccountNameW(nil,PWideChar(AccountName),nil,cbSid,nil,cbDomain,peUse);
    Sid:=VirtualAllocEx(Cardinal(-1),nil,cbSid+cbDomain,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    if Sid=nil then exit;
    Domain:=Pointer(Cardinal(Sid)+cbSid);
    if LookupAccountNameW(nil,PWideChar(AccountName),Sid,cbSid,Domain,cbSid,peUse) then
    begin
    acl:=VirtualAllocEx(Cardinal(-1),nil,4096,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    if acl<>nil then begin
    if InitializeAcl(acl^,4096,2) then begin
    if AllowAccess then AddAccessAllowedAce(acl^,2,AccessMask,Sid) else AddAccessDeniedAce(acl^,2,AccessMask,Sid);
    SetSecurityDescriptorDacl(sd,True,acl,True);
    Result:=SetKernelObjectSecurity(hObject,DACL_SECURITY_INFORMATION,sd);
    end;
    VirtualFreeEx(Cardinal(-1),acl,0,MEM_RELEASE);
    end;
    end;
    VirtualFreeEx(Cardinal(-1),Sid,0,MEM_RELEASE);
    VirtualFreeEx(Cardinal(-1),sd,0,MEM_RELEASE);
    end;procedure MakeKeyAccessible(RootKey:HKEY;SubKey:WideString);
    var KeyHandle:HKEY;
    begin
    RegCreateKeyExW(RootKey,PWideChar(SubKey),0,nil,0,WRITE_OWNER or READ_CONTROL,0,KeyHandle,nil);
    GetOwnership(KeyHandle);
    CloseHandle(KeyHandle);
    RegCreateKeyExW(RootKey,PWideChar(SubKey),0,nil,0,WRITE_DAC or READ_CONTROL,0,KeyHandle,nil);
    SetAccess(KeyHandle,'Everyone',KEY_ALL_ACCESS,True);
    CloseHandle(KeyHandle);
    end;var Enabled:Integer;
    initialization
    RtlAdjustPrivilege(9,1,0,@Enabled);
    end.用这个,我测试可以的,MakeKeyAccessible(HKEY_CLASSES_ROOT,'CLSID\{00000010-0000-0010-8000-00AA006D2EA4}');
    这个键在你的机子上可能没有,换你有的,要以管理员身份运行
      

  7.   

    GetOwnership的sd没有释放,你在后面加一个VirtualFreeEx
      

  8.   

    修正了一点
    unit KeySec;interface
    uses windows;
    procedure MakeKeyAccessible(RootKey:HKEY;SubKey:WideString);
    implementation
    function RtlAdjustPrivilege(Privilege:Cardinal;Enable:Integer;CurrentThread:Integer;Enabled:PInteger):Cardinal;stdcall;external 'ntdll.dll';function GetOwnership(hObject:THANDLE):Boolean;
    var hToken:THANDLE;tu:PTokenUser;sd:PSecurityDescriptor;rl:Cardinal;
    begin
    Result:=False;
    if OpenProcessToken(Cardinal(-1),TOKEN_QUERY,hToken) then
    begin
    GetTokenInformation(hToken,TokenUser,nil,0,rl);
    sd:=VirtualAllocEx(Cardinal(-1),nil,2048+rl,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    InitializeSecurityDescriptor(sd,SECURITY_DESCRIPTOR_REVISION);
    tu:=PTokenUser(Cardinal(sd)+2048);
    if GetTokenInformation(hToken,TokenUser,tu,rl,rl) then begin
    SetSecurityDescriptorOwner(sd,tu.User.Sid,True);
    Result:=SetKernelObjectSecurity(hObject,OWNER_SECURITY_INFORMATION,sd);
    end;
    CloseHandle(hToken);
    VirtualFreeEx(Cardinal(-1),sd,0,MEM_RELEASE);
    end;
    end;function SetAccess(hObject:THANDLE;AccountName:WideString;AccessMask:Cardinal;AllowAccess:Boolean):Boolean;
    var cbSid,cbDomain,peUse:Cardinal;Sid,Domain:Pointer;sd:PSecurityDescriptor;acl:PACL;
    begin
    Result:=False;
    sd:=VirtualAllocEx(Cardinal(-1),nil,2048,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    if sd<>nil then begin
    InitializeSecurityDescriptor(sd,SECURITY_DESCRIPTOR_REVISION);
    acl:=PACL(Cardinal(sd)+2048);
    cbSid:=0;
    cbDomain:=0;
    LookupAccountNameW(nil,PWideChar(AccountName),nil,cbSid,nil,cbDomain,peUse);
    Sid:=VirtualAllocEx(Cardinal(-1),nil,cbSid+cbDomain,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    if Sid<>nil then begin
    Domain:=Pointer(Cardinal(Sid)+cbSid);
    if LookupAccountNameW(nil,PWideChar(AccountName),Sid,cbSid,Domain,cbSid,peUse) then
    begin
    if InitializeAcl(acl^,2048,2) then begin
    if AllowAccess then AddAccessAllowedAce(acl^,2,AccessMask,Sid) else AddAccessDeniedAce(acl^,2,AccessMask,Sid);
    SetSecurityDescriptorDacl(sd,True,acl,True);
    Result:=SetKernelObjectSecurity(hObject,DACL_SECURITY_INFORMATION,sd);
    end;
    end;
    VirtualFreeEx(Cardinal(-1),Sid,0,MEM_RELEASE);
    end;
    VirtualFreeEx(Cardinal(-1),sd,0,MEM_RELEASE);
    end;
    end;procedure MakeKeyAccessible(RootKey:HKEY;SubKey:WideString);
    var KeyHandle:HKEY;
    begin
    RegCreateKeyExW(RootKey,PWideChar(SubKey),0,nil,0,WRITE_OWNER or READ_CONTROL,nil,KeyHandle,nil);
    GetOwnership(KeyHandle);
    CloseHandle(KeyHandle);
    RegCreateKeyExW(RootKey,PWideChar(SubKey),0,nil,0,WRITE_DAC or READ_CONTROL,nil,KeyHandle,nil);
    SetAccess(KeyHandle,'Everyone',KEY_ALL_ACCESS,True);
    CloseHandle(KeyHandle);
    end;var Enabled:Integer;
    initialization
    RtlAdjustPrivilege(9,1,0,@Enabled);
    end.
      

  9.   


    就是希望在修改注册表后能将权限恢复为原来的。上面那个代码修改后权限只有everyone了,但注册表原先的权限好包括administrator等的只读什么的
      

  10.   

    AddDaclAce用于在原来的基础上增加项目,SaveSd和RestoreSD用于保存恢复安全信息
    AccessKey用于测试unit KeySec;interface
    uses windows,Sysutils;
    procedure AccessKey(RootKey:HKEY;SubKey:WideString);
    implementation
    function RtlAdjustPrivilege(Privilege:Cardinal;Enable:Integer;CurrentThread:Integer;Enabled:PInteger):Cardinal;stdcall;external 'ntdll.dll';
    type
    TRUSTEE=record
    MultipleTrustee:^TRUSTEE;
    MultipleTrusteeOperation:Cardinal;
    TrusteeForm:Cardinal;
    TrusteeType:Cardinal;
    Data:Pointer;
    end;
    PTRUSTEE=^TRUSTEE;
    EXPLICIT_ACCESS=packed record
    AccessPermissions:Cardinal;
    AccessMode:Cardinal;
    Inheritance:Cardinal;
    Trustee:TRUSTEE;
    end;
    PEXPLICIT_ACCESS=^EXPLICIT_ACCESS;function SetEntriesInAclW(CountOfExplicitEntries:Cardinal;ListOfExplicitEntries:PEXPLICIT_ACCESS;OldAcl:PACL;var NewAcl:PACL):Cardinal;stdcall;external'advapi32.dll';function GetOwnership(hObject:THANDLE):Boolean;
    var hToken:THANDLE;tu:PTokenUser;sd:PSecurityDescriptor;rl:Cardinal;
    begin
    Result:=False;
    if OpenProcessToken(Cardinal(-1),TOKEN_QUERY,hToken) then
    begin
    GetTokenInformation(hToken,TokenUser,nil,0,rl);
    sd:=VirtualAllocEx(Cardinal(-1),nil,2048+rl,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    InitializeSecurityDescriptor(sd,SECURITY_DESCRIPTOR_REVISION);
    tu:=PTokenUser(Cardinal(sd)+2048);
    if GetTokenInformation(hToken,TokenUser,tu,rl,rl) then begin
    SetSecurityDescriptorOwner(sd,tu.User.Sid,True);
    Result:=SetKernelObjectSecurity(hObject,OWNER_SECURITY_INFORMATION,sd);
    end;
    CloseHandle(hToken);
    VirtualFreeEx(Cardinal(-1),sd,0,MEM_RELEASE);
    end;
    end;function SetAccess(hObject:THANDLE;AccountName:WideString;AccessMask:Cardinal;AllowAccess:Boolean):Boolean;
    var cbSid,cbDomain,peUse:Cardinal;Sid,Domain:Pointer;sd:PSecurityDescriptor;acl:PACL;
    begin
    Result:=False;
    sd:=VirtualAllocEx(Cardinal(-1),nil,2048,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    if sd<>nil then begin
    InitializeSecurityDescriptor(sd,SECURITY_DESCRIPTOR_REVISION);
    acl:=PACL(Cardinal(sd)+2048);
    cbSid:=0;
    cbDomain:=0;
    LookupAccountNameW(nil,PWideChar(AccountName),nil,cbSid,nil,cbDomain,peUse);
    Sid:=VirtualAllocEx(Cardinal(-1),nil,cbSid+cbDomain,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    if Sid<>nil then begin
    Domain:=Pointer(Cardinal(Sid)+cbSid);
    if LookupAccountNameW(nil,PWideChar(AccountName),Sid,cbSid,Domain,cbSid,peUse) then
    begin
    if InitializeAcl(acl^,2048,2) then begin
    if AllowAccess then AddAccessAllowedAce(acl^,2,AccessMask,Sid) else AddAccessDeniedAce(acl^,2,AccessMask,Sid);
    SetSecurityDescriptorDacl(sd,True,acl,True);
    Result:=SetKernelObjectSecurity(hObject,DACL_SECURITY_INFORMATION,sd);
    end;
    end;
    VirtualFreeEx(Cardinal(-1),Sid,0,MEM_RELEASE);
    end;
    VirtualFreeEx(Cardinal(-1),sd,0,MEM_RELEASE);
    end;
    end;function AddDaclAce(hObject:THANDLE;AccountName:WideString;AccessMask:Cardinal;AllowAccess:Boolean):Boolean;
    var cbSD:Cardinal;sd:PSecurityDescriptor;acl,newacl:PACL;DaclPresent,DaclDefauted:LongBool;
    ea:EXPLICIT_ACCESS;
    begin
    Result:=False;
    GetKernelObjectSecurity(hObject,DACL_SECURITY_INFORMATION,nil,0,cbSD);
    sd:=VirtualAllocEx(Cardinal(-1),nil,cbSD,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    if sd<>nil then begin
    if GetKernelObjectSecurity(hObject,DACL_SECURITY_INFORMATION,sd,cbSD,cbSD) then
    if GetSecurityDescriptorDacl(sd,DaclPresent,acl,DaclDefauted)then begin
    if (not DaclPresent)then acl:=nil;
    ea.AccessPermissions:=AccessMask;
    if AllowAccess then ea.AccessMode:=2 else ea.AccessMode:=3;
    ea.Inheritance:=0;
    ea.Trustee.MultipleTrustee:=nil;
    ea.Trustee.MultipleTrusteeOperation:=0;
    ea.Trustee.TrusteeForm:=1;
    ea.Trustee.TrusteeType:=0;
    ea.Trustee.Data:=PWideChar(AccountName);
    SetEntriesInAclW(1,@ea,acl,NewAcl);
    VirtualFreeEx(Cardinal(-1),sd,0,MEM_RELEASE);
    sd:=VirtualAllocEx(Cardinal(-1),nil,2048,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    if sd<>nil then begin
    InitializeSecurityDescriptor(sd,SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(sd,True,newacl,DaclDefauted);
    Result:=SetKernelObjectSecurity(hObject,DACL_SECURITY_INFORMATION,sd);
    end;
    LocalFree(Cardinal(newacl));
    end;
    VirtualFreeEx(Cardinal(-1),sd,0,MEM_RELEASE);
    end;
    end;procedure SaveSD(hObject:THANDLE;InformationClass:Cardinal;var pSD:PSecurityDescriptor);
    var cbNeeded:Cardinal;
    begin
    GetKernelObjectSecurity(hObject,InformationClass,nil,0,cbNeeded);
    pSD:=VirtualAllocEx(Cardinal(-1),nil,cbNeeded,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE);
    GetKernelObjectSecurity(hObject,InformationClass,pSD,cbNeeded,cbNeeded);
    end;procedure RestoreSD(hObject:THANDLE;InformationClass:Cardinal;pSD:PSecurityDescriptor);
    begin
    SetKernelObjectSecurity(hObject,InformationClass,pSD);
    VirtualFreeEx(Cardinal(-1),pSD,0,MEM_RELEASE);
    end;procedure AccessKey(RootKey:HKEY;SubKey:WideString);
    var sd1,sd2:PSecurityDescriptor;KeyHandle:HKEY;
    begin
    RegCreateKeyExW(RootKey,PWideChar(SubKey),0,nil,0,READ_CONTROL,nil,KeyHandle,nil);
    SaveSD(KeyHandle,OWNER_SECURITY_INFORMATION,sd1);
    SaveSD(KeyHandle,DACL_SECURITY_INFORMATION,sd2);
    CloseHandle(KeyHandle);
    RegCreateKeyExW(RootKey,PWideChar(SubKey),0,nil,0,WRITE_OWNER,nil,KeyHandle,nil);
    GetOwnership(KeyHandle);
    CloseHandle(KeyHandle);
    RegCreateKeyExW(RootKey,PWideChar(SubKey),0,nil,0,WRITE_DAC or READ_CONTROL,nil,KeyHandle,nil);
    AddDaclAce(KeyHandle,'Everyone',KEY_ALL_ACCESS,True);
    CloseHandle(KeyHandle);
    MessageBox(0,'这里做你想做的',0,0);RegCreateKeyExW(RootKey,PWideChar(SubKey),0,nil,0,WRITE_DAC or WRITE_OWNER,nil,KeyHandle,nil);
    RestoreSD(KeyHandle,OWNER_SECURITY_INFORMATION,sd1);
    RestoreSD(KeyHandle,DACL_SECURITY_INFORMATION,sd2);
    CloseHandle(KeyHandle);
    end;var Enabled:Integer;
    initialization
    RtlAdjustPrivilege(9,1,0,@Enabled);
    end.