Не удалось создать COM-объект повышения в Windows Seven - PullRequest
11 голосов
/ 10 ноября 2010

Я разрабатываю COM-суррогатный объект в C, он будет использоваться моими приложениями для вызова диалога повышения прав UAC для определенных действий, требующих административных прав.

План состоит в том, чтобызаставьте его экспортировать функцию, которая берет указатель на функцию с переменным числом аргументов и выполняет ее в другом контексте.Таким образом, приложение может использовать этот объект для выполнения некоторых действий с правами администратора, все, что ему нужно сделать, это использовать этот объект и передать ему указатель на функцию, которая должна быть выполнена с указанными правами.

Этоработает частично, вызов CoCreateInstance проходит нормально, указатель на функцию передается и моя функция выполняется.Однако, когда я создаю экземпляр этого объекта с использованием CoCreateInstanceAsAdmin , возникают проблемы;вот код:


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;
}

Вызов CoCreateInstanceAsAdmin завершается ошибкой с «Класс не зарегистрирован».

Объект регистрируется путем создания следующих ключей реестра (вот телофайла 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]

Я полагаю, что некоторые записи реестра отсутствуют - к такому выводу я пришел, читая сообщение об ошибке.Однако этот список разделов реестра был составлен после изучения документации на MSDN и других сайтах, поэтому я почти уверен, что ничего не пропущено.

Среди всего, что я пытался решить, - это реализовать его черезATL (такой, что регистрация автоматизирована).Это работает, но проблема в том, что я не могу передать указатель функции на прототип сгенерированной MIDL-функции.

Я пытался передать его, используя тип VARIANT :


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

в результате я получаю "Недопустимый тип аргумента".

Может ли кто-нибудь пролить свет на эту тему?Возможно, то, что я пытаюсь достичь, не возможно по замыслу?

Ответы [ 2 ]

0 голосов
/ 17 января 2014

Microsoft действительно не хочет, чтобы вы повышали свои привилегии, если это может помешать вам сделать это.Выполнение произвольных функций от имени привилегированного пользователя не должно быть легким, даже если Windows - даже прилично защищенная система.Вы могли бы попытаться выдать себя за другого пользователя, используя токены и получить лучший доступ таким образом, но даже тогда это будет растяжкой.Если я правильно помню, олицетворения пользователей даже не гарантируют, что вы получите полный доступ.Лучшее решение в этом случае - просто использовать учетную запись суперпользователя и правильно запрашивать правильные привилегии.

0 голосов
/ 15 ноября 2013

Я полагаю, что проблемы, с которыми вы столкнулись, связаны с разработкой и целью улучшения безопасности окна было помочь избежать потенциальных угроз безопасности.

...