Hook钩子程序(续)

上一篇写到 钩子程序 ,虽然本机调试成功了,但是,发给同学玩下,结果钩子无法加载。无奈没有网络,不停的看vs里面的帮助,Win API那部分居然是全英文的。。。看的好幸苦,也差不多知道是什么意思。但是,却还是不理解,为什么本机用Intptr.Zero是可以的。

想起有个函数GetLastError可以查看错误代号。然后,在程序中引入:

[DllImport("Kernel32.dll",SetLastError=true)]
        public static extern Int32 GetLastError();

之后,改写StartHook代码如下:

复制代码
public bool StartHook()
        {
            IntPtr InstallHook = IntPtr.Zero;
            if (this.mouseHandler == IntPtr.Zero)
            {
                this.m_MouseHookProcedure = new HOOKPROCEDURE(MouseHookProcedure);
                //安装钩子函数
                this.mouseHandler = (IntPtr)SetWindowsHookEx(WH_MOUSE_LL, this.m_MouseHookProcedure,InstaallHook, 0);
                if (this.mouseHandler == IntPtr.Zero)
                {
                    MessageBox.Show(GetLastError().ToString());
                    this.UnInstallHook();
                    return false;
                }
            }
            return true;
        }
复制代码

运行程序后获得exe文件,拖到虚拟机中,运行下= =得到错误代码

1428——没有模块句柄无法设置非本机的挂接。

之后修改下代码,又爆出87号错误orz。。。

在一片混乱下,也不知道该怎么办了。winAPI中,说到,钩子的时候,提到模块dll注入等等。而第三个参数便是与其相关的。查看了API的示例代码,发现其用的也是null啊。但是不知道为什么我用zero就是不行,跑去查看Intptr.Zero。结果看到这样一句话:

此字段的值并不等效于 null。

好吧,既然不等效与NULL,那么我该用什么来代替呢?没有找到对应的参数啊。

在Win API原型中,使用的是HINSTANCE这样的类型,虽然知道C#中常用Intptr来代替,但是,这里提到了模块句柄,且在winAPI中,HINSTANCE这个类型,在C#中,常用变量中并没有见到这个名字,虽然一直都用Intptr来代替,但是,我还是查了下这个类型。

结果中,第四位有一个函数:Marshal.GetHINSTANCE方法。想,既然要求是一个HINSTANCE,那就用这个试试呗。之后发现这个函数参数是Module类型,好吧,我跪了。。。。速成的C#还不知道什么是反射,也没用过。不过好在msdn是强大的~继续看Module,示例代码中,发觉可以直接用this.GetType().Module来得到Module。

然后,试了下,将代码改成了如下:

复制代码
public bool StartHook()
        {
            //IntPtr InstallHook = IntPtr.Zero;
            if (this.mouseHandler == IntPtr.Zero)
            {
                this.m_MouseHookProcedure = new HOOKPROCEDURE(MouseHookProcedure);
                //安装钩子函数
                this.mouseHandler = (IntPtr)SetWindowsHookEx(WH_MOUSE_LL, this.m_MouseHookProcedure,Marshal.GetHINSTANCE(this.GetType().Module), 0);
                if (this.mouseHandler == IntPtr.Zero)
                {
                    MessageBox.Show(GetLastError().ToString());
                    this.UnInstallHook();
                    return false;
                }
            }
            return true;
        }
复制代码

继续保留了GetLastError,这样还可以查看错误。运行正常,exe拖入虚拟机xp运行,这次也正常了~瞬间解放啊。。。。

小结:

SetWindowsHookEx的第三个参数,应该是指dll的句柄或者当前运行模块的句柄。或许是句柄一词是在C++中第一次听说,一直存有误会,觉得,就是一个窗口的标示符。原来还可以指示模块啊。。。。应该就是一个指针(地址定位符)的作用吧

发现GetLastError这样一个API,嗯~以后调用WinAPI,失败后可以查看错误代码(在写这个钩子的时候,出现好几次错误,却不知道错误的原因)。

貌似,是时候把入门经典啊,高级编程啊之类的给看一遍了。。。。每次看一点,就没看了。。。。速成的语言还是会有点小坑的~兴趣在编程上,过于广泛。。。。咳,下学期抽空看看吧,要不真的会悲剧的。。。

每天进步一点,期待逆袭~ http://www.cnblogs.com/zhangqy/archive/2013/01/28/2879461.html

原文地址:https://www.cnblogs.com/Leo_wl/p/2879944.html