[Win32] ShellHook的实现
来源:互联网 发布:jquery 数组 json 编辑:程序博客网 时间:2024/05/29 09:57
本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处:http://blog.csdn.net/zuishikonghuan/article/details/49133099
启动Windows,加载Win32子系统,登录一个用户会话后,会启动Shell程序,默认是explorer.exe,就是我们看到的桌面和任务栏等,其实Shell是可以自定义的,我们完全可以自己编写一个Shell取代系统的Shell。下面我们来看看编写Windows Shell的核心技术之一——ShellHook。
ShellHook是什么?当一个窗口创建、激活、关闭时,explorer总是能够捕获相应的消息,并更新任务栏上,就是通过ShellHook实现的。
explorer总是能够捕获相应的消息,并更新任务栏上,最初,我猜测explorer是通过timer定时调用枚举窗口,或者使用全局消息钩子实现,但是这两种方法对系统资源的消耗是巨大的,其实,要想实现这一功能,使用ShellHook即方便又稳定,而且还没有资源占用大的问题。
完整示例源码如下(注释很详细):
#include <windows.h>#pragma comment(lib,"user32.lib")#pragma comment(lib,"gdi32.lib")//#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);WNDCLASS wc;const TCHAR* AppName = TEXT("MyWindowClass1");HWND hwnd1;HWND edit2 = 0;//定义ShellHook的消息static UINT WM_SHELLHOOKMESSAGE;int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPTSTR lpCmdLine,_In_ int nCmdShow){//这里是在构建窗口类结构wc.style = CS_HREDRAW | CS_VREDRAW;wc.lpfnWndProc = WndProc;//窗口回调函数指针wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hInstance = hInstance;//实例句柄wc.hIcon = LoadIcon(hInstance, TEXT("ICON_1"));wc.hCursor = LoadCursor(NULL, IDC_ARROW);//默认指针wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);//默认背景颜色wc.lpszMenuName = NULL;wc.lpszClassName = AppName;//窗口类名//注册窗口类if (!RegisterClass(&wc)){MessageBox(NULL, TEXT("注册窗口类失败!"), TEXT("错误"), MB_ICONERROR);return 0;}//创建窗口int style = WS_OVERLAPPEDWINDOW;hwnd1 = CreateWindowEx(WS_EX_TOPMOST, AppName, TEXT("ShellHook"), style, 50, 50, 500, 500, 0, NULL, hInstance, 0);if (hwnd1 == NULL){MessageBox(NULL, TEXT("创建窗口失败!"), TEXT("错误"), MB_ICONERROR);return 0;}//显示、更新窗口ShowWindow(hwnd1, nCmdShow);UpdateWindow(hwnd1);//消息循环MSG msg;while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}return msg.wParam;}void AddEditText(TCHAR* string, HWND hwnd)//向edit control添加字符串{int len = GetWindowTextLength(hwnd);//获取edit control字符个数SendMessage(hwnd, EM_SETSEL, len, len);//将选中设置为末尾SendMessage(hwnd, EM_REPLACESEL, 0, (LPARAM)string);//将末尾替换为指定的字符串}LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){switch (uMsg){case WM_CREATE://创建edit controledit2 = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("Edit"), TEXT(""), WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL | ES_AUTOVSCROLL, 5, 5, 400, 450, hwnd, (HMENU)8, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);SendMessage(edit2, WM_SETFONT, (WPARAM)GetStockObject(17), 0);//进行ShellHookWM_SHELLHOOKMESSAGE = RegisterWindowMessage(TEXT("SHELLHOOK"));if (!RegisterShellHookWindow(hwnd))MessageBox(hwnd, TEXT("shellhook失败"), TEXT(""), 0);break;case WM_DESTROY://窗口已经销毁PostQuitMessage(0);//退出消息循环,结束应用程序return 0;break;default:break;}//这里是处理ShellHook的回调HWND hwin;if (uMsg == WM_SHELLHOOKMESSAGE){TCHAR tmp[50] = {0};hwin = (HWND)lParam;//得到窗口句柄//判断Shell消息类型if (wParam == HSHELL_WINDOWACTIVATED || wParam == HSHELL_RUDEAPPACTIVATED){AddEditText(TEXT("[窗口激活]"), edit2);goto print;}if (wParam == HSHELL_WINDOWDESTROYED){AddEditText(TEXT("[窗口关闭]"), edit2);goto print;}goto end;print://这里是判断一下窗口风格和扩展风格,如果是toolwindow或者子窗口可以直接过滤掉,但这里只是输出是特殊窗口,但不过滤DWORD style;style = GetWindowLongPtr(hwin, GWL_EXSTYLE);//获取窗口扩展风格if (style & WS_EX_TOOLWINDOW){//使用位与运算判断AddEditText(TEXT("ToolWindow "), edit2);}style = GetWindowLongPtr(hwin, GWL_STYLE);if (style & WS_CHILD){AddEditText(TEXT("Child "), edit2);}_itot((DWORD)hwin, tmp, 10);//将窗口句柄转换为TCHAR字符串AddEditText(tmp, edit2);AddEditText(TEXT(" - "), edit2);DWORD len = GetWindowTextLength(hwin);//获取窗口标题长度len = len * sizeof(TCHAR);//GetWindowTextLength得到的是字符数而不是字节数 //分配内存TCHAR* til = (TCHAR*)VirtualAlloc(NULL, len + 2, MEM_COMMIT, PAGE_READWRITE);//TCHAR* til = new TCHAR[len + 1];RtlZeroMemory(til, len + 2);//或者:til[len]='\0';GetWindowText(hwin, til, len/sizeof(TCHAR) + 2);//获取窗口标题AddEditText(til, edit2);AddEditText(TEXT("\r\n"), edit2);//添加换行符//释放资源VirtualFree(til, len + 2, MEM_DECOMMIT);//delete[] til;return 0;end:;}return DefWindowProc(hwnd, uMsg, wParam, lParam);//其他消息交给系统处理}
效果图:
0 0
- [Win32] ShellHook的实现
- WIN32汇编实现的HashTable
- win32平台下互斥锁的实现
- win32程序的变形窗口的实现
- Win32线程锁的一种高效实现
- 简单线程注入的实现(win32汇编语言)
- 简单线程注入的实现(win32汇编语言)
- WIN32 工具栏贴图背景图的实现
- Win32控制台程序的定时器实现
- win32平台下malloc的内部实现
- win32平台下malloc的内部实现
- Win32 自绘Button的实现方法
- win32平台下malloc的实现
- Win32实现系统任务栏的小图标
- Win32控制台程序的定时器实现
- win32平台下malloc的内部实现
- Win32实现INI文件的读写
- WIN32 SDK thunk 的安全实现
- Application.mk
- IndexedDB: 浏览器里内置的数据库简介
- ENVI遥感影像自然真彩色增强方法
- 浅析c++中的类型转换--const_cast
- 算法(一)求链表中的倒数第K 个结点
- [Win32] ShellHook的实现
- [bzoj2226][SPOJ5971]LCMSUM
- Linux鸟哥私房菜学习笔记(四)
- 进程&线程小结
- Python编写简易木马程序
- Oracle 简单操作手册
- 4-10 阶乘计算升级版 (20分)
- Spring实现AOP的4种方式
- JAVA开发思想与实例--模块化编程