[Hook]Winform:关于钩子的基础知识

mikel阅读(880)

基本概念
钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。
钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。

 

http://blog.csdn.net/hejinjiang/archive/2008/03/19/2197066.aspx有对勾子作了非常详细的介绍

 

尽管在 .NET 框架中不支持全局挂钩

MSDN

您无法在 Microsoft .NET 框架中实现全局挂钩。若要安装全局挂钩,挂钩必须有一个本机动态链接库 (DLL) 导出以便将其本身插入到另一个需要调入一个有效而且一致的函数的进程中。这需要一个 DLL 导出,而 .NET 框架不支持这一点。托管代码没有让函数指针具有统一的值这一概念,因为这些函数是动态构建的代理。

 

但我们通过API函数的调用,还是可以照样实现十年前很热门的技术

 

勾子到底能干嘛呢?

提示: 如果要设置系统级钩子, 钩子函数必须在 DLL .


SetWindowsHookEx(

 idHook: Integer;   {钩子类型}

 lpfn: TFNHookProc; {函数指针}

 hmod: HINST;       {包含钩子函数的模块(EXEDLL)句柄; 一般是 HInstance; 如果是当前线程这里可以是 0}

 dwThreadId: DWORD {关联的线程; 可用 GetCurrentThreadId 获取当前线程; 0 表示是系统级钩子}

): HHOOK;            {返回钩子的句柄; 0 表示失败}

 

//钩子类型 idHook 选项:

WH_MSGFILTER       = -1; {线程级; 截获用户与控件交互的消息}

WH_JOURNALRECORD   = 0; {系统级; 记录所有消息队列从消息队列送出的输入消息, 在消息从队列中清除时发生; 可用于宏记录}

WH_JOURNALPLAYBACK = 1; {系统级; 回放由 WH_JOURNALRECORD 记录的消息, 也就是将这些消息重新送入消息队列}

WH_KEYBOARD        = 2; {系统级或线程级; 截获键盘消息}

WH_GETMESSAGE      = 3; {系统级或线程级; 截获从消息队列送出的消息}

WH_CALLWNDPROC     = 4; {系统级或线程级; 截获发送到目标窗口的消息, SendMessage 调用时发生}

WH_CBT             = 5; {系统级或线程级; 截获系统基本消息, 譬如: 窗口的创建、激活、关闭、最大最小化、移动等等}

WH_SYSMSGFILTER    = 6; {系统级; 截获系统范围内用户与控件交互的消息}

WH_MOUSE           = 7; {系统级或线程级; 截获鼠标消息}

WH_HARDWARE        = 8; {系统级或线程级; 截获非标准硬件(非鼠标、键盘)的消息}

WH_Debug           = 9; {系统级或线程级; 在其他钩子调用前调用, 用于调试钩子}

WH_SHELL           = 10; {系统级或线程级; 截获发向外壳应用程序的消息}

WH_FOREGROUNDIDLE = 11; {系统级或线程级; 在程序前台线程空闲时调用}

WH_CALLWNDPROCRET = 12; {系统级或线程级; 截获目标窗口处理完毕的消息, SendMessage 调用后发生}

 

从这个结构体与其枚举参数,这是仁者见仁的事情,我们同事一直都在做用钩子控制别人软件,如QQ的事情,嘿嘿,其实也即相当于木马了,比如某某监听健盘而获取你密码的软件。而我们经常用的ctrl+alt+z调出QQ,也可以通过做一个全局的钩子来应用(热健的下面再介绍)

 

这里介绍了一篇勾住MOUSE的方法

http://support.microsoft.com/kb/318804/

而这里也介绍了一篇控制KEYBOARD的方法

http://www.cnblogs.com/zagelover/articles/1137331.html

 

而其最主要的就是下面这么几个API函数,而委托作为函数指针也在这里有个比较完美的体现吧,其实就充当回调函数的指针。

 

 

 //Declare wrapper managed MouseHookStruct class.

        [StructLayout(LayoutKind.Sequential)]

        public class MouseHookStruct

        {

            public POINT pt;

            public int hwnd;

            public int wHitTestCode;

            public int dwExtraInfo;

        }

//声明键盘钩子的封送结构类型
        [StructLayout(LayoutKind.Sequential)]
        public class KeyboardHookStruct
        {
            public int vkCode; //表示一个在1254间的虚似键盘码
            public int scanCode; //表示硬件扫描码
            public int flags;
            public int time;
            public int dwExtraInfo;
        }
        //装置钩子的函数
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

        //卸下钩子的函数
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);

        //下一个钩挂的函数
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

        [DllImport("user32")]
        public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);

