f53df7da64
Code submissions have continually suffered from formatting inconsistencies that constantly have to be addressed. Using clang-format simplifies this by making code formatting more consistent, and allows automation of the code formatting so that maintainers can focus more on the code itself instead of code formatting.
220 lines
6.2 KiB
C++
220 lines
6.2 KiB
C++
#pragma once
|
|
|
|
#include <stdint.h>
|
|
|
|
#ifdef __MINGW32__
|
|
#include <excpt.h>
|
|
#ifndef TRYLEVEL_NONE
|
|
#ifndef __MINGW64__
|
|
#define NO_SEH_MINGW
|
|
#endif
|
|
#ifndef __try
|
|
#define __try
|
|
#endif
|
|
#ifndef __except
|
|
#define __except (x) if (0)
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
static inline int safe_memcmp(const void *p1, const void *p2, size_t size)
|
|
{
|
|
|
|
// Disabled exceptions on mingw-w64 as it is broken
|
|
#ifndef __MINGW32__
|
|
#ifdef NO_SEH_MINGW
|
|
__try1(EXCEPTION_EXECUTE_HANDLER)
|
|
#else
|
|
__try
|
|
#endif
|
|
#endif
|
|
{
|
|
return memcmp(p1, p2, size);
|
|
}
|
|
// Disabled exceptions on mingw-w64 as it is broken
|
|
#ifndef __MINGW32__
|
|
#ifdef NO_SEH_MINGW
|
|
__except1
|
|
#else
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
#endif
|
|
{
|
|
return -1;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
struct patch_info {
|
|
size_t size;
|
|
const BYTE *data;
|
|
};
|
|
|
|
#define NEW_PATCH(x) \
|
|
{ \
|
|
sizeof(x), (x) \
|
|
}
|
|
#define MAX_PATCH_SIZE 2
|
|
|
|
static const BYTE force_jump[] = {0xEB};
|
|
static const BYTE ignore_jump[] = {0x90, 0x90};
|
|
|
|
#ifdef _WIN64
|
|
|
|
#define NUM_VERS (16)
|
|
#define CMP_SIZE (13)
|
|
|
|
static const uintptr_t patch_offset[NUM_VERS] = {
|
|
0x54FE6, //win7 - 6.1.7600.16385
|
|
0x55095, //win7 - 6.1.7601.16562
|
|
0x550C5, //win7 - 6.1.7601.17514
|
|
0x6E2FC, //win10 - 10.0.14393.0
|
|
0x6FE18, //win10 - 10.0.10240.16412
|
|
0x70050, //win10 - 10.0.10240.16384
|
|
0x703F8, //win10 - 10.0.10162.0
|
|
0x7E48C, //win10 - 10.0.10586.494
|
|
0x7E49C, //win10 - 10.0.10586.0
|
|
0x8BDB5, //win8.1 - 6.3.9431.00000
|
|
0x8E635, //win8.1 - 6.3.9600.17415
|
|
0x90352, //win8.1 - 6.3.9600.17085
|
|
0x9038A, //win8.1 - 6.3.9600.17095
|
|
0x93AFA, //win8.1 - 6.3.9600.16384
|
|
0x93B8A, //win8.1 - 6.3.9600.16404
|
|
0x1841E5 //win8 - 6.2.9200.16384
|
|
};
|
|
|
|
static const uint8_t patch_cmp[NUM_VERS][CMP_SIZE] = {
|
|
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x98, 0x68, 0x50, 0x00,
|
|
0x00},
|
|
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x98, 0x68, 0x50, 0x00,
|
|
0x00},
|
|
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x98, 0x68, 0x50, 0x00,
|
|
0x00},
|
|
{0x8b, 0x81, 0x18, 0x3e, 0x00, 0x00, 0x44, 0x39, 0x98, 0x90, 0x51, 0x00,
|
|
0x00},
|
|
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
|
|
0x00},
|
|
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
|
|
0x00},
|
|
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
|
|
0x00},
|
|
{0x8b, 0x81, 0x18, 0x3e, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
|
|
0x00},
|
|
{0x8b, 0x81, 0x18, 0x3e, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
|
|
0x00},
|
|
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0xB0, 0x28, 0x51, 0x00,
|
|
0x00},
|
|
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0xA8, 0x28, 0x51, 0x00,
|
|
0x00},
|
|
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00,
|
|
0x00},
|
|
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00,
|
|
0x00},
|
|
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00,
|
|
0x00},
|
|
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00,
|
|
0x00},
|
|
{0x49, 0x8b, 0x85, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x88, 0xc8, 0x50, 0x00,
|
|
0x00},
|
|
};
|
|
|
|
static const struct patch_info patch[NUM_VERS] = {
|
|
NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(force_jump),
|
|
NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(force_jump),
|
|
NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(force_jump),
|
|
NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump),
|
|
NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump),
|
|
NEW_PATCH(ignore_jump),
|
|
};
|
|
|
|
#else
|
|
|
|
#define NUM_VERS (16)
|
|
#define CMP_SIZE (12)
|
|
|
|
static const uintptr_t patch_offset[NUM_VERS] = {
|
|
0x79AA6, //win7 - 6.1.7601.16562
|
|
0x79C9E, //win7 - 6.1.7600.16385
|
|
0x79D96, //win7 - 6.1.7601.17514
|
|
0x7F9BD, //win8.1 - 6.3.9431.00000
|
|
0x8A3F4, //win8.1 - 6.3.9600.16404
|
|
0x8B15F, //win10 - 10.0.10240.16384
|
|
0x8B19F, //win10 - 10.0.10162.0
|
|
0x8B83F, //win10 - 10.0.10240.16412
|
|
0x8E9F7, //win8.1 - 6.3.9600.17095
|
|
0x8F00F, //win8.1 - 6.3.9600.17085
|
|
0x8FBB1, //win8.1 - 6.3.9600.16384
|
|
0x90264, //win8.1 - 6.3.9600.17415
|
|
0x90C3A, //win10 - 10.0.10586.494
|
|
0x90C57, //win10 - 10.0.10586.0
|
|
0x96673, //win10 - 10.0.14393.0
|
|
0x166A08 //win8 - 6.2.9200.16384
|
|
};
|
|
|
|
static const uint8_t patch_cmp[NUM_VERS][CMP_SIZE] = {
|
|
{0x8b, 0x89, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb9, 0x80, 0x4b, 0x00,
|
|
0x00},
|
|
{0x8b, 0x89, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb9, 0x80, 0x4b, 0x00,
|
|
0x00},
|
|
{0x8b, 0x89, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb9, 0x80, 0x4b, 0x00,
|
|
0x00},
|
|
{0x8b, 0x80, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb0, 0x40, 0x4c, 0x00,
|
|
0x00},
|
|
{0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
|
|
0x00},
|
|
{0x81, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
|
|
0x00},
|
|
{0x81, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
|
|
0x00},
|
|
{0x81, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
|
|
0x00},
|
|
{0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
|
|
0x00},
|
|
{0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
|
|
0x00},
|
|
{0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
|
|
0x00},
|
|
{0x87, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
|
|
0x00},
|
|
{0x81, 0x18, 0x2a, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
|
|
0x00},
|
|
{0x81, 0x18, 0x2a, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
|
|
0x00},
|
|
{0x81, 0x18, 0x2a, 0x00, 0x00, 0x83, 0xb8, 0xa8, 0x4c, 0x00, 0x00,
|
|
0x00},
|
|
{0x8b, 0x80, 0xe8, 0x29, 0x00, 0x00, 0x39, 0x90, 0xb0, 0x4b, 0x00,
|
|
0x00},
|
|
};
|
|
|
|
static const struct patch_info patch[NUM_VERS] = {
|
|
NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(force_jump),
|
|
NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(ignore_jump),
|
|
NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump), NEW_PATCH(force_jump),
|
|
NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(ignore_jump),
|
|
NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump),
|
|
NEW_PATCH(force_jump),
|
|
};
|
|
|
|
#endif
|
|
|
|
static inline int get_d3d9_patch(HMODULE d3d9)
|
|
{
|
|
uint8_t *addr = (uint8_t *)d3d9;
|
|
for (int i = 0; i < NUM_VERS; i++) {
|
|
int ret = safe_memcmp(addr + patch_offset[i], patch_cmp[i],
|
|
CMP_SIZE);
|
|
if (ret == 0)
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static inline uint8_t *get_d3d9_patch_addr(HMODULE d3d9, int patch)
|
|
{
|
|
if (patch == -1)
|
|
return nullptr;
|
|
|
|
uint8_t *addr = (uint8_t *)d3d9;
|
|
return addr + patch_offset[patch] + CMP_SIZE;
|
|
}
|