d3d9-patches.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #pragma once
  2. #include <stdint.h>
  3. #ifdef __MINGW32__
  4. #include <excpt.h>
  5. #ifndef TRYLEVEL_NONE
  6. #ifndef __MINGW64__
  7. #define NO_SEH_MINGW
  8. #endif
  9. #ifndef __try
  10. #define __try
  11. #endif
  12. #ifndef __except
  13. #define __except (x) if (0)
  14. #endif
  15. #endif
  16. #endif
  17. static inline int safe_memcmp(const void *p1, const void *p2, size_t size)
  18. {
  19. // Disabled exceptions on mingw-w64 as it is broken
  20. #ifndef __MINGW32__
  21. #ifdef NO_SEH_MINGW
  22. __try1(EXCEPTION_EXECUTE_HANDLER)
  23. #else
  24. __try
  25. #endif
  26. #endif
  27. {
  28. return memcmp(p1, p2, size);
  29. }
  30. // Disabled exceptions on mingw-w64 as it is broken
  31. #ifndef __MINGW32__
  32. #ifdef NO_SEH_MINGW
  33. __except1
  34. #else
  35. __except (EXCEPTION_EXECUTE_HANDLER)
  36. #endif
  37. {
  38. return -1;
  39. }
  40. #endif
  41. }
  42. struct patch_info {
  43. size_t size;
  44. const BYTE *data;
  45. };
  46. #define NEW_PATCH(x) \
  47. { \
  48. sizeof(x), (x) \
  49. }
  50. #define MAX_PATCH_SIZE 2
  51. static const BYTE force_jump[] = {0xEB};
  52. static const BYTE ignore_jump[] = {0x90, 0x90};
  53. #ifdef _WIN64
  54. #define NUM_VERS (16)
  55. #define CMP_SIZE (13)
  56. static const uintptr_t patch_offset[NUM_VERS] = {
  57. 0x54FE6, //win7 - 6.1.7600.16385
  58. 0x55095, //win7 - 6.1.7601.16562
  59. 0x550C5, //win7 - 6.1.7601.17514
  60. 0x6E2FC, //win10 - 10.0.14393.0
  61. 0x6FE18, //win10 - 10.0.10240.16412
  62. 0x70050, //win10 - 10.0.10240.16384
  63. 0x703F8, //win10 - 10.0.10162.0
  64. 0x7E48C, //win10 - 10.0.10586.494
  65. 0x7E49C, //win10 - 10.0.10586.0
  66. 0x8BDB5, //win8.1 - 6.3.9431.00000
  67. 0x8E635, //win8.1 - 6.3.9600.17415
  68. 0x90352, //win8.1 - 6.3.9600.17085
  69. 0x9038A, //win8.1 - 6.3.9600.17095
  70. 0x93AFA, //win8.1 - 6.3.9600.16384
  71. 0x93B8A, //win8.1 - 6.3.9600.16404
  72. 0x1841E5 //win8 - 6.2.9200.16384
  73. };
  74. static const uint8_t patch_cmp[NUM_VERS][CMP_SIZE] = {
  75. {0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x98, 0x68, 0x50, 0x00,
  76. 0x00},
  77. {0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x98, 0x68, 0x50, 0x00,
  78. 0x00},
  79. {0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x98, 0x68, 0x50, 0x00,
  80. 0x00},
  81. {0x8b, 0x81, 0x18, 0x3e, 0x00, 0x00, 0x44, 0x39, 0x98, 0x90, 0x51, 0x00,
  82. 0x00},
  83. {0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
  84. 0x00},
  85. {0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
  86. 0x00},
  87. {0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
  88. 0x00},
  89. {0x8b, 0x81, 0x18, 0x3e, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
  90. 0x00},
  91. {0x8b, 0x81, 0x18, 0x3e, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
  92. 0x00},
  93. {0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0xB0, 0x28, 0x51, 0x00,
  94. 0x00},
  95. {0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0xA8, 0x28, 0x51, 0x00,
  96. 0x00},
  97. {0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00,
  98. 0x00},
  99. {0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00,
  100. 0x00},
  101. {0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00,
  102. 0x00},
  103. {0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00,
  104. 0x00},
  105. {0x49, 0x8b, 0x85, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x88, 0xc8, 0x50, 0x00,
  106. 0x00},
  107. };
  108. static const struct patch_info patch[NUM_VERS] = {
  109. NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(force_jump),
  110. NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(force_jump),
  111. NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(force_jump),
  112. NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump),
  113. NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump),
  114. NEW_PATCH(ignore_jump),
  115. };
  116. #else
  117. #define NUM_VERS (16)
  118. #define CMP_SIZE (12)
  119. static const uintptr_t patch_offset[NUM_VERS] = {
  120. 0x79AA6, //win7 - 6.1.7601.16562
  121. 0x79C9E, //win7 - 6.1.7600.16385
  122. 0x79D96, //win7 - 6.1.7601.17514
  123. 0x7F9BD, //win8.1 - 6.3.9431.00000
  124. 0x8A3F4, //win8.1 - 6.3.9600.16404
  125. 0x8B15F, //win10 - 10.0.10240.16384
  126. 0x8B19F, //win10 - 10.0.10162.0
  127. 0x8B83F, //win10 - 10.0.10240.16412
  128. 0x8E9F7, //win8.1 - 6.3.9600.17095
  129. 0x8F00F, //win8.1 - 6.3.9600.17085
  130. 0x8FBB1, //win8.1 - 6.3.9600.16384
  131. 0x90264, //win8.1 - 6.3.9600.17415
  132. 0x90C3A, //win10 - 10.0.10586.494
  133. 0x90C57, //win10 - 10.0.10586.0
  134. 0x96673, //win10 - 10.0.14393.0
  135. 0x166A08 //win8 - 6.2.9200.16384
  136. };
  137. static const uint8_t patch_cmp[NUM_VERS][CMP_SIZE] = {
  138. {0x8b, 0x89, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb9, 0x80, 0x4b, 0x00,
  139. 0x00},
  140. {0x8b, 0x89, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb9, 0x80, 0x4b, 0x00,
  141. 0x00},
  142. {0x8b, 0x89, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb9, 0x80, 0x4b, 0x00,
  143. 0x00},
  144. {0x8b, 0x80, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb0, 0x40, 0x4c, 0x00,
  145. 0x00},
  146. {0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
  147. 0x00},
  148. {0x81, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
  149. 0x00},
  150. {0x81, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
  151. 0x00},
  152. {0x81, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
  153. 0x00},
  154. {0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
  155. 0x00},
  156. {0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
  157. 0x00},
  158. {0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
  159. 0x00},
  160. {0x87, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
  161. 0x00},
  162. {0x81, 0x18, 0x2a, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
  163. 0x00},
  164. {0x81, 0x18, 0x2a, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
  165. 0x00},
  166. {0x81, 0x18, 0x2a, 0x00, 0x00, 0x83, 0xb8, 0xa8, 0x4c, 0x00, 0x00,
  167. 0x00},
  168. {0x8b, 0x80, 0xe8, 0x29, 0x00, 0x00, 0x39, 0x90, 0xb0, 0x4b, 0x00,
  169. 0x00},
  170. };
  171. static const struct patch_info patch[NUM_VERS] = {
  172. NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(force_jump),
  173. NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(ignore_jump),
  174. NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump), NEW_PATCH(force_jump),
  175. NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(ignore_jump),
  176. NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump),
  177. NEW_PATCH(force_jump),
  178. };
  179. #endif
  180. static inline int get_d3d9_patch(HMODULE d3d9)
  181. {
  182. uint8_t *addr = (uint8_t *)d3d9;
  183. for (int i = 0; i < NUM_VERS; i++) {
  184. int ret = safe_memcmp(addr + patch_offset[i], patch_cmp[i],
  185. CMP_SIZE);
  186. if (ret == 0)
  187. return i;
  188. }
  189. return -1;
  190. }
  191. static inline uint8_t *get_d3d9_patch_addr(HMODULE d3d9, int patch)
  192. {
  193. if (patch == -1)
  194. return nullptr;
  195. uint8_t *addr = (uint8_t *)d3d9;
  196. return addr + patch_offset[patch] + CMP_SIZE;
  197. }