注:

ToAscii Function


The ToAscii function translates the specified virtual-key code and keyboard state to the corresponding character or characters. The function translates the code using the input language and physical keyboard layout identified by the keyboard layout handle.

To specify a handle to the keyboard layout to use to translate the specified code, use the ToAsciiEx function.

Return Value

If the specified key is a dead key, the return value is negative. Otherwise, it is one of the following values.

Value

Meaning

0

The specified virtual key has no translation for the current state of the keyboard.

1

One character was copied to the buffer.

2

Two characters were copied to the buffer. This usually happens when a dead-key character (accent or diacritic) stored in the keyboard layout cannot be composed with the specified virtual key to form a single character.

通过这个函数,有时也可以实现某些热健功能,特别是返回值为1    

到这里也顺便复习下KEYPRESS

在控件有焦点的情况下按下键时发生

键事件按下列顺序发生:

KeyDown

KeyPress

KeyUp

非字符键不会引发 KeyPress 事件;但非字符键却可以引发 KeyDown KeyUp 事件。

使用 KeyChar 属性在运行时对键击进行取样,并且使用或修改公共键击的子集。

若要仅在窗体级别处理键盘事件而不允许其他控件接收键盘事件,请将窗体的 KeyPress 事件处理方法中的 KeyPressEventArgs.Handled 属性设置为 true

   说明  
   
  具有焦点的对象接收该事件。一个窗体仅在它没有可视和有效的控件或   KeyPreview   属性被设置为   True   时才能接收该事件。一个   KeyPress   事件可以引用任何可打印的键盘字符,一个来自标准字母表的字符或少数几个特殊字符之一的字符与   CTRL   键的组合,以及   ENTER   或   BACKSPACE   键。KeyPress   事件过程在截取   TextBox   或   ComboBox   控件所输入的击键时是非常有用的。它可立即测试击键的有效性或在字符输入时对其进行格式处理。改变   keyascii   参数的值会改变所显示的字符。  
   
  可使用下列表达式将   keyascii   参数转变为一个字符:  
   
  Chr(KeyAscii)  
   
  然后执行字符串操作,并将该字符反译成一个控件可通过该表达式解释的   ANSI   数字:  
   
  KeyAscii   =   Asc(char)  
   
  应当使用   KeyDown   和   KeyUP   事件过程来处理任何不被   KeyPress   识别的击键,诸如:功能键、编辑键、定位键以及任何这些键和键盘换档键的组合等。与   KeyDown   和   KeyUp   事件不同的是,KeyPress   不显示键盘的物理状态,而只是传递一个字符。  
   
  KeyPress   将每个字符的大、小写形式作为不同的键代码解释,即作为两种不同的字符。而   KeyDown   和   KeyUp   用两种参数解释每个字符的大写形式和小写形式:keycode   —   显示物理的键(将   A   和   a   作为同一个键返回)和   shift   —指示   shift   +   key   键的状态而且返回   A   或   a   其中之一。  
   
  如果   KeyPreview   属性被设置为   True,窗体将先于该窗体上的控件接收此事件。可用   KeyPreview   属性来创建全局键盘处理例程。  
   

  注意…CTRL+@   的键盘组合的   ANSI   编号是   0。因为   Visual   Basic   将一个零值的   keyascii   识别为一个长度为零的字符串   (""),在应用程序中应避免使用   CTRL+@   的组合。

 

 

在这里下面的委托将充当函数指针用

public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);

[Hook]C#强化系列文章二:在C#中使用钩子

mikel阅读(877)

相信以前用过VB、Delphi,特别是VC的程序员应该对钩子程序都不陌生。在C#中我们同样可以使用钩子程序来实现特殊效果,比如当用户按下某个特殊键时提示,比如关闭应用程序前提示等。
当然使用方法相对VC来说要稍微复杂一点,有的地方还不太方便,下面的例子中实现两个基本功能:
1、按下Alt+F4时使窗口最小化
2、关闭应用程序前提示
不过目前只能捕获消息,不能屏蔽消息,我正在实验,也希望知道的高手能多多指教
一、加入winuser.h中的定义
因为钩子程序一般情况下都是在vc下使用的,在C#里面并没有对应的方法、结构等的定义,我们首先需要把winuser.h中的相关定义加入自己的类

钩子类型的枚举

具体的说明在msdn中都可以查到,主要的比如WH_KEYBOARD是监控按键事件,WH_CALLWNDPROC是在消息触发时执行

虚键值的定义

这个不用说明了,对应ALT、CTRL等键

消息结构体

