日历归档 |
|
<< < 2024 - 11 > >> | Su | Mo | Tu | We | Th | Fr | Sa | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
|
|
|
About Me |
|
|
ZhangSichu |
|
Male |
|
32 |
|
ZhangSichu@gmail.com |
|
ZhangSichu@hotmail.com |
|
ZhangSichu.com |
|
weibo.com/zhangsichu |
|
|
|
个人推荐 |
|
|
|
|
分类归档 |
|
|
|
|
My Friends |
|
|
|
|
UsbHook
|
UsbHook 看到这个题目,你一定会想 Usb钩子是个什么东西,能干什么,还叫这么怪的名字,那给它起个更好听的名字吧UsbSpy Usb间谍。 UsbSpy 产生的背景 在上学的时候,教人工智能的老师有个习惯,就是从来不给别人烤自己上课用的幻灯片。上课的时候,插自己的U盘到教室的机子,然后上放幻灯片,从来不把幻灯片烤到教室的机子上。别的老师不光给学生烤自己的幻灯片,考试前还划重点。这个老师既不烤幻灯片,还不划重点。快到考试了,同学都有些急了,就策划说做一个什么工具当U盘一插就拷U盘上的全部东西到硬盘的预先指定位置。就因为这个原因UsbSpy诞生了,当U盘插入时截获系统消息:WM_DEVICECHANGE.得到U盘盘符。拷贝U盘所有目录下的.ppt文件到D:\ppt下。话不多讲,开始UsbSpy的制作吧。 要写在前面的话 由于各种原因本文没有给出,UsbSpy全部源代码,本文附加了.Net下全局Hook的实现。留下了没有在.Net下动态加载/卸载一个的AppDomain中动态绑定事件的遗憾。UsbSpy的结局:最后虽然做出了UspSpy但是没人感给老师用的机子安装,最后还是熬夜复习赶考试了,最后还是通过了。
全局Hook只能定义在Dll中下面是Dll的定义
定义回调函数 LRESULT CALLBACK CallBackProc(int nCode,WPARAM wParam,LPARAM lParam) { MSG *pMsg = (MSG *)lParam; //HWND hWnd = ::FindWindow("#32770" , NULL);//"MfcHookApp" if ((pMsg->message == WM_DEVICECHANGE) && (!bInsert)) { bInsert=true; MessageBox(NULL, "UsbOK!", "Hook Message", MB_OK); ::PostMessage(hWndMain, WM_INST, wParam, lParam); } return (CallNextHookEx(hHook, nCode, wParam, lParam)); }
安装钩子 BOOL HOOKAPIFUNC InstallHook(HWND hWndm) { //只针对 我的电脑这个进程 //HWND hWnd = ::FindWindow("CabinetWClass", NULL); ////Get The handle. //DWORD dwThreadId = 0; ////Set the Thread number. //if (hWnd != NULL) //{ // dwThreadId = ::GetWindowThreadProcessId(hWnd, &dwThreadId); //} //if (dwThreadId != 0) //{ // hWndMain=hWndm; // hHook = SetWindowsHookEx(WH_GETMESSAGE, CallBackProc, hInstance, dwThreadId); // if (hHook == NULL||hWndMain == NULL) // { // MessageBox(NULL,"Hook Failed!", "Hook Message",MB_OK); // return false; // } // MessageBox(NULL,"Hook Succeed!", "Hook Message",MB_OK); // return true; //}
//针对 所有进程 全局的 hWndMain=hWndm; hHook = SetWindowsHookEx(WH_GETMESSAGE, CallBackProc, hInstance, 0); if (hHook == NULL||hWndMain == NULL) { MessageBox(NULL,"Hook Failed!", "Hook Message",MB_OK); return false; } MessageBox(NULL,"Hook Succeed!", "Hook Message",MB_OK); return true; } 卸载钩子 BOOL HOOKAPIFUNC UninstallHook() { return (BOOL)UnhookWindowsHookEx(hHook); }
CMfcHookDllApp::CMfcHookDllApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance }
// The one and only CMfcHookDllApp object
#pragma data_seg(".SHARED") static HHOOK hHook = NULL; //定义全局钩子 #pragma data_seg()
#define HOOKAPIFUNC extern "C" __declspec(dllexport) #define WM_INST (WM_USER+200) //定义用户自定义消息
HoolApp部分
安装钩子 void CMfcHookAppDlg::InstallHook(void) { HINSTANCE hInstDLL = NULL;
typedef BOOL (*insHookFunc)(HWND hWnd); //();表示不带参数这里表示带参数
insHookFunc insHook = NULL;
if ((hInstDLL = LoadLibrary((LPCTSTR)"MfcHookDll.dll")) != NULL) { //insHook = (insHookFunc)GetProcAddress(hInstDLL, "InstallHook"); insHook = (insHookFunc)GetProcAddress(hInstDLL,MAKEINTRESOURCE(1));//使用函数名和用MAKEINTRESOURCE用名字编码也可以做到 if (insHook != NULL) { insHook(m_hWnd); } } }
卸载钩子 void CMfcHookAppDlg::UninstallHook(void) { HINSTANCE hInstDLL = NULL; typedef BOOL (*uninsHookFunc)(); uninsHookFunc uninsHook = NULL;
if ((hInstDLL = LoadLibrary((LPCTSTR)"MfcHookDll.dll")) != NULL) { uninsHook = (uninsHookFunc)GetProcAddress(hInstDLL,MAKEINTRESOURCE(2)); //uninsHook = (uninsHookFunc)GetProcAddress(hInstDLL, "UninstallHook"); if (uninsHook != NULL) { uninsHook(); } FreeLibrary(hInstDLL); } }
定义用户回调函数 LRESULT CMfcHookAppDlg::OnInst(WPARAM wParam, LPARAM lParam) { // TODO: 处理用户自定义消息 MessageBox("OK","Hook"); return 0; }
BEGIN_MESSAGE_MAP(CMfcHookAppDlg, CDialog) ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_BN_CLICKED(IDC_BUTTON_CLOSE, OnBnClickedButtonClose) ON_BN_CLICKED(IDC_BUTTON_INSTALL, OnBnClickedButtonInstall) ON_BN_CLICKED(IDC_BUTTON_UNINSTALL, OnBnClickedButtonUninstall) ON_MESSAGE(WM_INST, OnInst) //注意这个消息映射 是自己添加的不是系统生成的 ON_WM_CLOSE() END_MESSAGE_MAP()
.Net下的全局钩子的定义 完全参考 http://www.codeproject.com/csharp/globalhook.asp 自己包装了Dll,Exe用工程引入了Dll Exe部分 void MainFormLoad(object sender, System.EventArgs e) { actHook= new DotNetHookDll(); // crate an instance // hang on events actHook.OnMouseActivity+=new MouseEventHandler(MouseMoved); actHook.KeyDown+=new KeyEventHandler(MyKeyDown); actHook.KeyPress+=new KeyPressEventHandler(MyKeyPress); actHook.KeyUp+=new KeyEventHandler(MyKeyUp); } public void MouseMoved(object sender, MouseEventArgs e) { labelMousePosition.Text=String.Format("x={0} y={1}", e.X, e.Y); if (e.Clicks>0) LogWrite("MouseButton - " + e.Button.ToString()); } public void MyKeyDown(object sender, KeyEventArgs e) { LogWrite("KeyDown - " + e.KeyData.ToString()); } public void MyKeyPress(object sender, KeyPressEventArgs e) { LogWrite("KeyPress - " + e.KeyChar); } public void MyKeyUp(object sender, KeyEventArgs e) { LogWrite("KeyUp - " + e.KeyData.ToString()); } private void LogWrite(string txt) { textBox.AppendText(txt + Environment.NewLine); textBox.SelectionStart = textBox.Text.Length; }
部分Dll public event MouseEventHandler OnMouseActivity; //定义事件 public event KeyEventHandler KeyDown; public event KeyPressEventHandler KeyPress; public event KeyEventHandler KeyUp;
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);//定义代理 static int hMouseHook = 0; //Declare mouse hook handle as int. static int hKeyboardHook = 0; //Declare keyboard hook handle as int.
//values from Winuser.h in Microsoft SDK. public const int WH_MOUSE_LL = 14; //mouse hook constant public const int WH_KEYBOARD_LL = 13; //keyboard hook constant
HookProc MouseHookProcedure; //Declare MouseHookProcedure as HookProc type. HookProc KeyboardHookProcedure; //Declare KeyboardHookProcedure as HookProc type.
//Declare wrapper managed POINT class. [StructLayout(LayoutKind.Sequential)] public class POINT { public int x; public int y; }
//Declare wrapper managed MouseHookStruct class. [StructLayout(LayoutKind.Sequential)] public class MouseHookStruct { public POINT pt; public int hwnd; public int wHitTestCode; public int dwExtraInfo; }
//Declare wrapper managed KeyboardHookStruct class. [StructLayout(LayoutKind.Sequential)] public class KeyboardHookStruct { public int vkCode; //Specifies a virtual-key code. The code must be a value in the range 1 to 254. public int scanCode; // Specifies a hardware scan code for the key. public int flags; // Specifies the extended-key flag, event-injected flag, context code, and transition-state flag. public int time; // Specifies the time stamp for this message. public int dwExtraInfo; // Specifies extra information associated with the message. }
private const int WM_MOUSEMOVE = 0x200; private const int WM_LBUTTONDOWN = 0x201; private const int WM_RBUTTONDOWN = 0x204; private const int WM_MBUTTONDOWN = 0x207; private const int WM_LBUTTONUP = 0x202; private const int WM_RBUTTONUP = 0x205; private const int WM_MBUTTONUP = 0x208; private const int WM_LBUTTONDBLCLK = 0x203; private const int WM_RBUTTONDBLCLK = 0x206; private const int WM_MBUTTONDBLCLK = 0x209;
private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam) { // if ok and someone listens to our events if ((nCode >= 0) && (OnMouseActivity!=null)) { MouseButtons button=MouseButtons.None; switch (wParam) { case WM_LBUTTONDOWN: //case WM_LBUTTONUP: //case WM_LBUTTONDBLCLK: button=MouseButtons.Left; break; case WM_RBUTTONDOWN: //case WM_RBUTTONUP: //case WM_RBUTTONDBLCLK: button=MouseButtons.Right; break; } int clickCount=0; if (button!=MouseButtons.None) if (wParam==WM_LBUTTONDBLCLK || wParam==WM_RBUTTONDBLCLK) clickCount=2; else clickCount=1; //Marshall the data from callback. MouseHookStruct MyMouseHookStruct = (MouseHookStruct) Marshal.PtrToStructure(lParam, typeof(MouseHookStruct)); MouseEventArgs e=new MouseEventArgs( button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0 ); OnMouseActivity(this, e); } return CallNextHookEx(hMouseHook, nCode, wParam, lParam); }
没有实现的部分 using System.Reflection; using System.Runtime;
在动态加载的AppDomain中绑定一个事件到函数: void LoadDomain() { //Set the Application Domain Setup. AppDomainSetup domainSetup = new AppDomainSetup(); domainSetup.ApplicationBase = System.Environment.CurrentDirectory;
//Create Domain AppDomain Domain = AppDomain.CreateDomain("RemoteDomain", null, domainSetup); //Add the DotNetHookDll.dll Assembly assembly = Domain.Load("DotNetHookDll"); object asseblyObject = assembly.CreateInstance("DotNetHook.DotNetHookDll");
System.Type DotNetHookDll = asseblyObject.GetType();
EventInfo[] eventInfors = DotNetHookDll.GetEvents() ;
eventInfors[0].AddEventHandler(eventInfors[0],MouseEventHandler(MouseMoved)); //这一句总报错。 AppDomain.Unload(Domain); }
这个函数想做到:不用工程引入Dll,要动态加载Dll然后动态释放Dll,并动态绑定Dll中的一个Event到Exe中的一个Delegate.
总结 .Net下实现一个全局的Hook或者某个进程的Hook都不是很好写,写的都比较多,在这一点上没有MFC简单,但是.Net下的AppDomain应用程序域,这种先进的安全的概念,即使Dll出了问题,有异常产生,主程序动态释放这个域,主程序还可以继续执行,而MFC动态加载Dll,Dll里的函数有了问题,整个程序就死了。MFC在这点上远比不上.Net。
参考文章 http://www.microsoft.com/china/msdn/library/langtool/vcsharp/csharp05162002.mspx http://blog.joycode.com/percyboy/
本文所有事例程序在中文WindowsXp Sp2 + VC7 下编译通过 File: 本文源程序
|
|
#re:UsbHook 11/28/2010 3:12:18 PM sdads
|
|
#re:UsbHook 12/22/2005 5:16:33 PM guest
|
|
#re:UsbHook 12/15/2005 9:46:48 PM 淡如云烟
|
怎么截获U盘被加进系统的消息呢? 好象里面就有截获鼠标和键盘消息的呀? 怎么获得U盘的盘符呢?
|
|
#re:UsbHook 10/31/2005 6:01:44 PM 游客
|
|
|
|
|
|