replace ollydbg's WNDPROC on OD's plugin
2016-07-17 17:27
204 查看
前言
在ODBG_Pluginshortcut中处理F1, 发现在CPU窗口不来F1.再试下, 替换OD的窗口处理函数,是否能在每个窗口都收到F1按下的消息.
实验结果:在CPU窗口按F1, 不会被主窗口的窗口处理过程捕获.
看起来像是, CPU窗口子类化过了, 有自己的窗口处理过程.
代码片段
// MyOdPlugin.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include "MyOdPlugin.h" #include "plugin.h" #pragma comment(lib, "OLLYDBG.LIB") // 测试位 #define TEST_BIT_00 0x00000001 #define TEST_BIT_01 0x00000002 #define TEST_BIT_02 0x00000004 #define TEST_BIT_03 0x00000008 #define TEST_BIT_04 0x00000010 #define TEST_BIT_05 0x00000020 #define TEST_BIT_06 0x00000040 #define TEST_BIT_07 0x00000080 #define TEST_BIT_08 0x00000100 #define TEST_BIT_09 0x00000200 #define TEST_BIT_10 0x00000400 #define TEST_BIT_11 0x00000800 #define TEST_BIT_12 0x00001000 #define TEST_BIT_13 0x00002000 #define TEST_BIT_14 0x00004000 #define TEST_BIT_15 0x00008000 #define TEST_BIT_16 0x00010000 #define TEST_BIT_17 0x00020000 #define TEST_BIT_18 0x00040000 #define TEST_BIT_19 0x00080000 #define TEST_BIT_20 0x00100000 #define TEST_BIT_21 0x00200000 #define TEST_BIT_22 0x00400000 #define TEST_BIT_23 0x00800000 #define TEST_BIT_24 0x01000000 #define TEST_BIT_25 0x02000000 #define TEST_BIT_26 0x04000000 #define TEST_BIT_27 0x08000000 #define TEST_BIT_28 0x10000000 #define TEST_BIT_29 0x20000000 #define TEST_BIT_30 0x40000000 #define TEST_BIT_31 0x80000000 // OD插件名字最长为31个字符 // 0--------90--------90--------90 #define MY_OD_PLUGIN_NAME "MyOdPlugin1" HWND g_hOdWnd = NULL; ///< OD 的窗口句柄 LONG_PTR g_OldWndProc = NULL; ///< 原始的窗口处理过程 LRESULT CALLBACK MyWindowProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); LRESULT CALLBACK OnWmKeyDown( HWND hwnd, // handle to window UINT uMsg, // WM_KEYDOWN WPARAM wParam, // virtual-key code LPARAM lParam // key data ); LRESULT CALLBACK OnWmKeyDownF1( HWND hwnd, // handle to window UINT uMsg, // WM_KEYDOWN WPARAM wParam, // virtual-key code LPARAM lParam // key data ); void ReplaceWndProc(); void RestoreWndProc(); BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } // OD启动时,应该是检测了2个必须的插件函数都存在的DLL, 才会当插件来用 // 只实现2个必须函数函数之一时, 插件函数不会被调用 // 先调用 ODBG_Plugindata int ODBG_Plugindata(char *shortname) { if (NULL != shortname) { strcpy(shortname, MY_OD_PLUGIN_NAME); } return PLUGIN_VERSION; } // 再调用 ODBG_Plugininit int ODBG_Plugininit(int ollydbgversion,HWND hw,ulong *features) { if (PLUGIN_VERSION != ollydbgversion) { return -1; } g_hOdWnd = hw; ReplaceWndProc(); return 0; } void ODBG_Plugindestroy(void) { // OD关闭的时候, 会来这里 // IsWindow(g_hOdWnd) 已经无效了 // 只有OD未关闭, 只卸载插件的情况下, 才会恢复原始OD窗口过程 RestoreWndProc(); } void ReplaceWndProc() { if (NULL != g_hOdWnd) { // OD的窗口过程是A版的 g_OldWndProc = SetWindowLongPtrA(g_hOdWnd, GWLP_WNDPROC, (LONG_PTR)MyWindowProc); } } void RestoreWndProc() { if ((NULL != g_hOdWnd) && (NULL != g_OldWndProc)) { if (IsWindow(g_hOdWnd)) { SetWindowLongPtrA(g_hOdWnd, GWLP_WNDPROC, g_OldWndProc); g_OldWndProc = NULL; } } } LRESULT CALLBACK MyWindowProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { if (WM_KEYDOWN == uMsg) { if (S_OK == OnWmKeyDown(hwnd, uMsg, wParam, lParam)) { return S_OK; // An application should return zero if it processes this message. } } return CallWindowProc((WNDPROC)g_OldWndProc, hwnd, uMsg, wParam, lParam); } LRESULT CALLBACK OnWmKeyDown( HWND hwnd, // handle to window UINT uMsg, // WM_KEYDOWN WPARAM wParam, // virtual-key code LPARAM lParam // key data ) { if (S_OK == OnWmKeyDownF1(hwnd, uMsg, wParam, lParam)) { return S_OK; } return S_OK; } LRESULT CALLBACK OnWmKeyDownF1( HWND hwnd, // handle to window UINT uMsg, // WM_KEYDOWN WPARAM wParam, // virtual-key code LPARAM lParam // key data ) { // wParam : Specifies the virtual-key code of the nonsystem key if ((wParam != VK_F1) ///< the F1 key only && ((lParam & TEST_BIT_29) == 0) ///< when keydown, the prev key status is up, only process the first key down ) { return S_FALSE; } // 在CPU窗口按F1, 被OD吃掉了, 不会来F1 // 其他子窗口中按下F1, 可以来 // 和 ODBG_Pluginshortcut 处理效果一样 // 好处是, 如果用自己的窗口处理过程, 可以处理的更细, 不止是键盘组合键 // 弹出帮助文件 if ((NULL != g_hOdWnd) && (::IsWindow(g_hOdWnd))) { ::PostMessage( g_hOdWnd, WM_COMMAND, MAKEWPARAM(2504, 0), // notification code and identifier 0); // handle to control (HWND) } return S_OK; }
相关文章推荐
- 2. crontab 的使用
- 语音信号的预加重和加窗处理
- UILabel,文字添加下划线,中划线
- 国内公共DNS
- hdu4352 XHXJ's LIS(数位Dp)
- Docker安装及镜像管理
- 如何计算两个文档的相似度(一)
- 《linux学习》之怎么安装搜狗输入法
- Linux多线程与同步
- iOS获取经纬度
- Android 自定义View (一)
- 专访腾讯徐汉彬:架构、优化环环相扣,日请求8亿只是起点
- 杭电oj -1008
- ARP协议学习
- 关于《自己动手写CPU》使用GNU工具过程遇到的问题
- memove 的实现
- 用位运算实现四则运算之加减乘除
- Python遇到的小问题与解决方法,时时更新!
- Bit and Byte Order
- 深度解析:清理烂代码