他人の空似自作物置場

DisableJoyL3.zip/DisableJoyL3/main.cpp


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <vector>
#include <map>
#include <string>
#include <algorithm>

#include <Windows.h>

#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>

#include <boost/version.hpp>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>

#include "dll_hack_lib.h"
#include "main.h"

#pragma comment(lib, "dinput8.lib")

const IMAGE_DOS_HEADER &getDosHeader(const HMODULE hmod = ::GetModuleHandle(NULL)) {
  const unsigned int base = reinterpret_cast<unsigned int>(hmod);
  return *reinterpret_cast<const IMAGE_DOS_HEADER *>(base);
}

const IMAGE_NT_HEADERS &getNtHeader(const HMODULE hmod = ::GetModuleHandle(NULL)) {
  const unsigned int base = reinterpret_cast<unsigned int>(hmod);
  const IMAGE_DOS_HEADER &mz = getDosHeader(hmod);
  return *reinterpret_cast<const IMAGE_NT_HEADERS *>(base + mz.e_lfanew);
}

bool ChangeIAT(const std::string &targetDllName, const std::string &targetFuncName, const FARPROC function) {
  std::string targetDllNameLow;
  targetDllNameLow.resize(targetDllName.size());
  std::transform(targetDllName.begin(), targetDllName.end(), targetDllNameLow.begin(), ::tolower);

  const HMODULE hmod = ::GetModuleHandle(NULL);
  const IMAGE_NT_HEADERS &nt = getNtHeader(hmod);
  const IMAGE_DATA_DIRECTORY &dir = nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
  const IMAGE_IMPORT_DESCRIPTOR *desc = reinterpret_cast<const IMAGE_IMPORT_DESCRIPTOR *>(reinterpret_cast<unsigned int>(hmod) + dir.VirtualAddress);
  for (; desc->OriginalFirstThunk != 0; desc++) {
    const char * const dllName = reinterpret_cast<const char *>(reinterpret_cast<unsigned int>(hmod) + desc->Name);
    const unsigned int dllNameLength = ::strlen(dllName);
    std::string dllNameLow;
    dllNameLow.resize(dllNameLength);
    std::transform(&dllName[0], &dllName[dllNameLength], dllNameLow.begin(), ::tolower);
    if (dllNameLow != targetDllNameLow) {
      continue;
    }
    const IMAGE_THUNK_DATA *thunk = reinterpret_cast<const IMAGE_THUNK_DATA *>(reinterpret_cast<unsigned int>(hmod) + desc->OriginalFirstThunk);
    const IMAGE_THUNK_DATA *outThunk = reinterpret_cast<const IMAGE_THUNK_DATA *>(reinterpret_cast<unsigned int>(hmod) + desc->FirstThunk);
    for (;thunk->u1.AddressOfData != NULL; thunk++, outThunk++) {
      if (!IMAGE_SNAP_BY_ORDINAL32(thunk->u1.Ordinal)) {
        const char * const funcName = reinterpret_cast<const char *>(reinterpret_cast<unsigned int>(hmod) + thunk->u1.AddressOfData + 2);
        if (targetFuncName == funcName) {
          return org::click3::DllHackLib::WriteCode(NULL, reinterpret_cast<unsigned int>(outThunk), reinterpret_cast<const unsigned char *>(&function), sizeof(function));
        }
      }
    }
  }
  return false;
}

HRESULT (__stdcall * p_GetDeviceState)(IDirectInputDevice *, DWORD, LPVOID) = NULL;
HRESULT __stdcall d_GetDeviceState(IDirectInputDevice *self, DWORD cbData, LPVOID lpvData) {
  const HRESULT result = p_GetDeviceState(self, cbData, lpvData);
  if (result == DI_OK && cbData == 0x50) {
    reinterpret_cast<unsigned char *>(lpvData)[0x3A] = 0x00;
  }
  return result;
}

HRESULT (__stdcall * p_SetDataFormat)(IDirectInputDevice *, LPCDIDATAFORMAT) = NULL;
HRESULT __stdcall d_SetDataFormat(IDirectInputDevice *self, LPCDIDATAFORMAT lpdf) {
  return p_SetDataFormat(self, lpdf);
}

HRESULT (__stdcall * p_CreateDevice)(IDirectInput8 *, REFGUID, LPDIRECTINPUTDEVICE *, LPUNKNOWN) = NULL;
HRESULT __stdcall d_CreateDevice(IDirectInput8 *self, REFGUID rguid, LPDIRECTINPUTDEVICE *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) {
  const HRESULT result = p_CreateDevice(self, rguid, lplpDirectInputDevice, pUnkOuter);
  if (result == S_OK) {
    if (!org::click3::DllHackLib::ChangeVartualProcAddress(*lplpDirectInputDevice,  reinterpret_cast<void **>(p_SetDataFormat == NULL ? &p_SetDataFormat : NULL), &IDirectInputDevice::SetDataFormat, d_SetDataFormat)) {
      return DIERR_NOTINITIALIZED;
    }
    if (!org::click3::DllHackLib::ChangeVartualProcAddress(*lplpDirectInputDevice,  reinterpret_cast<void **>(p_GetDeviceState == NULL ? &p_GetDeviceState : NULL), &IDirectInputDevice::GetDeviceState, d_GetDeviceState)) {
      return DIERR_NOTINITIALIZED;
    }
  }
  return result;
}

HRESULT __stdcall d_DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter) {
  const HRESULT result = ::DirectInput8Create(hinst, dwVersion, riidltf, ppvOut, punkOuter);
  if (result == DI_OK) {
    if (ppvOut == NULL) {
      return DIERR_INVALIDPARAM;
    }
    if (!org::click3::DllHackLib::ChangeVartualProcAddress(*ppvOut, reinterpret_cast<void **>(&p_CreateDevice), &IDirectInput8::CreateDevice, d_CreateDevice)) {
      return DIERR_INVALIDPARAM;
    }
  }
  return result;
}

void main() {
  if (!ChangeIAT("dinput8.dll", "DirectInput8Create", reinterpret_cast<FARPROC>(d_DirectInput8Create))) {
    return;
  }
}