Глобальная проблема Hook Keylogger

Он записывает ключи в текстовое поле в настоящее время, поэтому его безопасно.

ПРОБЛЕМА Проблема в том, когда я запускаю это на виртуальной машине или ноутбуке моих друзей, он зависает после нажатия определенного количества клавиш (случайных). У меня он отлично работает.

http://i34.tinypic.com/29o1im8.jpg

class GlobalKeyboardHook
{


    #region Definition of Structures, Constants and Delegates

    public delegate int KeyboardHookProc(int nCode, int wParam, ref GlobalKeyboardHookStruct lParam);

    public struct GlobalKeyboardHookStruct
    {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
        public int dwExtraInfo;
    }

    const int WM_KEYDOWN = 0x100;
    const int WM_KEYUP = 0x101;
    const int WM_SYSKEYDOWN = 0x104;
    const int WM_SYSKEYUP = 0x105;
    const int WH_KEYBOARD_LL = 13;

    #endregion

    #region Events

    public event KeyEventHandler KeyDown;
    public event KeyEventHandler KeyUp;

    #endregion

    #region Instance Variables

    public List HookedKeys = new List();
    IntPtr hookHandle = IntPtr.Zero;

    #endregion

    #region DLL Imports

    [DllImport("kernel32.dll")]
    static extern IntPtr LoadLibrary(string lpFileName);

    [DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall, SetLastError = true)]
    static extern IntPtr SetWindowsHookEx(int hookID, KeyboardHookProc callback, IntPtr hInstance, uint threadID);

    [DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall, SetLastError = true)]
    static extern bool UnhookWindowsHookEx(IntPtr hookHandle);

    [DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall)]
    static extern int CallNextHookEx(IntPtr hookHandle, int nCode, int wParam, ref GlobalKeyboardHookStruct lParam);




    #endregion

    #region Public Methods

    public int hookProc(int nCode, int wParam, ref GlobalKeyboardHookStruct lParam)
    {

        if (nCode >= 0)
        {
            Keys key = (Keys)lParam.vkCode;

            if (HookedKeys.Contains(key) == true)
            {
                KeyEventArgs kea = new KeyEventArgs(key);

                    if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && KeyUp != null)
                    {
                        KeyUp(this, kea);
                    }
                    else if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && KeyDown != null)
                    {
                        KeyDown(this, kea);
                    }
                    if (kea.Handled) return 1;


            }
        }

     return CallNextHookEx(hookHandle, nCode, wParam, ref lParam);
    }


    public void hook()
    {
            IntPtr hInstance = LoadLibrary("user32");
            hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);
    }


    public void unhook()
    {
        UnhookWindowsHookEx(hookHandle);
    }

    #endregion

    #region Constructors and Destructors

    public GlobalKeyboardHook()
    {
        hook();
    }

    ~GlobalKeyboardHook()
    {
        unhook();
    }

    #endregion

7
задан RSTYLE 22 August 2010 в 10:28
поделиться

1 ответ

Попробуйте отладить приложение с включенным MDA «CallbackOnCollectedDelegate» (Отладка -> Исключения -> Управляемые помощники отладки -> установите флажок «CallbackOnCollectedDelegate»).

Общая ошибка здесь состоит в том, что делегат для вашей подключаемой процедуры автоматически собирается GC после того, как вы устанавливаете ловушку (он создается как часть маршалинга P / Invoke для SetWindowsHookEx ). После того, как GC собирает делегата, программа вылетает при попытке вызвать обратный вызов. Это также объяснило бы случайность.

Если это ваша проблема, вы увидите следующее сообщение об ошибке:

Обратный вызов был выполнен для мусора. собранный делегат типа '...'. Это может вызвать сбои приложения, повреждение и потеря данных. При прохождении делегаты неуправляемому коду, они должны сохранить жизнь управляемым приложение, пока оно не будет гарантировано что их никогда не назовут.

Попробуйте сохранить ссылку на вашу подключаемую процедуру как на член вашего класса, например:

public delegate int KeyboardHookProc(int nCode, int wParam, ref GlobalKeyboardHookStruct lParam);

public int hookProc(int nCode, int wParam, ref GlobalKeyboardHookStruct lParam)
{
    // ...
}

public void hook()
{
    _hookProc = new KeyboardHookProc(hookProc);
    IntPtr hInstance = LoadLibrary("user32");
    hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, _hookProc, hInstance, 0);
}

KeyboardHookProc _hookProc;
10
ответ дан 7 December 2019 в 01:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: