DirectInput8挂钩问题

时间:2016-01-31 22:42:13

标签: c++ c visual-studio directx directinput

我刚开始使用directx / directinput开发,我正在运行一些测试,其中包含一些我在网上找到的代码示例。无论如何,我想挂钩一个使用dinput8的应用程序将我自己的自定义输入发送到前​​景窗口,并且我正在使用此基础来执行此操作:

    // dllmain.cpp : Defines the entry point for the DLL application.
    #define _CRT_SECURE_NO_WARNINGS                                                         // ignore some warnings...
    #define _CRT_NON_CONFORMING_SWPRINTFS                                                   // ...
    #include "stdio.h"
    #include <windows.h>
    #include "detours.h"
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <vector>
    #include <time.h>
    #include "dinput.h"
    #pragma comment(lib, "detours.lib")
    #pragma comment(lib, "user32.lib")


    typedef HRESULT(__stdcall* GetDeviceState_t)(LPDIRECTINPUTDEVICE, DWORD, LPVOID *);
    HRESULT __stdcall hkGetDeviceState(LPDIRECTINPUTDEVICE pDevice, DWORD cbData, LPVOID *lpvData);
    DWORD Base = 0;
    DWORD GetDeviceStateOffset = 0x7670; // This is the offset of GetDeviceState from DInput8.dll
    // Open IDA and Import the DInput8.dll, then look in the Functions Table for DirectInput8Create
    // There is an Address (1000XXXX or 0CXXXXX) - copy it and save it for later
    // Then take a look for CDIDev_GetDeviceState and copy that address too
    // Now substract the Address from CDIDev_GetDeviceState from DIrectInput8Create and u'll get your offset

    HANDLE tmpHandle = NULL;
    HMODULE hModDInput8 = NULL;
    DWORD dwGetDeviceState = NULL;
    FARPROC dwDirectInput8Create = NULL;

    struct MyKeys
    {
        BYTE Key;
        DWORD StartTime;
        DWORD TTL;
        BOOLEAN isDown;
    };
    MyKeys KeyBuffer[256];

    DWORD WINAPI HookThread();
    void add_log(char* format, ...);
    void SendKeyDInput(byte DIK_, DWORD time);
    GetDeviceState_t pGetDeviceState;

    BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
            add_log("==========LOG START==========");
            add_log("DLL Attached");
            add_log("Creating Thread...");
            tmpHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&HookThread, 0, 0, 0);
            if (!tmpHandle)
            {
                add_log("ThreadCreation Failed!");
            }
            break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
        }
        return TRUE;
    }

    DWORD WINAPI HookThread()
    {
        Base = (DWORD)GetModuleHandleA("test.exe"); 
        add_log("Thread Created");
        add_log("game.exe Base: %x", Base);

        while (!hModDInput8)
        {
            add_log("Searching dinput8.dll...");
            hModDInput8 = GetModuleHandle(L"dinput8.dll");
            Sleep(100);
        }
        add_log("Found dinput8.dll: %x !", hModDInput8);

        while (!dwDirectInput8Create)
        {
            add_log("Searching GetDeviceState...");
            dwDirectInput8Create = GetProcAddress(hModDInput8, "DirectInput8Create");
            Sleep(100);
        }
        add_log("Found DirectInput8Create: %x !", dwDirectInput8Create);

        dwGetDeviceState = (DWORD)((DWORD)dwDirectInput8Create - GetDeviceStateOffset);

        add_log("GetDevicestate is here (DirectInput8Create - %x): %x", GetDeviceStateOffset, dwGetDeviceState);
        add_log("Hooking GetDeviceState...");
        pGetDeviceState = (GetDeviceState_t)DetourAttach(&(PVOID&)dwGetDeviceState, (PBYTE)hkGetDeviceState);
        add_log("Initiate Keyboard Buffer...");

        //initiate buffer
        for (int i = 0; i < 256; i++)
        {
            KeyBuffer[i].isDown = false;
            KeyBuffer[i].Key = 0;
            KeyBuffer[i].StartTime = 0;
            KeyBuffer[i].TTL = 0;
        }

        add_log("Going into Main Loop...");
        while (true)
        {
            if (GetAsyncKeyState(VK_F5) & 1 << 15)
            {
                // We check the Most Sigificant Bit from VK_F5 (F5) whilst we shifted it with 15 bits to left 1 
                // and then a small delay so we have enaught time to release the key
                add_log("F5 pushed attempting to sendkey");
                // Sleep a short time so we have time to release the F5 Key
                Sleep(500);
                // Now we send a A Key with 1 sec time to our Game
                SendKeyDInput(DIK_A, 1000);
            }
        }


        return 0;
    }
    void SendKeyDInput(byte DIK, DWORD time)
    {
        KeyBuffer[DIK].Key = DIK;
        KeyBuffer[DIK].TTL = time;
        KeyBuffer[DIK].StartTime = GetTickCount();
    }

    HRESULT __stdcall hkGetDeviceState(LPDIRECTINPUTDEVICE lpDevice, DWORD cbData, LPVOID *lpvData)
    {
        HRESULT hResult = DI_OK;
        static BYTE buffer[256];
        int key_count = 0;
        for (int i = 0; i<256; i++)
        {
            if (KeyBuffer[i].Key != 0 && KeyBuffer[i].TTL>0 && KeyBuffer[i].StartTime != 0)
            {
                if (GetTickCount() > KeyBuffer[i].StartTime + KeyBuffer[i].TTL && KeyBuffer[i].isDown)
                {
                    KeyBuffer[i].Key = 0;
                    KeyBuffer[i].StartTime = 0;
                    KeyBuffer[i].TTL = 0;
                    KeyBuffer[i].isDown = false;
                    buffer[KeyBuffer[i].Key] = 0;
                }
                else {
                    KeyBuffer[i].isDown = true;
                    buffer[KeyBuffer[i].Key] = 0x80;
                    key_count += 1;
                    add_log("Sending Key %x for %i milliseconds count: %i", KeyBuffer[i].Key, KeyBuffer[i].TTL, key_count);
                }
            }
        }

        if (key_count != 0)
        {
            cbData = 256;
            memcpy(lpvData, buffer, cbData);
        }
        else {
            hResult = pGetDeviceState(lpDevice, cbData, lpvData);
        }

        return hResult;
    }

    //Creates a Logfile in the Game Directory
    void add_log(char* format, ...)
    {
        HANDLE filehandle;
        DWORD dwReadBytes;
        char buffer[2048];
        char writebuffer[2048];
        va_list args;
        va_start(args, format);
        vsprintf_s(buffer, format, args);
        filehandle = CreateFile(L"Log.txt", GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
        SetFilePointer(filehandle, 0, 0, FILE_END);
        sprintf_s(writebuffer, 2048, "Log Added: %s\r\n", buffer);
        WriteFile(filehandle, writebuffer, strlen(writebuffer), &dwReadBytes, 0);
        CloseHandle(filehandle);
    }

此代码中唯一的问题是当我尝试发送输入时,它没有经过。我已经得到了一些帮助并缩小了对此的解决方案,其中包括:&#34; 尝试 GetDeviceState hk 只需 memset(缓冲区,0,大小) SendDeviceData &#34;。我已经搜索了一下,我一直无法找到更多关于如何实施这个解决方案的事情,而且我很难过。 你们当中有人可以告诉我如何使用这些信息来修复这个基础吗?我非常感激,谢谢。

0 个答案:

没有答案