2010-11-10 10 views
10

Estoy desarrollando un objeto sustituto COM objeto en C, mis aplicaciones lo utilizarán para llamar al cuadro de diálogo de elevación de UAC para ciertas acciones que requieren derechos administrativos.Error al crear el objeto COM de elevación en Windows Seven

El plan es exportar una función que toma un puntero a una función con un número variable de argumentos y lo ejecuta en un contexto diferente. De esta forma, una aplicación puede usar este objeto para realizar algunas acciones con derechos de administrador, todo lo que necesita hacer es usar ese objeto y pasarle un puntero a la función que debe ejecutarse con dichos derechos.

Esto funciona parcialmente, llamando al CoCreateInstance va bien, el puntero a la función se pasa y se ejecuta mi función. Sin embargo, cuando creo una instancia de este objeto usando CoCreateInstanceAsAdmin, ocurren problemas; Aquí está el código:


HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv) 
{ 
// Manual implementation of CreateInstanceAsAdmin 
CComPtr BindCtx; 
HRESULT hr = CreateBindCtx(0,&BindCtx); 
BIND_OPTS3 bo; 
memset(&bo, 0, sizeof(bo)); 
bo.cbStruct = sizeof(bo); 
bo.grfMode = STGM_READWRITE; 
bo.hwnd = hwnd; 
bo.dwClassContext = CLSCTX_LOCAL_SERVER; 
hr = BindCtx->SetBindOptions(&bo); 
if (SUCCEEDED(hr)) 
{ 
    // Use the passed in CLSID to help create the COM elevation moniker string 
    CComPtr Moniker; 
    WCHAR wszCLSID[50]; 
    WCHAR wszMonikerName[300]; 
    StringFromGUID2(rclsid,wszCLSID,sizeof(wszCLSID)/sizeof(wszCLSID[0])); 
    //Elevation:Administrator!new 
    hr = StringCchPrintfW(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), L"Elevation:Administrator!new:%s", wszCLSID); 
    if (SUCCEEDED(hr)) 
    { 
    // Create the COM elevation moniker 
    ULONG ulEaten = 0; 
    ULONG ulLen = (ULONG)wcslen(wszMonikerName); 
    LPBC pBindCtx = BindCtx.p; 
    hr = MkParseDisplayName(pBindCtx,wszMonikerName,&ulEaten,&Moniker); 
    if (SUCCEEDED(hr) && ulEaten == ulLen) 
    { 
    // Use passed in reference to IID to bind to the object 
    IDispatch * pv = NULL; 
    hr = Moniker->BindToObject(pBindCtx,NULL,riid,ppv); 
    } 
    } 
} 
return hr; 
} 

Calling CoCreateInstanceAsAdmin falla con "Clase no registrada".

El objeto se ha registrado mediante la creación de las siguientes claves del registro (aquí está el cuerpo del archivo REG)


[HKEY_CLASSES_ROOT\COMsurrogate] 
@="COMsurrogate Class" 

[HKEY_CLASSES_ROOT\COMsurrogate\CurVer] 
@="COMsurrogate.1" 

[HKEY_CLASSES_ROOT\COMsurrogate\CLSID] 
@="{686B6F70-06AE-4dfd-8C26-4564684D9F9F}" 

[HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}] 
@="COMsurrogate Class" 
"LocalizedString"="@C:\\Windows\\system32\\COMsurrogate.dll,-101" 
"DllSurrogate"="" 

[HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\ProgID] 
@="COMsurrogate.1" 

[HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\VersionIndependentProgID] 
@="COMsurrogate" 

[HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\InprocServer32] 
@="@C:\\windows\system32\COMsurrogate.dll" 
"ThreadingModel"="Apartment" 

[HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\NotInsertable] 

[HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\Programmable] 

supongo que algunas entradas de registro faltan - esa es la conclusión a la que llegue al leer el mensaje de error. Sin embargo, esta lista de claves de registro se compiló después de explorar la documentación en MSDN y otros sitios, por lo que estoy bastante seguro de que no se pasó nada.

Entre las cosas que he tratado de resolver es implementarlo a través de ATL (de manera que el registro sea automático). Eso funciona, pero el problema es que no puedo pasar un puntero de función al prototipo de función generada MIDL.

traté de pasarlo utilizando el VARIANTE Tipo:


v.vt = VT_PTR; 
void (*myptr)(void); 
myptr = &DoTheStuff; 
v.byref = myptr; 
hr = theElevated->CoTaskExecuter(0, v); 

como resultado que reciben "tipo de argumento no válido".

¿Podría alguien arrojar algo de luz sobre el tema? Quizás lo que estoy tratando de lograr no es posible por diseño?

+0

Yuck. ¿Se supone que esto se ejecuta como un proceso separado? ¿Esto está en una versión de 64 bits de Windows? Un DllSurrogate en blanco es un problema en x64 Win7. Tampoco hay señales de un AppID o proxy/stub. Ref: http://msdn.microsoft.com/en-us/library/ms686606%28VS.85%29.aspx –

+2

¡Puaj! Esto es un agujero de seguridad de proporciones masivas. Si necesita algo para ejecutar código con privilegios elevados, entonces dele funciones fijas para ejecutar.¡Tenerlo ejecutar apuntadores de funciones arbitrarias significa que también puede haber elevado el programa original! –

+5

No se puede pasar un puntero significativo a un objeto COM fuera de proceso, el bit "fuera de proceso" debería indicarle cuál. Lo mejor que puede hacer en este tipo de escenario es tener un objeto prerregistrado que haga el trabajo y lo dirija a través del límite, pero también podría elevar ese objeto COM en primer lugar. En cuanto al error, compruebe que está registrando HKEY_LOCAL_MACHINE (vaya a Software \ Classes \ CLSID \ ...) en lugar de HKEY_CURRENT_USER. Si está en el usuario actual, entonces el usuario elevado no puede verlo debido a la forma en que implementa COM en vista +. – tyranid

Respuesta

0

Creo que los problemas que tiene son por diseño y que la intención de las mejoras de seguridad de la ventana era ayudar a evitar posibles riesgos de seguridad.

0

Microsoft realmente no desea que eleve sus privilegios si esto puede impedirlo. Ejecutar funciones arbitrarias como usuario privilegiado no debería ser fácil de ninguna manera si Windows es incluso un sistema decente. Podría intentar suplantar a un usuario diferente utilizando tokens y obtener un mejor acceso de esa manera, pero incluso así sería un tramo. Si recuerdo bien, las suplantaciones de los usuarios ni siquiera garantizarán que tendrá acceso completo. La mejor solución en este caso es simplemente usar la cuenta de súper usuario y solicitar correctamente los privilegios correctos.

Cuestiones relacionadas