这个是windows内部传递过来的消息的结构
二、加入自己定义的委托和事件参数

钩子委托

HokkProc是SetWindowsHookEx调用时的委托事件,HookEventHandler是自己的委托事件

钩子事件参数

是自己的委托事件中接受的事件参数
三、实现自己的钩子类
这一步是最重要的,要使用钩子,我们需要引用user32.dll中的相应方法:

        [DllImport("user32.dll")]
        
static extern IntPtr SetWindowsHookEx(HookType hook, HookProc callback, IntPtr hMod, uint dwThreadId);

        [DllImport(
"user32.dll")]
        
static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport(
"user32.dll")]
        
static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport(
"user32.dll")]
        
static extern short GetKeyState(VirtualKeys nVirtKey);

SetWindowsHookEx是注册一个钩子程序,UnhookWindowsHookEx是释放钩子程序,CallNextHookEx调用钩子的后续事件处理,GetKeyState得到所按的虚键
然后就可以调用这些方法来实现钩子程序,比如注册一个钩子可以调用:

            m_hook = SetWindowsHookEx(m_hooktype, m_hookproc, IntPtr.Zero, (uint)AppDomain.GetCurrentThreadId());

其中m_hooktype就是HookType中定义的类型,m_hookproc就是实际的钩子处理程序:

m_hookproc = new HookProc(KeyHookProcedure);

最关键的就是KeyHookProcedure等钩子处理程序:

        protected int KeyHookProcedure(int code, IntPtr wParam, IntPtr lParam)
        
{
            
if (code != 0)
            
{
                
return CallNextHookEx(m_hook, code, wParam, lParam);
            }


            
if (HookInvoked != null)
            
{
                Keys key 
= (Keys)wParam.ToInt32();
                HookEventArgs eventArgs 
= new HookEventArgs();
                eventArgs.key 
= key;
                eventArgs.lParam 
= lParam;
                eventArgs.wParam 
= wParam;
                eventArgs.HookCode 
= code;
                eventArgs.bAltKey 
= GetKeyState(VirtualKeys.VK_MENU) <= 127;
                eventArgs.bCtrlKey 
= GetKeyState(VirtualKeys.VK_CONTROL) <= 127;
                HookInvoked(this, eventArgs);
            }


            
return CallNextHookEx(m_hook, code, wParam, lParam);
        }

在这个事件中可以取得消息的参数,特别是按键的值,然后通过HookInvoked委托调用事件实际的处理程序
四、在应用程序中调用钩子类
我们可以在自己的form中声明两个钩子对象

        private MyHook callProcHook = new MyHook(HookType.WH_CALLWNDPROC);
        
private MyHook keyHook = new MyHook(HookType.WH_KEYBOARD);

然后在初始化时注册钩子:

        private void Form1_Load(object sender, EventArgs e)
        
{
            keyHook.HookInvoked 
+= new HookEventHandler(keyHook_HookInvoked);
            keyHook.Install();

            callProcHook.HookInvoked 
+= new HookEventHandler(callProcHook_HookInvoked);
            callProcHook.Install();
        }

然后就是实际的钩子事件:

        private void keyHook_HookInvoked(object sender, HookEventArgs e)
        
{
            
if (e.key == Keys.F4 && e.bAltKey) //Alt + F4
            {
                
this.WindowState = FormWindowState.Minimized;
            }

        }


        
private void callProcHook_HookInvoked(object sender, HookEventArgs e)
        
{
            
unsafe
            
{
                CWPSTRUCT
* message = (CWPSTRUCT*)e.lParam;
                
if (message != null)
                
{
                    
if (message->message == WM_CLOSE)
                    
{
                        (sender 
as MyHook).CallNextProc = false;
                        MessageBox.Show(
"程序即将关闭!");
                    }

                }

            }

        }

这样我们就可以通过钩子实现一些相对底层的应用。
代码说的有点乱,我就把最主要的代码直接列在下面供大家参考:

例子代码

以上的钩子只对当前应用程序起作用,如果想控制其他的所有程序,需要使用全局钩子。原则上全局钩子在C#中是不支持的,在http://www.codeproject.com/csharp/globalhook.asp 中的代码可以参照来实现全局钩子

[Hook]API 通过HOOK OpenProcess() 实现进程防杀

mikel阅读(1660)

