replace ollydbg's WNDPROC on OD's plugin

来源:互联网 发布:d3.js 时间轴 编辑:程序博客网 时间:2024/05/22 06:25

前言

在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_Plugindataint ODBG_Plugindata(char *shortname) {    if (NULL != shortname) {        strcpy(shortname, MY_OD_PLUGIN_NAME);    }    return PLUGIN_VERSION;}// 再调用 ODBG_Plugininitint 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;    }
0 0
原创粉丝点击