권한 상승이 필요한 로컬 COM 서버를 생성 했으므로 승격되지 않은 프로세스 내부에서 인스턴스화해야합니다.COM Elevation Vista/Windows 7에서 Moniker가 서버를 승격하지 못했습니다.
MSDN's article on the COM elevation moniker을 사용하여 지정된 요구 사항에 따라 서버 클래스를 구성했습니다. 서버가 HKLM 하이브에 성공적으로 등록되었습니다.
코드 샘플 : 그것은 CoGetObject(PWideChar(sMonikerName), @rBindOpts, IID, PInterface)
에 관해서
procedure CoCreateInstanceAsAdmin(const Handle: HWND;
const ClassID, IID: TGuid; PInterface: PPointer);
var
rBindOpts: TBindOpts3;
sMonikerName: WideString;
iRes: HRESULT;
begin
ZeroMemory(@rBindOpts, Sizeof(TBindOpts3));
rBindOpts.cbStruct := Sizeof(TBindOpts3);
rBindOpts.hwnd := Handle;
rBindOpts.dwClassContext := CLSCTX_LOCAL_SERVER;
sMonikerName := 'Elevation:Administrator!new:' + GUIDToString(ClassID);
iRes := CoGetObject(PWideChar(sMonikerName), @rBindOpts, IID, PInterface);
OleCheck(iRes);
end;
class function CoIMyServer.Create: IMyServer;
begin
CoCreateInstanceAsAdmin(HInstance, CLASS_IMyServer, IMyServer, @Result);
end;
는 내가 UAC 화면을 얻을 관리자로 서버를 실행 확인합니다. 그러나 OleCheck(iRes)
은 "요청한 작업에 권한 상승이 필요합니다"오류를 반환합니다.
that article 나는 "Over-The-Shoulder (OTS) Elevation"에 대해 읽었습니다.
승격되지 않은 프로세스에서 내 서버 인스턴스를 사용할 수있는 유일한 방법입니까? 그렇다면 서버에서 언제 CoInitializeSecurity
을 호출해야합니까?
전체 등록 정보
HKLM\SOFTWARE\Wow6432Node\Classes\CLSID
{MyServer CLSID}
(Default) = IMyServer Object
LocalizedString = @C:\Program Files (x86)\MyServer\MyServer.exe,-15500
Elevation
Enabled = 0x000001 (1)
LocalServer32
(Default) = C:\PROGRA~2\MyServer\MYSERVER.EXE
ProgID
(Default) = uMyServer.IMyServer
TypeLib
(Default) = {TypeLib GUID}
Version
(Default) = 1.0
HKLM\SOFTWARE\Wow6432Node\Classes\Interface
{GUID of IID_IMyServer}
(Default) = IMyServer
ProxyStubClsid32
(Default) = {Some GUID}
TypeLib
(Default) = {TypeLib GUID}
Version = 1.0
위의 서버를 등록한 후 내 레지스트리에 존재하는 유일한 항목입니다. 내가 사용하려고 모두 동일한 AppID가 GUID으로
function GetSecurityDescriptor(const lpszSDDL: LPWSTR; out pSD: PSecurityDescriptor): Boolean;
begin
Result := ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1,
pSD, nil);
end;
function GetLaunchActPermissionsWithIL(out pSD: PSecurityDescriptor): Boolean;
var
lpszSDDL: LPWSTR;
begin
// Allow World Local Launch/Activation permissions. Label the SD for LOW IL Execute UP
lpszSDDL := 'O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)';
Result := GetSecurityDescriptor(lpszSDDL, pSD);
end;
function GetAccessPermissionsForLUAServer(out pSD: PSecurityDescriptor): Boolean;
var
lpszSDDL: LPWSTR;
begin
// Local call permissions to IU, SY
lpszSDDL := 'O:BAG:BAD:(A;;0x3;;;IU)(A;;0x3;;;SY)';
Result := GetSecurityDescriptor(lpszSDDL, pSD);
end;
function SetAccessPermissions(hAppKey: HKEY; pSD: PSECURITY_DESCRIPTOR): Boolean;
var
dwLen: DWORD;
iRes: LONG;
begin
dwLen := GetSecurityDescriptorLength(pSD);
iRes := RegSetValueExA(hAppKey, 'AccessPermission', 0, REG_BINARY, pSD, dwLen);
Result := iRes = ERROR_SUCCESS;
end;
function SetLaunchActPermissions(hAppKey: HKEY; pSD: PSECURITY_DESCRIPTOR): Boolean;
var
dwLen: DWORD;
iRes: LONG;
begin
dwLen := GetSecurityDescriptorLength(pSD);
iRes := RegSetValueExA(hAppKey, 'LaunchPermission', 0, REG_BINARY, pSD, dwLen);
Result := iRes = ERROR_SUCCESS;
end;
procedure Initialize;
var
pSD: PSecurityDescriptor;
sSubKey: WideString;
hAppKey: HKEY;
begin
sSubKey := 'AppID\{GUID}';
RegOpenKeyW(HKEY_CLASSES_ROOT, PWideChar(sSubKey), hAppKey);
if GetAccessPermissionsForLUAServer(pSD) then
if not SetAccessPermissions(hAppKey, pSD) then
raise Exception.Create(Format('Access permissions aren''t set. System error: %d',
[GetLastError()]));
pSD := nil;
if GetLaunchActPermissionsWithIL(pSD) then
if not SetLaunchActPermissions(hAppKey, pSD) then
raise Exception.Create(Format('Launch permissions aren''t set. System error: %d',
[GetLastError()]));
end;
initialization
TAutoObjectFactory.Create(ComServer, TMyServer, Class_IMyServer,
ciMultiInstance, tmApartment);
Initialize;
:
추가적인 세부 사항
성공은 암시 적으로 다음 코드를 사용하여 조언으로 점심 권한을 설정 + CoInitializeSecurity()
를 호출하지 않고 시도 내 서버 인터페이스의 CLSID GUID와 새로 생성 된 GUID : 결과가 동일합니다. AccessPermission
및 LaunchPermission
값이 서버 등록 후 지정된 위치에 나타납니다.
또한 시도 :
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\MyServer.exe]
@="MyServer"
"AppID"="{My GUID}"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{My GUID}]
@="MyServer"
"ROTFlags"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{My GUID}]
@="MyServer Object"
"AppID"="{My GUID}"
:
- 64 비트 응용 프로그램으로 내가 수동으로 만든
추가 레지스트리 키/값을 서버에있는 건물 APPID 키
ROTFlags = 1
지정
정말로 'HKEY_CLASSES_ROOT'에 직접 쓰지 말아야합니다. 읽기에는 괜찮지 만 쓰기를 위해서는'HKEY_LOCAL_MACHINE \ Software \ Classes'를 사용해야합니다. MSDN은 그만큼 말한다. 그 외에도'CoInitializeSecurity()'를 어디에서 어떻게 호출합니까? –
레지스트리 키에 대해 확인하십시오. 그것을 수정했습니다. "Over-The-Shoulder (OTS) Elevation"섹션에 따르면'CoInitializeSecurity()'는 암묵적으로 호출됩니다 ('SetAccessPermissions' 코드로 예제를 보시기 바랍니다). – AlexeyDaryin
아직 명시 적으로 호출 해 보셨습니까? –