在WINDOWS操作系统下,当我们无法结束或者不知道怎样结束一个程序的时候,或者是懒得去找“退出”按钮的时候,通常会按 “CTRL+ALT+DEL”呼出任务管理器,找到想结束的程序,点一下“结束任务”就了事了,呵呵,虽然有点粗鲁,但大多数情况下都很有效,不是吗?
                 
    设想一下,如果有这么一种软件,它所要做的工作就是对某个使用者在某台电脑上的活动 作一定的限制,而又不能被使用者通过“结束任务”这种方式轻易地解除限制,那该怎么做?无非有这么三种方法:1.屏蔽“CTRL+ALT+DEL”这个热 键的组合;2.让程序不出现在任务管理器的列表之中;3.让任务管理器无法杀掉这个任务。对于第一种方法,这样未免也太残酷了,用惯了“结束任务”这种方 法的人会很不习惯的;对于第二种方法,在WINDOWS 9X下可以很轻易地使用注册服务进程的方法实现,但是对于WINDOWS  NT架构的操作系统没有这个方法了,进程很难藏身,虽然仍然可以实现隐藏,但 实现机制较为复杂;对于第三种方法,实现起来比较简单,我的作品:IPGate网址过滤器 就是采用的这种方式防杀的,接下来我就来介绍这种方法。
    任务管理器的“结束任务”实际上就是强制终止进程,它所使用的杀手锏是一个叫做TerminateProcess()的Win32 API函数,我们来看看它的定义:
            BOOL TerminateProcess(
              HANDLE      hProcess; // 将被结束进程的句柄
              UINT        uExitCode; // 指定进程的退出码
            );
    看 到这里,是不是觉得不必往下看都知道接下来要做什么:Hook TerminateProcess()函数,每次TerminateProcess()被调用的时候先判断企图结束的进程是否是我的进程,如果是的话就简 单地返回一个错误码就可以了。真的是这么简单吗?先提出一个问题,如何根据hProcess判断它是否是我的进程的句柄?答案是:在我的进程当中先获得我 的进程的句柄,然后通过进程间通讯机制传递给钩子函数,与hProcess进行比较不就行了?错!因为句柄是一个进程相关的值,不同进程中得到的我的进程 的句柄的值在进程间进行比较是无意义的。
    怎么办?我们来考察一下我的hProcess它是如何得到的。一个进程只有它的进程 ID是独一无二的,操作系统通过进程ID来标识一个进程,当某个程序要对这个进程进行访问的话,它首先得用OpenProcess这个函数并传入要访问的 进程ID来获得进程的句柄,来看看它的参数:
            HANDLE OpenProcess(
            DWORD      dwDesiredAccess, // 希望获得的访问权限
            BOOL       bInheritHandle, // 指明是否希望所获得的句柄可以继承
            DWORD      dwProcessId // 要访问的进程ID
            );
     脉 络渐渐显现:在调用TerminateProcess()之前,必先调用OpenProcess(),而OpenProcess()的参数表中的 dwProcessId是在系统范围内唯一确定的。得出结论:要Hook的函数不是TerminateProcess()而是 OpenProcess(),在每次调用OpenProcess()的时候,我们先检查dwProcessId是否为我的进程的ID(利用进程间通讯机 制),如果是的话就简单地返回一个错误码就可以了,任务管理器拿不到我的进程的句柄,它如何结束我的进程呢?
    至此,疑团全部 揭开了。由Hook TerminateProcess()到Hook OpenProcess()的这个过程,体现了一个逆向思维的思想。其实我当初钻进了TerminateProcess()的死胡同里半天出也不来,但最 终还是蹦出了灵感的火花,注意力转移到了OpenProcess()上面,实现了进程防杀。喜悦之余,将这心得体会拿出来与大家分享。

[QQ]让电脑只能登录指定QQ号码,限制其他QQ登陆方法

mikel阅读(614)

这里有一个方法可以电脑只能登录指定QQ号码,供大家参考。

  1、首先登录允许登录的QQ号码,(如果已经在电脑上登录过了,这步可以省略)主要目的就是把自己的QQ号码记录下来,这样在QQ的安装文件夹里就会出来你自己的QQ号码文件夹。如图1

  让电脑只能登录指定QQ号码

  2、进入到你安装QQ的目录中,把其它人的QQ号码文件夹进行删除,只留下你需要登录的QQ号码文件夹即可。

  3、进入到你安装QQ的目录中,找到“WizardCtrl.dll”(动态链接库文件),将该文件删除或者移动到其他的目录中。这里我建议大家改名就可以了,把WizardCtrl最后一个字母改为1,哈哈,这样不容易被人发现。如果删除,以后想恢复就有点麻烦。

  让电脑只能登录指定QQ号码

  当完成以上三步的时候,你的电脑就只认你的QQ号了,其它人的QQ号进行登录的时候,一律无反应。

[QQ]ws2_32.dll 禁止使用某个软件

