DSAnd писал(а):
Картинка в точности описывает условие данной задачи.Ех...

Add(MainForm,2953706,154,119)
{
Width=544
Height=188
}
Add(InlineCode,9836184,322,168)
{
WorkPoints=#4:test|
EventPoints=#4:info|
DataPoints=#7:rootkey|3:key|3:del|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|38:uses Windows, kol, err, Share, Debug ;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|9: public|22: rootkey:THI_Event;|18: key:THI_Event;|18: del:THI_Event;|19: info:THI_Event;|0:|45: procedure test(var dt:TData; index:word);|4: |22: constructor Create;|32: destructor Destroy; override;|5: end;|1: |4:var |22: hiClass:THiAsmClass;|0:|14:implementation|0:|5:const|32: HEAP_ZERO_MEMORY = $00000008;|23: SDDL_REVISION_1 = 1;|0:|136: HKEYNames: array[0..4] of string = ('HKEY_CLASSES_ROOT','HKEY_CURRENT_USER','HKEY_LOCAL_MACHINE','HKEY_USERS','HKEY_CURRENT_CONFIG');|6: |4:type|29: SID_AND_ATTRIBUTES = record|14: Sid: PSID;|22: Attributes: DWORD;|6: end;|0:|4:type|28: PTOKEN_USER = ^TOKEN_USER;|21: TOKEN_USER = record|29: User: SID_AND_ATTRIBUTES;|6: end;|0:|126:// https://learn.microsoft.com/ru-ru/windows/win32/api/sddl/nf-sddl-convertsecuritydescriptortostringsecuritydescriptora |61:function ConvertSecurityDescriptorToStringSecurityDescriptor(|63: SecurityDescriptor: PSECURITY_DESCRIPTOR; |39: RequestedStringSDRevision: DWORD;|49: SecurityInformation: SECURITY_INFORMATION; |42: var StringSecurityDescriptor: LPSTR;|137: StringSecurityDescriptorLen: PULONG): BOOL; stdcall; external advapi32 name 'ConvertSecurityDescriptorToStringSecurityDescriptorA';|120:// https://learn.microsoft.com/ru-ru/windows/win32/api/sddl/nf-sddl-convertstringsecuritydescriptortosecuritydescriptora|61:function ConvertStringSecurityDescriptorToSecurityDescriptor(|54: StringSecurityDescriptor: LPCSTR;|46: StringSDRevision: DWORD; |59: var SecurityDescriptor: Windows.PSECURITY_DESCRIPTOR;|148: SecurityDescriptorSize: PULONG): BOOL; stdcall; external advapi32 name 'ConvertStringSecurityDescriptorToSecurityDescriptorA'; |0:|31:function ConvertSidToStringSid(|32: Sid: PSID; |92: var StringSid: LPSTR): BOOL; stdcall; external advapi32 name 'ConvertSidToStringSidA';|31:function ConvertStringSidToSid(|39: StringSid: LPCSTR;|85: var Sid: PSID): BOOL; stdcall; external advapi32 name 'ConvertStringSidToSidA';|0:|31:constructor THiAsmClass.Create;|5:begin|18: inherited Create;|17: hiClass := self;|4:end;|0:|31:destructor THiAsmClass.Destroy;|5:begin|19: inherited Destroy;|4:end;|0:|44:function Str2HKey(const skey: string): HKey;|3:var|10: i: byte;|5:begin|15: Result := $0;|47: for i := Low(HKEYNames) to High(HKEYNames) do|7: begin|31: if HKEYNames[i] = skey then|38: Result := HKEY_CLASSES_ROOT + i;|6: end;|4:end;|0:|57:function GetCurrentUserSIDString(sDefault:string):string;|20:var dwLength: DWORD;|18: Token:THandle;|27: pTokenUser:PTOKEN_USER;|20: StringSid:PChar;|5:begin|19: result:=sDefault;|14: dwLength:=0;|20: pTokenUser := nil;|58: OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token);|77: if not GetTokenInformation(Token, TokenUser, pTokenUser, 0, dwLength) then |7: begin|51: if GetLastError=ERROR_INSUFFICIENT_BUFFER then |6: begin|72: pTokenUser:=HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwLength);|30: if pTokenUser<>nil then |8: begin|86: if GetTokenInformation(Token, TokenUser, pTokenUser, dwLength, dwLength) then |7: begin|65: ConvertSidToStringSid(pTokenUser^.User.Sid, StringSid);|28: result:=StringSid;|39: LocalFree(HLOCAL(StringSid));|12: end;|48: HeapFree(GetProcessHeap, 0, pTokenUser);|10: end;|8: end;|6: end;|21: CloseHandle(Token);|4:end;|0:|74:function SetPrivilege(sPrivilegeName: string; bEnabled: boolean): boolean;|3:var|31: TPPrev, TP: TTokenPrivileges;|17: Token: THandle;|18: dwRetLen: DWord;|5:begin|18: Result := False;|85: OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES OR TOKEN_QUERY, Token);|25: TP.PrivilegeCount := 1;|82: if LookupPrivilegeValue(nil, PChar(sPrivilegeName), TP.Privileges[0].LUID) then |9: begin |22: if (bEnabled) then|57: TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED|8: else|45: TP.Privileges[0].Attributes := 0; |20: dwRetLen := 0;|71: // функция выполняется успешно, возвращается ненулевое значение. |178: // Чтобы определить, настроила ли функция все указанные привилегии, вызовите Метод GetLastError, который возвращает одно из следующих значений при успешном выполнении функции:|55: // ERROR_SUCCESS - ok, ERROR_NOT_ALL_ASSIGNED - fail|97: AdjustTokenPrivileges(Token, False, TP, SizeOf(TPPrev), TPPrev, dwRetLen); //0 error, >0 ok|30: if GetLastError = 0 then|23: Result := true; |6: end;|21: CloseHandle(Token);|5:end; |0:|87:function SetRegPermission(Key:HKey; SubKeyName:WideString; ResetAccess:string):boolean;|4:var |27: dwSize,RegResult:DWORD;|44: pNewSD,pSD:Windows.PSECURITY_DESCRIPTOR;|17: pSdStr:PChar;|16: SvcKey:HKey;|20: dwLength: DWORD;|18: Token:THandle;|27: pTokenUser:PTOKEN_USER;|18: sNewSD:string;|5:begin|16: result:=false;|0:|55:if SetPrivilege('SeTakeOwnershipPrivilege', True) then |5:begin|0:|5: try|81: RegResult:=RegOpenKeyExW(Key, PWideChar(SubKeyName), 0, WRITE_OWNER, SvcKey);|4: |36: if RegResult=ERROR_SUCCESS then |6: begin|18: dwLength:=0;|25: pTokenUser := nil; |62: OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token);|81: if not GetTokenInformation(Token, TokenUser, pTokenUser, 0, dwLength) then |8: begin|60: if GetLastError=ERROR_INSUFFICIENT_BUFFER then begin|76: pTokenUser:=HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwLength);|39: if pTokenUser<>nil then begin|90: if GetTokenInformation(Token, TokenUser, pTokenUser, dwLength, dwLength) then |8: begin|57: GetMem(pSD,SECURITY_DESCRIPTOR_MIN_LENGTH);|78: InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);|63: SetSecurityDescriptorDacl(pSD, True, Nil, False);|75: SetSecurityDescriptorOwner(pSD, pTokenUser^.User.Sid, FALSE);|91: SysErrorMessage( RegSetKeySecurity(SvcKey,OWNER_SECURITY_INFORMATION, pSD) );|27: FreeMem(pSD);|16: end;|52: HeapFree(GetProcessHeap, 0, pTokenUser);|14: end;|12: end;|10: end;|25: CloseHandle(Token);|26: RegCloseKey(SvcKey);|8: end;|9: finally|52: SetPrivilege('SeTakeOwnershipPrivilege', false);|6: end;|0:|2: |93: RegResult:=RegOpenKeyExW(Key, PWideChar(SubKeyName), 0, READ_CONTROL or WRITE_DAC, SvcKey);|1: |88: if RegResult<>ERROR_SUCCESS then raise Exception.Create(e_Custom, int2str(RegResult));|2: |5: try|13: pSD:=nil;|15: // dwSize:=0; |24: dwSize:=1024;//276; |1: |77: RegResult:=RegGetKeySecurity(SvcKey,DACL_SECURITY_INFORMATION, pSD, dwSize);|90: if RegResult<>ERROR_SUCCESS then raise Exception.Create(e_Custom, int2str(RegResult));|0:|23: GetMem(pSD,dwSize);|68: InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);|81: RegResult:=RegGetKeySecurity(SvcKey, DACL_SECURITY_INFORMATION, pSD, dwSize);|90: if RegResult<>ERROR_SUCCESS then raise Exception.Create(e_Custom, int2str(RegResult));|126: if ConvertSecurityDescriptorToStringSecurityDescriptor(pSD, SDDL_REVISION_1, DACL_SECURITY_INFORMATION, pSdStr, nil) then |6: begin|15: pNewSD:=nil;|123: if ResetAccess <> '' then sNewSD:=ResetAccess else sNewSD:= pSdStr+'(A;OICI;GA;;;'+GetCurrentUserSIDString('BA')+')';|110: if ConvertStringSecurityDescriptorToSecurityDescriptor(PChar(sNewSD), SDDL_REVISION_1, pNewSD, nil) then|50: if IsValidSecurityDescriptor(pNewSD) then |7: begin|82: RegResult:=RegSetKeySecurity(SvcKey, DACL_SECURITY_INFORMATION, pNewSD);|42: if RegResult=ERROR_SUCCESS then |9: begin|32: ResetAccess:=pSdStr;|25: result:=true;|14: end;|12: end;|52: if pNewSD<>nil then LocalFree(HLOCAL(pNewSD));|32: LocalFree(HLOCAL(pSdStr));|8: end;|9: finally|2: |34: if pSD<>nil then FreeMem(pSD);|24: RegCloseKey(SvcKey);|6: end;|2: |5:end; |4:end;|0:|0:|0:|27:procedure THiAsmClass.test;|21:var RKey, oKey: HKey;|24: uKey, AceStr:string;|19: status:longint;|5:begin|28: uKey:= ToStringEvent(key);|42: RKey:= Str2HKey(ToStringEvent(rootkey));|14: AceStr:= '';|2: |72: // --- https://learn.microsoft.com/ru-ru/windows/win32/api/winreg/ ---|89: // https://learn.microsoft.com/ru-ru/windows/win32/sysinfo/registry-element-size-limits|121: // имена ключей не учитывает регистр https://learn.microsoft.com/ru-ru/windows/win32/api/winreg/nf-winreg-regopenkeyexa|109: // KEY_READ https://learn.microsoft.com/ru-ru/windows/win32/sysinfo/registry-key-security-and-access-rights|68: status:= RegOpenKeyEx(HKey(RKey), PChar(uKey), 0, KEY_READ, oKey);|34: if status <> ERROR_SUCCESS then |7: begin|40: if status = ERROR_ACCESS_DENIED then|11: begin|17: // AceStr|63: // owner (O:), primary group (G:), DACL (D:), SACL (S:)|79: // https://learn.microsoft.com/ru-ru/windows/win32/secauthz/ace-strings|79: // https://learn.microsoft.com/ru-ru/windows/win32/secauthz/sid-strings|98: // AceType;AceFlags;Rights;ObjectGuid;InheritObjectGuid;AccountSid;(ConditionalExpression)|45: // ace_type - "A" SDDL_ACCESS_ALLOWED|101: // ace_flags - "CI" SDDL_CONTAINER_INHERIT, "OI" SDDL_OBJECT_INHERIT, "SA" SDDL_AUDIT_SUCCESS|41: // Rights - "GA" SDDL_GENERIC_ALL|71: // A;OICI;GA;;;AccountSid // "BA" - SDDL_BUILTIN_ADMINISTRATORS|8: |46: _hi_OnEvent(info, 'SetRegPermission');|59: if SetRegPermission(RKey,PChar(uKey), AceStr ) then|13: begin|79: _hi_OnEvent(info, SysErrorMessage(GetLastError)); // Set Rights - ok|8: |42: if ToIntegerEvent(del) = 1 then |11: begin |43: _hi_OnEvent(info, 'DeleteKey');|107: //RegDeleteKeyA(RKey, PChar(uKey)); // for Ex - KEY_WOW64_32KEY 0x0200, KEY_WOW64_64KEY 0x0100 |82: _hi_OnEvent(info, SysErrorMessage(RegDeleteKeyA(RKey, PChar(uKey)))); |9: end; |10: |5: end|6: else|76: _hi_OnEvent(info, SysErrorMessage(status)); // Set Rights - fail |8: end|9: else|116: _hi_OnEvent(info, 'ERROR: ' +uKey + ' > ' + int2str(status)+ ', ' + SysErrorMessage(status)); // other error|5: end|6: else|77: _hi_OnEvent(info, 'INFO: ' +uKey + ' > ' + ' доступ разрешен. Пропуск');|5: |20: RegCloseKey(oKey);|4:end;|0:|4:end.|
link(info,2529294:doAdd,[(373,174)(373,160)])
link(rootkey,4476602:Text,[])
link(key,12581518:Text,[])
link(del,2974096:Checked,[])
}
Add(Memo,2529294,392,154)
{
Left=110
Top=65
Width=410
Height=75
ScrollBars=3
}
Add(Button,6459255,245,161)
{
Left=10
Top=10
link(onClick,15522598:doEvent1,[])
}
Add(Edit,12581518,329,63)
{
Left=110
Top=30
Width=410
Text="SECURITY\\test"
}
Add(Hub,15522598,287,161)
{
link(onEvent1,2529294:doClear,[])
link(onEvent2,9836184:test,[])
}
Add(Edit,4476602,322,21)
{
Left=110
Top=5
Width=410
Text="HKEY_LOCAL_MACHINE"
}
Add(CheckBox,2974096,336,105)
{
Left=15
Top=90
Width=75
Caption="DelKey?"
}