Как перенаправить вызовы на ole32.dll в свою собственную прокси-библиотеку?

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

Для этого, используя Microsoft Visual Studio 2008 в Windows 7, я создаю прокси-библиотеку DLL, которая пересылает все, кроме одного вызова, в стандартную библиотеку ole32.dll, как описано в различных статьях, например. Перехвачено: Windows Hacking через перенаправление DLL. В результате DLL выглядит отлично, но я просто не могу создавать существующие программы (я использую стандартный контейнер тестирования ActiveX Control (tstcon32.exe) как тестовое приложение) забрать мою прокси-библиотеку. Независимо от того, что я делаю, программы всегда, кажется, подбирают C:\Windows\SysWow64\ole32.dll в соответствии с Process Explorer. Я пробовал несколько вещей до сих пор:

  • Подготовьте каталог, содержащий мою прокси-библиотеку DLL, к PATH, а затем вызовите программу; казалось, не имеет никакого эффекта.
  • Скопируйте мою прокси-DLL в тот же каталог, что и вызываемая программа; не повезло.
  • Создайте файл .local в том же каталоге, что и вызываемая программа, как описано в статье "Перенаправление динамической ссылки" и поставьте мой прокси DLL в тот же каталог - тоже не работало. Но потом я прочитал, что это перестало работать над более поздними версиями Windows. Кроме того, ole32.dll является "известной DLL" в соответствии с параметром реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs, поэтому перенаправление на основе .local, вероятно, не будет работать.
  • Использовать перенаправление на основе манифеста, как описано, например. в DLL-перенаправлении с использованием манифеста, но это тоже не показало никакого эффекта. Однако этот подход кажется нетривиальным, поэтому я сделал что-то неправильно.

Есть ли у кого-нибудь опыт перенаправления вызовов на стандартные DLL, такие как ole32.dll с помощью DLL-заглушки? Как вы заставили приложения забрать свою заглушку DLL?

Ответ 1

Я понимаю, что это немного поздно примерно через 6 месяцев, но я пытался сделать то же самое и иметь некоторые дополнительные примечания:

  • Вы можете взять и удалить ole32.dll из HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs. Это позволяет обойти тот факт, что Windows заблокировала эти ключи.
  • Создание ключа SafeDllSearch со значением 0 в HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager должно изменить путь поиска.

Применяя оба эти метода и перезагружая, подключение все еще не работает. Я пошел дальше, загрузил виртуальную машину с одним из наших спасательных компакт-дисков (среда на основе Windows PE) и перезаписал одну из них в system32. Windows не загружается в результате - никаких ошибок символов, но я никогда не дошел до LogonUI.exe. Возможно, мои заблокированные функции сломаны, поэтому это может быть причиной.

Во всяком случае, это создало реальный ощутимый эффект крюка - пусть и тот, который кричит "сломан"!. К сожалению, это очень сложно отладить, и я могу прибегнуть к другому методу hooking - а именно IAT patching.

Изменить другой эксперимент, который я выполнил, заключается в явной загрузке самой Dll в адресное пространство целевого процесса. Этот фрагмент кода выглядит следующим образом:

wchar_t* TargetPath = argv[1];
wchar_t DllPath[] = L"N:\\experiments\\ole32.dll";
STARTUPINFOW si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(STARTUPINFOW));
memset(&pi, 0, sizeof(PROCESS_INFORMATION));

// create process suspended
BOOL bResult = CreateProcess(NULL, TargetPath, NULL, NULL, FALSE, 
    CREATE_SUSPENDED, NULL, NULL, &si, &pi);

// write DLL name to remote process
void* RemoteAddr = VirtualAllocEx(pi.hProcess, NULL, sizeof(DllPath)+1, 
    MEM_RESERVE | MEM_COMMIT, PAGE_READONLY);
WriteProcessMemory(pi.hProcess, RemoteAddr, DllPath, sizeof(DllPath), &BytesWritten);

// get handle to LoadLibraryW
PTHREAD_START_ROUTINE pfLoadLibrary = (PTHREAD_START_ROUTINE) 
    GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");

// create remote thread calling LoadLibraryW
HANDLE hThread = CreateRemoteThread(pi.hProcess, NULL, 
    0, pfLoadLibrary, RemoteAddr, 0, NULL);

// start remote process
ResumeThread(pi.hThread);

Обработка ошибок удалена для краткости.

В основном цель заключалась в том, чтобы принудительно загрузить my ole32.dll в целевое адресное пространство, прежде чем у него появилась возможность загрузить ole32.dll из system32. В моем случае ole32.dll загружался позже в подпрограмме загрузки приложения, поэтому теоретически это должно было работать. На практике это не так. Я не уверен, почему.

Обновить. Мой исходный код завершился неудачно, потому что у DLL были неразрешенные предупреждения о символах во время выполнения. Этот метод работает. По-видимому, он загружает как my ole32.dll, так и один из system32. Чтобы обеспечить успешную загрузку библиотеки, я добавил вызов LoadLibrary(DllPath) к приведенному выше коду.

Ответ 2

Возможно, winapioverride может вам помочь. Он может регистрировать все вызовы win api без программирования. Поэтому он вводит dll в процесс, который выполняет регистрацию. Если я правильно его помню, можно также добавить собственные пользовательские dll - даже до того, как процесс фактически выполнит какой-либо код. В документации есть информация о шпионских объектах com.