mikel阅读(691)

一般在自己电脑上,不会不想使用某个软件,但却有些软件不想让别人使用。怎么办?
方法:
在该软件安装目录下新建一个文件名为 ws2_32.dll 的文件(建立一个空的文本文件,然后将文件名改为ws2_32.dll,注意扩展名。) 此后在运行该软件应用程序时,系统就会有出错提示:“应用程序或 DLL X:\XXX\XXX\ws2_32.dll 为无效的  Windows 映像。请再检测一遍您的安装盘。”该软件就不能被使用了。本方法适用基于NT系统的WinXP, Win2000, Win2003。
当然,这只是一个小技巧。如果你想在别人的电脑上玩游戏,却发现不能运行程序,那就赶快到该游戏的安装目录下看看,有没有一个 ws2_32.dll 的文件。
简单原理:
ws2_32.dll 是 Windows Sockets应用程序接口,用于支持 Internet 和网络应用程序,是个动态链接库文件。程序运行时会自动调用 ws2_32.dll 文件。而 Windows 在查找动态链接库文件时会先在应用程序当前目录搜索,但此时该目录下的文件是重建的一个空文件,所以程序就不能被正常运行了。
一些知识:
ws2_32.dll 一般位于系统文件夹中。Windows 在应用程序当前目录没有找到然后会去搜索 Windows 所在目录,如果还是没有会搜索 system32 和 system 目录。一些病毒利用此原理在杀毒软件目录中建立伪 "ws2_32.dll" 的文件或文件夹,在杀毒软件看来这是程序运行需要的文件而调用,这个所谓的“文件”又不具备系统 "ws2_32.dll" 文件的功能,所以杀毒软件等就无法运行了而提示:应用程序正常初始化 (0xc00000ba) 失败!
伪 "ws2_32.dll" 文件夹其实重命名之后程序就可以运行的,但是有个没用的又无法删除的文件夹看着也不舒服,因此这个内部含有非法文件名的文件夹就用下面方法删除:
1. 解压附件里面的文件(修复“显示所有文件和文件夹”.reg),双击它修复显示所有文件和文件夹。然后在资源管理器上点击工具>>选项 >>查看,将隐藏受保护的操作系系统(推荐)的勾去掉,勾选显示所有文件和文件夹之后一路的确认,好了现在隐藏的文件全部显示出来。(临时解 决办法可以将 ws2_32.dll 文件夹改个名称,要彻底删除请往下看。)
2. 到杀毒软件的安装目录下找到以伪 "ws2_32.dll" 的文件夹(一般隐藏的文件夹颜色略白)。
3. 解压附件里面的“将畸形文件托到我上面.bat”到任意目录,用鼠标左键点击将要删除的 ws2_32.dll 文件或者文件夹(一般这些目录下的隐藏文件都需要删除)按住不松然后拖放到该文件图标上(就像把文件拖到文件夹里的操作一样,此工具双击是不能运行的), 一个 CMD 窗口闪烁之后伪 "ws2_32.dll" 文件夹就被删除了。你需要的软件就可以启动了!此批处理文件也可以删除其他文件名怪怪的文件。

[QQ]揭密:映像劫持病毒的原理及预防

mikel阅读(840)

