2012-01-26 3 views
4

Вот немного справочной информации. Я работаю над заменой dll, которая была использована в методе инъекции dll через запись реестра AppInit_DLLs. Его цель заключалась в том, чтобы присутствовать в каждом процессе и устанавливать перехваты в GDI32.dll для сбора информации о печати. Это своего рода напуганный способ получить то, что мы хотим. Самому DLL больше 10 лет (написано на Visual Studio 97), и мы хотели бы заменить его чем-то менее инвазивным, чем инъекционная dll.Вопросы о SetWindowsHookEx() и подключении

Возможно, что мы ищем SetWindowsHookEx(). У меня были некоторые проблемы с этим, но у меня также были некоторые дискуссии с коллегами о том, стоит ли это дерево лаять. Вот некоторые вопросы, которые мы не могли определить:

  1. Когда мы привязываем подпрограмму из библиотеки DLL, например StartDoc() из Gdi32.dll, действительно ли мы получить уведомление каждый раз, любой другой процесс использует эту rotuine из этой DLL? Это своего рода функциональность, которую мы получали с нашей инъекцией .dll, и нам нужна такая же функциональность в будущем.

  2. При запуске крючка выполняется ли процедура обработки крюка в пространстве процесса процесса, инициирующего фактический вызов, или в пространстве процесса процесса, который настроил крюк? Мое мнение таково, что он должен запускаться в пространстве процессов процесса, который называется подпрограммой. Например, если программа вызывает StartDoc() из GDI32.dll, она будет иметь код процедуры обработки крючка, «впрыснутый» в его пространство и выполненный. В противном случае должна быть какая-то межпроцессная связь, которая автоматически настраивается между вызывающим процессом и процессом, который устанавливает крючок, и я просто не вижу этого в этом. Кроме того, необходимо, чтобы эта процедура обработки перехвата выполнялась в пространстве процесса вызывающего процесса, так как одна из вещей, которую ему нужно знать, - это имя этого процесса вызова, и я не уверен, как получить эту информацию, если в действительности этот процесс не выполнялся.

  3. Если процедура обработки крюка написана с использованием управляемой среды .NET, будет ли она нарушена при подключении к процессу, не использующему управляемую среду .NET? Мы действительно хотели бы отойти от C++ здесь и использовать C#, но что произойдет, если мы получим наш крючок из процесса, который не управляется? Как указывалось ранее, я думаю, что наша процедура обработки крюка будет выполняться в процессе, который первоначально назывался подпрограммой, которая была подключена. Но если это так, то я бы подумал, что у нас возникнут проблемы, если этот процесс не будет использовать среду времени выполнения .NET, но входящий код обработки подключений.

ответ

3
  1. Да.

  2. Как правило, это первый: он выполняется в контексте процесса, событие которого оно зацепляется.

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

    Исключения из этого общего правила является клавиатуры и мыши крючки низкого уровня (WH_LL_KEYBOARD и WH_LL_MOUSE).Так как эти типы крюков , а не, введенные в клиентские процессы, обратный вызов вызывается в том же потоке, который первоначально назывался SetWindowsHookEx.

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

    Для других типов крюков ваши проблемы, выраженные в вопросе, являются точными. Вам нужно будет написать эти DLL-файлы с крючками на C или C++. Разумеется, rest ваших частей приложения все равно может быть написан на управляемом языке. Единственное, что имеет значение, это DLL.

Вы могли бы рассмотреть вопрос о поиске в любом Microsoft Detours или EasyHook.

+0

Благодарим вас за ответ. Я считаю, что вы правы во всех отношениях. К сожалению, это касается вопросов 2 и 3. Проверьте этот самородок информации, которую я нашел. Мое маленькое сердце разбивается в самом конце этой страницы http://support.microsoft.com/kb/318804. Глобальные перехватчики не разрешены в C#, если только для клавиатур и событий мыши, как вы упомянули. Похоже, мне придется повторно внедрить DLL для инъекций. Его такая инвазивная техника, но похоже, что это единственный способ. Еще раз спасибо. – Ultratrunks

+0

@ultra: Да, это правильно. Вы не можете вводить управляемые DLL в другие процессы, потому что они не загружали CLR. Поскольку низкоуровневые клавиатуры и мышиные крючки не вводятся, они не имеют этого ограничения и поэтому могут быть записаны в управляемом коде. Да, это инвазивно, но это всего лишь факт жизни с крючками. Обычно я не рекомендую использовать крючок по этой причине и другие. Но если вам абсолютно необходимо получать уведомление, когда вызывается какая-либо системная функция, то инъекция DLL будет единственным способом сделать это. Напишите DLL на C++ и используйте его в приложении .NET. –

Смежные вопросы