Я пытаюсь подключить CBT-хук в ОС Windows.В настоящее время я использую Windows 7 x64.
Я прочитал много тем, рассказывающих об этой проблеме, но ни одна из них не решила мою проблему.Приложение работает хорошо;Хук установлен, и я вижу, что приходят уведомления.
На самом деле возникла проблема в том, что приложение не уведомлено о перехвате CBT других процессов, выполняющихся на той же машине.
Приложение написано на C # (с использованием Microsoft .NET).Вот пример работы:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsHook
{
class Program
{
[STAThread]
static void Main(string[] args)
{
uint thid = (uint)AppDomain.GetCurrentThreadId();
bool global = true;
mHookDelegate = Marshal.GetFunctionPointerForDelegate(new HookProc(ManagedCallback));
if (global == true) {
mNativeWrapperInstance = LoadLibrary("Native_x64.dll");
thid = 0;
} else {
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
mNativeWrapperInstance = GetModuleHandle(curModule.ModuleName);
}
}
mNativeWrappedDelegate = AllocHookWrapper(mHookDelegate);
mHookHandle = SetWindowsHookEx(/*WH_CBT*/5, mNativeWrappedDelegate, mNativeWrapperInstance, thid);
if (mHookHandle == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
Application.Run(new Form());
if (FreeHookWrapper(mNativeWrappedDelegate) == false)
throw new Win32Exception("FreeHookWrapper has failed");
if (FreeLibrary(mNativeWrapperInstance) == false)
throw new Win32Exception("FreeLibrary has failed");
if (UnhookWindowsHookEx(mHookHandle) == false)
throw new Win32Exception(Marshal.GetLastWin32Error());
}
static int ManagedCallback(int code, IntPtr wParam, IntPtr lParam)
{
Trace.TraceInformation("Code: {0}", code);
if (code >= 0) {
return (0);
} else {
return (CallNextHookEx(mHookHandle, code, wParam, lParam));
}
}
delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
static IntPtr mHookHandle;
static IntPtr mHookDelegate;
static IntPtr mNativeWrapperInstance = IntPtr.Zero;
static IntPtr mNativeWrappedDelegate = IntPtr.Zero;
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int hook, IntPtr callback, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll")]
internal static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FreeLibrary(IntPtr hModule);
[DllImport("Native_x64.dll")]
private static extern IntPtr AllocHookWrapper(IntPtr callback);
[DllImport("Native_x64.dll")]
private static extern bool FreeHookWrapper(IntPtr wrapper);
[DllImport("Native_x64.dll")]
private static extern int FreeHooksCount();
}
}
AllocHookWrapper и FreeHookWrapper - импортированные подпрограммы из компилятора DLL (Native_x64.dll) для платформы x64, расположенного в одном каталоге приложения.AllocHookWrapper сохраняет указатель функции (управляемой подпрограммы) и возвращает подпрограмму DLL, вызывающую указатель функции).
Вот код библиотеки DLL:
#include "stdafx.h"
#include "iGecko.Native.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define WRAPPER_NAME(idx) Wrapper ## idx
#define WRAPPER_IMPLEMENTATION(idx) \
LRESULT WINAPI WRAPPER_NAME(idx)(int code, WPARAM wparam, LPARAM lparam) \
{ \
if (sHooksWrapped[idx] != NULL) \
return (sHooksWrapped[idx])(code, wparam, lparam); \
else \
return (0); \
}
#define WRAPPER_COUNT 16
HOOKPROC sHooksWrapped[WRAPPER_COUNT] = { NULL };
WRAPPER_IMPLEMENTATION(0x00);
WRAPPER_IMPLEMENTATION(0x01);
WRAPPER_IMPLEMENTATION(0x02);
WRAPPER_IMPLEMENTATION(0x03);
WRAPPER_IMPLEMENTATION(0x04);
WRAPPER_IMPLEMENTATION(0x05);
WRAPPER_IMPLEMENTATION(0x06);
WRAPPER_IMPLEMENTATION(0x07);
WRAPPER_IMPLEMENTATION(0x08);
WRAPPER_IMPLEMENTATION(0x09);
WRAPPER_IMPLEMENTATION(0x0A);
WRAPPER_IMPLEMENTATION(0x0B);
WRAPPER_IMPLEMENTATION(0x0C);
WRAPPER_IMPLEMENTATION(0x0D);
WRAPPER_IMPLEMENTATION(0x0E);
WRAPPER_IMPLEMENTATION(0x0F);
const HOOKPROC sHookWrappers[] = {
WRAPPER_NAME(0x00),
WRAPPER_NAME(0x01),
WRAPPER_NAME(0x02),
WRAPPER_NAME(0x03),
WRAPPER_NAME(0x04),
WRAPPER_NAME(0x05),
WRAPPER_NAME(0x06),
WRAPPER_NAME(0x07),
WRAPPER_NAME(0x08),
WRAPPER_NAME(0x09),
WRAPPER_NAME(0x0A),
WRAPPER_NAME(0x0B),
WRAPPER_NAME(0x0C),
WRAPPER_NAME(0x0D),
WRAPPER_NAME(0x0E),
WRAPPER_NAME(0x0F)
};
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
return (TRUE);
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
extern "C" IGECKONATIVE_API HOOKPROC WINAPI AllocHookWrapper(HOOKPROC wrapped)
{
for(int i = 0; i < WRAPPER_COUNT; i++) {
if (sHooksWrapped[i] == NULL) {
sHooksWrapped[i] = wrapped;
return sHookWrappers[i];
}
}
return (NULL);
}
extern "C" IGECKONATIVE_API BOOL WINAPI FreeHookWrapper(HOOKPROC wrapper)
{
for(int i = 0; i < WRAPPER_COUNT; i++) {
if (sHookWrappers[i] == wrapper) {
sHooksWrapped[i] = NULL;
return TRUE;
}
}
return (FALSE);
}
extern "C" IGECKONATIVE_API INT WINAPI FreeHooksCount()
{
int c = 0;
for(int i = 0; i < WRAPPER_COUNT; i++) {
if (sHooksWrapped[i] == NULL)
c++;
}
return (c);
}
На самом деле яменя интересуют события, связанные с окном (создание, уничтожение) в определенной системе, но на самом деле я не могу получать уведомления от ОС ...
Что происходит?Что я пропустил?
Обратите внимание, что я работаю с группой Administratos.
Я нашел этот интересный раздел на этой странице
Глобальные хуки не поддерживаются в .NET Framework Нельзя реализовать глобальные хуки в Microsoft .NET Framework.Чтобы установить глобальный хук, хук должен иметь собственный экспорт DLL, чтобы вставить себя в другой процесс, для которого требуется допустимая, согласованная функция для вызова.Это поведение требует экспорта DLL..NET Framework не поддерживает экспорт DLL.Управляемый код не имеет понятия согласованного значения для указателя на функцию, потому что эти указатели на функции являются прокси, которые создаются динамически.
Я решил сделать трюк, реализовав собственную DLL, содержащую обратный вызов ловушки, которыйвызывает управляемый обратный вызов.Однако управляемый обратный вызов вызывается только в процессе, который вызывает процедуру SetWindowsHookEx, и не вызывается другими процессами.
Каковы возможные обходные пути?
Возможно выделение динамической памяти для храненияидентификатор процесса (управляемый) и отправка пользовательских сообщений, описывающих подключенные функции?
Чего я добиваюсь, так это системного монитора, который обнаруживает новые выполненные процессы, обнаруживает созданныерасположение и размер окон, а также закрытые окна, сдвинутые окна, свернутые / развернутые окна.Последовательно монитор должен обнаруживать события мыши и клавиатуры (всегда общесистемные), а также он должен «эмулировать» события мыши и клавиатуры.
Каждый процесс на одном и том же рабочем столе должен независимо отслеживаться архивом (32 или 64 бита) и базовым фреймворком (собственным или управляемым).
Монитор должен принудительно обрабатывать положение, размер и перемещения окон процесса и быть в состоянии действовать как локальный пользователь, чтобы позволить удаленному пользователювыступать в роли локального пользователя (что-то вроде VNC).