193 lines
5.5 KiB
C++
193 lines
5.5 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 (14)
|
|
#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
|
|
0x6FE18, //win10 - 10.0.10240.16412
|
|
0x70050, //win10 - 10.0.10240.16384
|
|
0x703F8, //win10 - 10.0.10162.0
|
|
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, 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},
|
|
{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(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 (14)
|
|
#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
|
|
0x90C57, //win10 - 10.0.10586.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},
|
|
{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(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;
|
|
}
|