C#,需要帮助来分离一个初学者程序

本文关键字:一个 程序 初学者 分离 帮助 | 更新日期: 2023-09-27 18:35:01

作为初学者课程,我想将本教程 http://null-byte.wonderhowto.com/how-to/create-simple-hidden-console-keylogger-c-sharp-0132757/移植到 Windows 窗体应用程序。这应该向用户显示在名为"lblMessage"的标签中按下了哪些键。

我现在已将代码分成两部分。

表格1.cs

using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        public GlobalKeyHook hook = new GlobalKeyHook();
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            // Origin
            // _hookID = SetHook(_proc);
            hook._hookID = hook.SetHook(_proc);
        }
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            // Origin
            // UnhookWindowsHookEx(_hookID);
            hook.UnhookWindowsEx(_hookID);
        }
    }
}

全球钥匙钩.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
namespace WindowsFormsApplication3
{
    class GlobalKeyHook : Form
    {
        #region DLLs
        [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)]
        public 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);
        #endregion

        #region Fields and delegation
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x0100;
        private static LowLevelKeyboardProc _proc = HookCallback;
        public static IntPtr _hookID = IntPtr.Zero;
        public delegate IntPtr LowLevelKeyboardProc(
        int nCode, IntPtr wParam, IntPtr lParam);
        #endregion
        public GlobalKeyHook()
        {
            IntPtr hookID = _hookID;
            LowLevelKeyboardProc proc = _proc;
        }
        static Form form = new Form();
        #region Methods
        private static IntPtr HookCallback(
            int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);
                Console.WriteLine((Keys)vkCode);
                form.Text = vkCode.ToString();
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }
        public static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                GetModuleHandle(curModule.ModuleName), 0);
            }
        }
        #endregion
    }
}

但是我无法使用 Form1 类中的public static IntPtr _hookID、方法SetHook()或 DLL UnhookWindowsHookEx。是否可以从另一个类使用这个"类型"?

C#,需要帮助来分离一个初学者程序

不确定这会解决您的所有问题,但可以帮助您避免其中的一些问题。

如果这是 .net 4.0 或更高版本,则SetWindowsHookEX()调用可能会返回 0(失败(,因为 .net 不再模拟托管 dll 的本机模块。要解决此问题,您可以为LoadLibrary()添加如下 DllImport:

[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)]
    public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);

然后在你打电话之前SetWindowsHookEX()做这个:

IntPtr hinstDLL = UnsafeMethods.LoadLibrary("user32.dll"); 

并像这样称呼SetWindowsHookEX()

SetWindowsHookEx(WH_KEYBOARD_LL, proc,
            hinstDLL, 0);

基本上SetWindowsHookEX()需要一个有效的模块句柄,它验证它,但从未实际使用它。 加载user32的原因是,由于您是从中 p/调用函数,因此您拥有它。

另外,在您的构造函数中,只需将其设置为 IntPtr.Zero。如果您总是将其设置为 IntPtr.Zero,则无需_hookID。还值得注意的是,如果您运行此内容的计算机的 win7sp1 低于使用 IntPtr.Zero 的 win7sp1 将无法工作(至少 99% 确定(。

我强烈建议您查看这组钩子 他们有一个不错的钩子库实现,您可以根据需要轻松扩展。

你需要将 GlobalKeyHook 类设置为 public class GlobalKeyHook