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
。是否可以从另一个类使用这个"类型"?
不确定这会解决您的所有问题,但可以帮助您避免其中的一些问题。
如果这是 .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
。