【简 介】
所谓的映像劫持(IFEO)就是Image File Execution Options,位于注册表的 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options 由于这个项主要是用来调试程序用的,对一般用户意义不大。默认是只有管理员和local system有权读写修改。
  映像劫持的定义
  所谓的映像劫持(IFEO)就是Image File Execution Options,位于注册表的
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options 由于这个项主要是用来调试程序用的,对一般用户意义不大。默认是只有管理员和local system有权读写修改。
  通俗一点来说,就是比如我想运行QQ.exe,结果运行的却是FlashGet.exe,也就是说在这种情况下,QQ程序被FLASHGET给劫持了,即你想运行的程序被另外一个程序代替了。
  映像劫持病毒
  虽然映像劫持是系统自带的功能,对我们一般用户来说根本没什么用的必要,但是就有一些病毒通过映像劫持来做文章,表面上看起来是运行了一个程序,实际上病毒已经在后台运行了。
  大部分的病毒和木马都是通过加载系统启动项来运行的,也有一些是注册成为系统服务来启动,他们主要通过修改注册表来实现这个目的,主要有以下几个方面:
  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
  HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs
  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify
  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
  HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce
  但是与一般的木马,病毒不同的是,就有一些病毒偏偏不通过这些来加载自己,不随着系统的启动运行,而是等到你运行某个特定的程序的时候运行, 这也抓住了一些用户的心理,一般的用户,只要发觉自己的机子中了病毒,首先要察看的就是系统的加载项,很少有人会想到映像劫持,这也是这种病毒高明的地 方。
  映像劫持病毒主要通过修改注册表中的HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution options 项来劫持正常的程序,比如有一个病毒 vires.exe 要劫持 qq 程序,它会在上面注册表的位置新建一个qq.exe项,再这个项下面新建一个字符串的键值 Debugger 内容是:C:\WINDOWS\SYSTEM32\VIRES.EXE(这里是病毒藏身的目录)即可。当然如果你把该字符串值改为任意的其他值的话,系统 就会提示找不到该文件。
  映像胁持的基本原理
  WINDOWS NT系统在试图执行一个从命令行调用的可执行文件运行请求时,先会检查运行程序是不是可执行文件,如果是的话,再检查格式的,然后就会检查是否存在。如果 不存在的话,它会提示系统找不到文件或者是“指定的路径不正确等等。把这些键删除后,程序就可以运行!
  映像劫持的应用
  ★ 禁止某些程序的运行
  先看一段代码:
  Windows Registry Editor Version 5.00
  [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File
Execution Options\qq.exe]
  "Debugger"="123.exe"
  把它保存为 norun_qq.reg,双击导入注册表,打开你的QQ看一下效果!
  这段代码的作用是禁止QQ运行,每次双击运行QQ的时候,系统都会弹出一个框提示说找不到QQ,原因就是QQ被重定向了。如果要让QQ继续运行的话,把123.exe改为其安装目录就可以了。
  ★ 偷梁换柱恶作剧
  每次我们按下CTRL+ALT+DEL键时,都会弹出任务管理器,想不想在我们按下这些键的时候让它弹出命令提示符窗口,下面就教你怎么玩:
  Windows Registry Editor Version 5.00
  [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File
Execution Options\taskmgr.exe]
  "Debugger"="C:\\WINDOWS\\pchealth\\helpctr\\binaries\\msconfig.exe"
  将上面的代码另存为 task_cmd.reg,双击导入注册表。按下那三个键看是什么效果,不用我说了吧,是不是很惊讶啊!精彩的还在后头呢?
  ★让病毒迷失自我
  同上面的道理一样,如果我们把病毒程序给重定向了,是不是病毒就不能运行了,答案是肯定的!下面就自己试着玩吧!
  Windows Registry Editor Version 5.00
  [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File
Execution Options\sppoolsv.exe]
  "Debugger"="123.exe"
  [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File
Execution Options\logo_1.exe]
  "Debugger"="123.exe"
  上面的代码是以金猪病毒和威金病毒为例,这样即使这些病毒在系统启动项里面,即使随系统运行了,但是由于映象劫持的重定向作用,还是会被系统提示无法找到病毒文件(这里是logo_1.exe和sppoolsv.exe)。是不是很过瘾啊,想不到病毒也有今天!
  当然你也可以把病毒程序重定向到你要启动的程序中去,如果你想让QQ开机自启动,你可以把上面的123.exe改为你QQ的安装路径即可,但是前提是这些病毒必须是随系统的启动而启动的。
映像劫持的应用也讲了不少了,下面就给大家介绍一下如何防止映象劫持吧!
  映像劫持的预防
  ★权限限制法
  如果用户无权访问该注册表项了,它也就无法修改这些东西了。打开注册表编辑器,进入
  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options ,选中该项,右键——>权限——>高级,将administrator 和 system 用户的权限调低即可(这里只要把写入操作给取消就行了)。
  ★快刀斩乱麻法
  打开注册表编辑器,进入把HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
项,直接删掉 Image File Execution Options 项即可解决问题。

[QQ]禁止和恢复QQ运行

mikel阅读(758)

客户端上网控制( 为ISA定义一个域名集,现在只可访问指定网站)
企业禁止qq运行

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\QQ.exe]
"Debugger"="cmd.exe"

 恢复qq运行
  @echo off
  reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\QQ.exe"  /f

[模板] .Net下模板引擎NVelocity的封装类――VelocityHelper

mikel阅读(875)

最近在做一个项目,客户要求有网站模板功能,能够自主编辑网站的风格,因为这个系统是为政府部门做子站系统,举个例如:每个街道办拥有一个站点,而且可以设置他们的风格。

ASP.NET下的Skin技术可能能够实现这个功能的,不过我个人觉得ASP.NET的Skin技术相对于我的项目来过于复杂了,我需要一个能像PHP下Smarty模板技术的就足够了。在网络上搜索了一阵,最后找到了NVelocity

