TSHooks.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include <windows.h>
  2. #include <psapi.h>
  3. #include "TSHooks.hpp"
  4. static ADDR ImageBase;
  5. static ADDR ImageSize;
  6. static void InitScanner()
  7. {
  8. HMODULE module = GetModuleHandle(NULL);
  9. if (module) {
  10. MODULEINFO info;
  11. GetModuleInformation(GetCurrentProcess(), module, &info, sizeof(MODULEINFO));
  12. ImageBase = (ADDR)info.lpBaseOfDll;
  13. ImageSize = info.SizeOfImage;
  14. }
  15. }
  16. static bool CompareData(BYTE *data, BYTE *pattern, char* mask)
  17. {
  18. for (; *mask; ++data, ++pattern, ++mask) {
  19. if (*mask == 'x' && *data != *pattern)
  20. return false;
  21. }
  22. return (*mask) == 0;
  23. }
  24. static ADDR FindPattern(ADDR imageBase, ADDR imageSize, BYTE *pattern, char *mask)
  25. {
  26. for (ADDR i = imageBase; i < imageBase + imageSize; ++i) {
  27. if (CompareData((PBYTE)i, pattern, mask))
  28. return i;
  29. }
  30. return 0;
  31. }
  32. // Public
  33. ADDR tsh_ScanFunctionCode(char *pattern, char *mask)
  34. {
  35. return FindPattern(ImageBase, ImageSize - strlen(mask), (BYTE *)pattern, mask);
  36. }
  37. ADDR tsh_ScanFunctionHex(char *text)
  38. {
  39. unsigned int len = strlen(text);
  40. char *patt = new char[len];
  41. char *mask = new char[len];
  42. int outidx = 0;
  43. int val = 0;
  44. bool uk = false;
  45. for (unsigned int i = 0; i < len; ++i) {
  46. char c = text[i];
  47. if(c == '?') {
  48. uk = true;
  49. } else if (c >= '0' && c <= '9') {
  50. val = (val << 4) + (c - '0');
  51. } else if (c >= 'A' && c <= 'F') {
  52. val = (val << 4) + (c - 'A' + 10);
  53. } else if (c >= 'a' && c <= 'f') {
  54. val = (val << 4) + (c - 'a' + 10);
  55. } else if (c == ' ') {
  56. patt[outidx] = uk ? 0 : val;
  57. mask[outidx] = uk ? '?' : 'x';
  58. val = 0;
  59. uk = false;
  60. ++outidx;
  61. }
  62. }
  63. patt[outidx] = uk ? 0 : val;
  64. mask[outidx] = uk ? '?' : 'x';
  65. ++outidx;
  66. patt[outidx] = 0;
  67. mask[outidx] = 0;
  68. ADDR res = tsh_ScanFunctionCode(patt, mask);
  69. delete(patt);
  70. delete(mask);
  71. return res;
  72. }
  73. //////////////////////////////////////////////////
  74. // Call Patching and Hooking
  75. void tsh_PatchByte(ADDR location, BYTE value)
  76. {
  77. DWORD oldProtection;
  78. VirtualProtect((void *)location, 1, PAGE_EXECUTE_READWRITE, &oldProtection);
  79. *((BYTE *)location) = value;
  80. VirtualProtect((void *)location, 1, oldProtection, &oldProtection);
  81. }
  82. void tsh_PatchBytes(unsigned int len, ADDR location, BYTE *repl)
  83. {
  84. for (unsigned int i = 0; i < len; ++i) {
  85. tsh_PatchByte(location + i, repl[i]);
  86. }
  87. }
  88. void tsh_PatchInt(ADDR addr, int rval)
  89. {
  90. for (unsigned int i = 0; i < 4; ++i) {
  91. BYTE repl = (rval >> (i*8)) & 0xFF;
  92. tsh_PatchByte(addr + i, repl);
  93. }
  94. }
  95. int tsh_PatchAllMatches(unsigned int len, char *pattern, char *mask, char *replace, bool debugprint)
  96. {
  97. int numpatched = 0;
  98. for (ADDR i = ImageBase; i < ImageBase + ImageSize - len; ++i){
  99. if (CompareData((BYTE *)i, (BYTE *)pattern, mask)) {
  100. if (debugprint) BlPrintf("TSHooks: Patching call at %08x", i);
  101. ++numpatched;
  102. for (ADDR c = 0; c < len; c++)
  103. tsh_PatchByte(i+c, replace[c]);
  104. }
  105. }
  106. return numpatched;
  107. }
  108. //////////////////////////////////////////////////
  109. // Init
  110. BlFunctionDefIntern(tsh_BlPrintf);
  111. bool tsh_InitInternal()
  112. {
  113. InitScanner();
  114. tsh_BlPrintf = (tsh_tsh_BlPrintfFnT)tsh_ScanFunctionHex((char *)"8D 44 24 08 33 D2 50 FF 74 24 08 33 C9 E8 ? ? ? ? 83 C4 08 C3");
  115. if (!tsh_BlPrintf)
  116. return false;
  117. #ifndef TSFUNCS_EXCLUDE_MINHOOK
  118. MH_STATUS status = MH_Initialize();
  119. if (status != MH_OK) {
  120. tsh_BlPrintf("TSHooks | Failed to initialize MinHook: %s", MH_StatusToString(status));
  121. return false;
  122. }
  123. else if (TSFUNCS_DEBUG)
  124. tsh_BlPrintf("TSHooks | MinHook initialized");
  125. #endif
  126. return true;
  127. }