读书人

已解决来人散分了Hook DirectInpu

发布时间: 2012-10-08 19:54:56 作者: rapoo

已解决,来人散分了,Hook DirectInput->CreateDevice->GetDeviceData
在一款使用DirectInput的3D游戏里面,通过Hook DirectInput8Create函数,CreateDevice方法,取得了GetDeviceData函数指针,在GetDeviceData里面已经可以取得键盘输入的数据(程序未使用GetDeviceState获得数据)

C/C++ code
HRESULT CHook::MyGetDeviceData(LPVOID *ppvOut, DWORD cbObjectData, LPDIDEVICEOBJECTDATA didod, LPDWORD pdwInOut, DWORD dwFlags){    HRESULT hr = CGetDeviceData::Real(ppvOut, cbObjectData, didod, pdwInOut, dwFlags);    if(SUCCEEDED(hr))    {        for(DWORD i = 0; i < *pdwInOut; i++)        {            if(didod[i].dwOfs == DIK_CAPSLOCK)            {                if(didod[i].dwData & 0x80)                {                    m_TurnLeft = !m_TurnLeft;                    didod[i].dwOfs = m_TurnLeft ? DIK_A : DIK_D;                }                else                    didod[i].dwOfs = m_TurnLeft ? DIK_A : DIK_D;            }        }    }    return hr;}

函数是通过定义的基类CGetDeviceData的纯虚函数MyGetDeviceData进入的,现在的问题是:
只有部分键可以修改,例如DIK_I键,打开物品栏,直接写成
C/C++ code
HRESULT CHook::MyGetDeviceData(LPVOID *ppvOut, DWORD cbObjectData, LPDIDEVICEOBJECTDATA didod, LPDWORD pdwInOut, DWORD dwFlags){    HRESULT hr = CGetDeviceData::Real(ppvOut, cbObjectData, didod, pdwInOut, dwFlags);    if(SUCCEEDED(hr))    {        for(DWORD i = 0; i < *pdwInOut; i++)        {            if(didod[i].dwOfs == DIK_I)            {                didod[i].dwOfs = DIK_L;            }        }    }    return hr;}

并不能打开L键的功能,仍然打开I对应的功能(关于这一点不能理解,例如我修改A=D,D=A可以倒转A、D键位),还有我键盘没有SCROLL键,这个键在这个游戏中是录像的功能,我修改HOME键指向SCROLL也没有效果(断点确实修改了)。
在X64 win7系统,不能写驱动实现。

还有如何在MyGetDeviceData添加按键?

附上基类CGetDeviceData代码
C/C++ code
// CGetDeviceDatatypedef HRESULT (WINAPI *lpGetDeviceData)(LPVOID *ppvOut, DWORD cbObjectData, LPDIDEVICEOBJECTDATA didod, LPDWORD pdwInOut, DWORD dwFlags);class CGetDeviceData{private:    static CGetDeviceData* m_this;    static HRESULT WINAPI _MyGetDeviceData(LPVOID *ppvOut, DWORD cbObjectData, LPDIDEVICEOBJECTDATA didod, LPDWORD pdwInOut, DWORD dwFlags){        return m_this->MyGetDeviceData(ppvOut, cbObjectData, didod, pdwInOut, dwFlags);    };public:    lpGetDeviceData Real;    virtual HRESULT MyGetDeviceData(LPVOID *ppvOut, DWORD cbObjectData, LPDIDEVICEOBJECTDATA didod, LPDWORD pdwInOut, DWORD dwFlags) = 0;    void Init(LPVOID *lplpDirectInputDevice){        ULONG* vptr = *(*(ULONG***)lplpDirectInputDevice);        Real = (lpGetDeviceData)vptr[10];        vptr[10] = (ULONG)_MyGetDeviceData;    };    CGetDeviceData(){        m_this = this;        Real = NULL;    };};


[解决办法]
好几天前就看到这帖子了,实在是不懂啊,惭愧
[解决办法]
我也惭愧~接点分算了
[解决办法]
无功受禄了

读书人网 >VC/MFC

热点推荐