NVelocity是Java模板引擎Velocity的.Net版本。NVelocity目前官方版本为0.42。官方地址:http://nvelocity.sourceforge.net/, 原作者已经申明不再对NVelocity做技术支持了,所以sourceforge上NVelocity版本一直是0.42不再有更新了。不过目前 NVelocity已经有1.0的版本了,是由castleproject项目维护的。NVelocity.dll能在castle项目中找到。 Castleproject地址:http://www.castleproject.org/。

要使用NVelocity模板技术需要学习VTL语言。网络上关于NVelocity的VTL语言介绍的比较少,不过没有关系,由于NVelocity是有Velocity移植过来的所以Velocity的VTL语言完全适用于NVelocity。下面我们来封装一个VelocityHelper类以方便NVelocity在在.NET中使用

VelocityHelper.cs 文件

using System;
using System;
using System.Web;
using System.IO;
using NVelocity;
using NVelocity.App;
using NVelocity.Context;
using NVelocity.Runtime;
using Commons.Collections;
 
///
/// NVelocity模板工具类 VelocityHelper
///
public class VelocityHelper
{
private VelocityEngine velocity = null;
private IContext context = null;
///
/// 构造函数
///
///
模板文件夹路径
public VelocityHelper(string templatDir)
{
Init(templatDir);
}
///
/// 无参数构造函数
///
public VelocityHelper() { ;}
///
/// 初始话NVelocity模块
///
///
模板文件夹路径
public void Init(string templatDir)
{
//创建VelocityEngine实例对象
velocity = new VelocityEngine();
 
//使用设置初始化VelocityEngine
ExtendedProperties props = new ExtendedProperties();
props.AddProperty(RuntimeConstants.RESOURCE_LOADER, "file");
props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, HttpContext.Current.Server.MapPath(templatDir));
props.AddProperty(RuntimeConstants.INPUT_ENCODING, "gb2312");
props.AddProperty(RuntimeConstants.OUTPUT_ENCODING, "gb2312");
velocity.Init(props);
 
//为模板变量赋值
context = new VelocityContext();
}
///
/// 给模板变量赋值
///
///
模板变量
///
模板变量值
public void Put(string key, object value)
{
if (context == null)
context = new VelocityContext();
context.Put(key, value);
}
///
/// 显示模板
///
///
模板文件名
public void Display(string templatFileName)
{
//从文件中读取模板
Template template = velocity.GetTemplate(templatFileName);
//合并模板
StringWriter writer = new StringWriter();
template.Merge(context, writer);
//输出
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Write(writer.ToString());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
}

使用方法:

VelocityHelper vh = new VelocityHelper();
vh.Init(@"templates");//指定模板文件的相对路径
vh.Put("title", "员工信息");
vh.Put("comName","成都xxxx里公司");
vh.Put("property","天营");
vh.Put("comAddress","四川成都市");
 
ArrayList aems = new ArrayList();
aems.Add(new EM("小李",22,"男"));
aems.Add(new EM("小王",21,"女"));
aems.Add(new EM("小周",22,"男"));
aems.Add(new EM("小瓜",32,"男"));
vh.Put("aems", aems);
 
//使用tp1.htm模板显示
vh.Display("tp1.htm");

注意上面只有关键性的代码,如EM为员工类。完整代码请在下面下载。

找不到NVelocity.dll的朋友可以在这里下载:

VelocityHelper封装类以及使用Demo 其中的NVelocity.dll是1.0版本的

Velocity中文手册下载这个VLT语言一样适用于NVelocity

[MVC]MVC实用集锦(1)

mikel阅读(764)

最近的项目是用ASP.NET MVC开发的,所以希望从实际开发的角度,通过一些实例,帮助大家快速的开发ASP.NET MVC程序。
 1.创建控件,MVC中通过htmlHelper生成HTML标签。

1 <%= Html.TextBox("UserName")%>
2 <%= Html.TextBox("UserName","Coolin")%>
3 <%= Html.TextBox("UserName","Coolin",
            new { @class = "className",disabled = true })%>

最后一项htmlAttributes,可以设置样式等属性。
2.RegisterRoutes带来了什么变化。通过VS创建一个MVC应用程序,会在Global.asax中看到下面的代码(我添加了第一条)
 

 1 routes.MapRoute(
 2         "Account",   
 3         "{Account}/{List}/{type}",                                 
 4         new { controller = "Account", action = "List" }  
 5   );
 6 
 7 routes.MapRoute(
 8         "Default",                                                           
 9         "{controller}/{action}/{id}",                                 
10         new { controller = "Home", action = "Index", id = "" }  
11   );

      
现在看一下它带来的变化,假设view有如下代码

