Win32 подключает DLL-библиотеку к приложениям, построенным на «любом процессоре» - PullRequest
7 голосов
/ 27 января 2012

Я работаю над проектом, который фиксирует все взаимодействия с пользователем.MSDN сообщает ( this )

SetWindowsHookEx может использоваться для внедрения DLL в другой процесс.32-битная DLL не может быть внедрена в 64-битный процесс, а 64-битная DLL не может быть внедрена в 32-битный процесс.Если приложение требует использования хуков в других процессах, требуется, чтобы 32-разрядное приложение вызывало SetWindowsHookEx для внедрения 32-разрядной DLL в 32-разрядные процессы, а 64-разрядное приложение вызывало SetWindowsHookEx для внедрения 64-разрядногоDLL в 64-битных процессах.

Мой вопрос: что произойдет, если приложение было построено против Any CPU.Нужно ли мне вызывать SetWindowsHookEx из DLL, созданной для Any CPU.

Я написал HookLogger_32.exe, загружающий HookFunctions_32.dll (оба x86) и HookLogger_64.exe, загружающий параметр HookFunctions_64.dll (оба x64) WH_CBT и WH_MOUSE глобально (не определенный поток).

HookLogger_32.exe, HookLogger_64.exe, HookFunctions_32.dll и HookFunctions_64.dll написаны на C ++.

Когда я нажимаю на приложение .NET, созданное для Any CPU, эти библиотеки DLL получаютвводится (через SetWindowHookEx).ОС Windows зависает, и мне приходится принудительно перезагружать мой компьютер.

Когда одно и то же приложение .NET создается для x86 или x64 и когда я нажимаю на приложение после того, как HookLoggers (32- и 64-разрядные) работаютзапустил все работает нормально.

Любые причины такого неопределенного поведения.

Платформа, на которой я работаю, - это 64-битная машина.

Ответы [ 4 ]

3 голосов
/ 05 февраля 2012

Вам необходимо выполнить инъекцию из DLL с соответствующим битом - т. Е. «Любой ЦП» становится 32- или 64-битным во время выполнения ... и ваша DLL должна соответствовать битности времени выполнения!

Что-то полезное в вашемСитуация известна как «параллельная сборка» (две версии одной и той же сборки, одна 32-битная и другая 64-битная) ... Я думаю, вы найдете их полезными:

Здесь выможно найти хорошее пошаговое руководство, содержащее множество полезных информационных фрагментов - оно описывает .NET DLL-оболочку C ++ / CLI DLL со ссылкой на собственную DLL

ОБНОВЛЕНИЕ:

Чтобы сделать перехват действительно простым и надежным, посмотрите эту хорошо протестированную и бесплатную библиотеку - помимо прочего она работает с AnyCPU!

0 голосов
/ 08 февраля 2012

На 32-битном компьютере должно быть совершенно очевидно, что битовая нагрузка, которую берет любое приложение CPU.

64-разрядный компьютер получает две отдельные установки .NET Framework: по одной для каждой разрядности. Приложение .NET, скомпилированное как с любым ЦП, так как цель обычно выполняется в 64-разрядной установке, но может также запускаться в 32-разрядной установке, если на нее ссылается другое приложение, непосредственно нацеленное на x86. Таким образом, вы можете быть уверены, что получаете, только если знаете, как выполняется приложение: как самостоятельный процесс или по ссылке.

Я бы не стал делать никаких предположений. Не думайте, что процесс 64-битный на 64-битном компьютере: потенциально он может быть 32-битным. Проверьте его правильно, чтобы увидеть, в каком режиме он работает. Затем введите из 32-битного или 64-битного режима соответственно.

Причина, по которой вы должны использовать ту же битность, что и целевой процесс, заключается в том, что по техническим причинам, в которые я не буду входить, такие хуки не могут пересекать то, что называется барьером SysWOW. SysWOW - это то, что позволяет 32-разрядным приложениям запускаться на 64-разрядном компьютере, 16-разрядным приложениям - 32-разрядному компьютеру и т. Д. Вы пересекаете барьер, когда общаетесь между приложениями, запущенными на разных сторонах SysWOW. - то есть один работает в SysWOW (32-разрядная версия), а другой - нет (64-разрядная версия). Проще говоря, процесс должен быть полностью внутри или вне SysWOW. Таким образом, вы не можете добавить 32-битный код в 64-битный процесс, и наоборот.

0 голосов
/ 07 февраля 2012

Просто из вашего описания проблемы я думаю ... Скомпилированная программа Any CPU загружает заглушку x86, которая запускает 32-битный хук, затем заглушка x86 проверяет и видит, что среда поддерживает 64-битную версию, и запускает 64-битную версию CLR.

В этом сценарии ваша 32-битная ловушка DLL получает сообщение WH_SHELL и пытается внедрить в процесс (заглушку x86), который уже завершился, ИЛИ внедрить 32-битную ловушку в 64-битный процесс CLR. Таким образом, ваша «очень неоднозначная и требует уточнения» системная ошибка.

Если вы хотите подробно рассказать о том, что на самом деле делает ваш код, вам будет оказана большая помощь (и меньше обобщений и «просто используйте программу A»). Вы действительно внедряете код в процесс или вызываете SetWindowsHookEx с dwThreadId процесса.

0 голосов
/ 05 февраля 2012

Полагаю, ваша главная проблема в том, что вы пытаетесь внедрить сборку .NET в собственный процесс, и это, безусловно, не сработает. Я даже не уверен, что SetWindowsHookEx поддерживает внедрение сборки .NET в процесс CLR. Решение вашей проблемы:

  1. Переписать / перекомпилировать dll, используя собственный компилятор, такой как C ++ / Delphi / VB и т. Д., Для платформы x86 и x64.
  2. Убедитесь, что ваша dll зависит только от системных библиотек. Например, это не должно зависеть от какой-либо DLL, которая не поставляется с Windows, потому что вы можете аварийно завершить целевой процесс. Для определения зависимостей вы можете использовать инструмент «Обходчик зависимостей».
  3. Как упоминалось в MSDN, у вас должен быть исполняемый инжектор для каждого процессора, который вы хотите поддерживать. В данном случае x86 и x64.

Или вы можете использовать лучшую библиотеку для инъекций / перехвата, такую ​​как madCodeHook или Detours. Таким образом вы преодолеете проблему № 3, не говоря уже о десятках плюсов, которые они предоставляют.

...