1 <%= Html.ActionLink("男性""List"new { type = "Man" }) %>
2 <%= Html.ActionLink("女性""List"new { type = "Woman" }) %>

1 <%= Url.RouteUrl("Account"new { controller = "Account", action = "List", type= "Man" }) %>
2 <%= Url.RouteUrl("Account"new { controller = "Account", action = "List", type= "Woman" }) %>

对应的Url应该是  localhost:XXXX/Account/List/Man 和 localhost:XXXX/Account/List/Woman
当然也可以不在Global.asax中注册那条规则,对应的Url就会变成大家熟悉的 localhost:XXXX/Account/List?type=Man。
顺 便提一下我在开发中遇到过的一个问题,还以上面的例子为例,在程序的开发阶段,没有加入刚才那条规则,当我们在程序中加入了 sitemap(mvcsitemap),结果却是sitemap的路径永远不能指向Woman的路径,可能是sitemap不能通过 ?后面参数区分路径,后来加入了这条规则,url中去掉参数,问题解决了。
3.ajax异步请求controller
controller中有如下代码

1 public ActionResult Delete(Guid id)
2 {
3      Delete(id);
4      return Json(new { success = true });
5 }

 view中代码如下

1 $.getJSON(<%= Url.Action("Delete""Account",new { id="xx-xx-xxx" }) %>
2     function(result) {
3         if (result.success) {
4             //通过脚本移除此行
5             alert("删除成功!")    
6         } 
7     });

4.扩展htmlHelper,方便在view中调用后台代码。
步骤 1)创建静态类 HtmlHelperExtension。
       2)引入 System.Web.Mvc 。
       3)创建需要的方法,例如:

1 public static string FirstExtension(this HtmlHelper htmlHelper)
2 {
3     return "FirstExtension";
4 }

      4)在view中引入HtmlHelperExtension所在的命名空间(一定不要忘,我忘了很多次)
      5)在view中使用,例如 <%= Html.FirstExtension() %>

[模板]Getting Start With NVelocity

mikel阅读(785)

NVelocityjava velocityC#实现,目前我在CodePlex维护着与Velocity同步的版本。NVelocity也在项目中使用着,在社区也有国外开发者的一些反馈。

 下面是一个在ASP.NET如何使用NVelocity的非常简单例子:

 定义HttpHandler:


 1namespace NVelocity.TestWebsite
 2{
 3    using System;
 4    using System.Collections.Generic;
 5    using System.IO;
 6    using System.Web;
 7
 8    using Commons.Collections;
 9
10    using NVelocity.App;
11    using NVelocity.Context;
12    using NVelocity.Runtime;
13
14    /// <summary>
15    /// 
16    /// </summary>

17    public class NVelocityHandler : IHttpHandler
18    {
19        #region IHttpHandler Members
20
21        public bool IsReusable
22        {
23            get return false; }
24        }

25
26        public void ProcessRequest(HttpContext context)
27        {
28            VelocityEngine velocity = new VelocityEngine();
29
30            ExtendedProperties props = new ExtendedProperties();
31
32            //定义模板路径
33            props.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Views"));
34
35            //初始化
36            velocity.Init(props);
37
38            List<City> list = new List<City>();
39
40            list.Add(new City() { Name = "sh", Id = 21 });
41            list.Add(new City() { Name = "bj", Id = 22 });
42            list.Add(new City() { Name = "tj", Id = 23 });
43
44
45            IContext c = new VelocityContext();
46
47            //添加到上下文中
48            c.Put("cities", list);
49
50            //根据请求输出
51            velocity.MergeTemplate(context.Request.QueryString["vm"+ ".vm""UTF-8", c, context.Response.Output);
52        }

53
54        #endregion

55    }

56
57    /// <summary>
58    /// 城市
59    /// </summary>

60    public class City
61    {
62        /// <summary>
63        /// ID
64        /// </summary>

65        public int Id getset; }
66
67        /// <summary>
68        /// 名称
69        /// </summary>

70        public string Name getset; }
71    }

72}

73

 一个用于测试的default.vm模板文件:


1##循环输出
2#foreach($city in $cities)
3Id:$city.id<br />
4城市名称:$city.name<br />
5#end
6##索引获取数据
7$cities.get_item(2).name
8

 在Web.config中配置上面定义的HttpHandler:


<httpHandlers>
            
<add verb="*" path="*.page" type="NVelocity.TestWebsite.NVelocityHandler,NVelocity.TestWebsite"/>
        
</httpHandlers>

 请求及输出效果: