Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

655 righe
20 KiB

  1. #pragma once
  2. // #include <istream>
  3. // #include <fstream>
  4. // #include <vector>
  5. #include <string>
  6. // #include <sstream>
  7. // #include <Psapi.h>
  8. // #include <iterator>
  9. #include <Windows.h>
  10. // #include <assert.h>
  11. // #include <iostream>
  12. // #include <algorithm>
  13. #include <Psapi.h>
  14. // enum EPagePermissions
  15. // {
  16. // Execute = PAGE_EXECUTE,
  17. // ExecuteRead = PAGE_EXECUTE_READ,
  18. // ExecuteReadWrite = PAGE_EXECUTE_READWRITE,
  19. // ExecuteWriteCopy = PAGE_EXECUTE_WRITECOPY,
  20. // Read = PAGE_READONLY,
  21. // ReadWrite = PAGE_READWRITE,
  22. // WriteCopy = PAGE_WRITECOPY,
  23. // WriteCombine = PAGE_WRITECOMBINE
  24. // };
  25. // struct PatternInfo
  26. // {
  27. // const char *Pattern;
  28. // EPagePermissions Permissions;
  29. // };
  30. namespace PatternScan
  31. {
  32. // struct PatternByte
  33. // {
  34. // struct PatternNibble
  35. // {
  36. // unsigned char data;
  37. // bool wildcard;
  38. // } nibble[2];
  39. // };
  40. // static std::string formathexpattern(std::string patterntext)
  41. // {
  42. // std::string result;
  43. // int len = patterntext.length();
  44. // for (int i = 0; i < len; i++)
  45. // if (patterntext[i] == '?' || isxdigit(patterntext[i]))
  46. // result += toupper(patterntext[i]);
  47. // return result;
  48. // }
  49. // static int hexchtoint(char ch)
  50. // {
  51. // if (ch >= '0' && ch <= '9')
  52. // return ch - '0';
  53. // else if (ch >= 'A' && ch <= 'F')
  54. // return ch - 'A' + 10;
  55. // else if (ch >= 'a' && ch <= 'f')
  56. // return ch - 'a' + 10;
  57. // return 0;
  58. // }
  59. // static bool patterntransform(std::string patterntext, std::vector<PatternByte> &pattern)
  60. // {
  61. // pattern.clear();
  62. // patterntext = formathexpattern(patterntext);
  63. // int len = patterntext.length();
  64. // if (!len)
  65. // return false;
  66. // if (len % 2) //not a multiple of 2
  67. // {
  68. // patterntext += '?';
  69. // len++;
  70. // }
  71. // PatternByte newByte;
  72. // for (int i = 0, j = 0; i < len; i++)
  73. // {
  74. // if (patterntext[i] == '?') //wildcard
  75. // {
  76. // newByte.nibble[j].wildcard = true; //match anything
  77. // }
  78. // else //hex
  79. // {
  80. // newByte.nibble[j].wildcard = false;
  81. // newByte.nibble[j].data = hexchtoint(patterntext[i]) & 0xF;
  82. // }
  83. // j++;
  84. // if (j == 2) //two nibbles = one byte
  85. // {
  86. // j = 0;
  87. // pattern.push_back(newByte);
  88. // }
  89. // }
  90. // return true;
  91. // }
  92. // static bool patternmatchbyte(unsigned char byte, const PatternByte &pbyte)
  93. // {
  94. // int matched = 0;
  95. // unsigned char n1 = (byte >> 4) & 0xF;
  96. // if (pbyte.nibble[0].wildcard)
  97. // matched++;
  98. // else if (pbyte.nibble[0].data == n1)
  99. // matched++;
  100. // unsigned char n2 = byte & 0xF;
  101. // if (pbyte.nibble[1].wildcard)
  102. // matched++;
  103. // else if (pbyte.nibble[1].data == n2)
  104. // matched++;
  105. // return (matched == 2);
  106. // }
  107. // size_t patternfind(std::string pattern, int offset)
  108. // {
  109. // std::vector<PatternByte> searchpattern;
  110. // std::string::iterator end_pos = std::remove(pattern.begin(), pattern.end(), ' ');
  111. // pattern.erase(end_pos, pattern.end());
  112. // SYSTEM_INFO sysinf;
  113. // GetSystemInfo(&sysinf);
  114. // DWORD startAddress = (DWORD)sysinf.lpMinimumApplicationAddress;
  115. // unsigned char *data = (unsigned char *)startAddress;
  116. // //MEMORY_BASIC_INFORMATION mbi;
  117. // if (!patterntransform(pattern.c_str(), searchpattern))
  118. // return (size_t)-1;
  119. // //#define MEMORY_READABLE (PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE)
  120. // //#define MEMORY_WRITABLE (PAGE_READWRITE | PAGE_EXECUTE_READWRITE)
  121. // //#define MEMORY_EXECUTABLE (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE)
  122. // size_t searchpatternsize = searchpattern.size();
  123. // for (size_t i = 0, pos = 0; i < 0x7FFFFFFF; i++) //search for the pattern
  124. // {
  125. // //if (VirtualQuery((LPVOID)i, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) != 0
  126. // // && ((mbi.State != MEM_COMMIT) || !(mbi.Protect & MEMORY_READABLE) || (mbi.Protect & PAGE_GUARD)))
  127. // // //&& mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS && !(mbi.Protect & PAGE_GUARD))
  128. // //{
  129. // if (patternmatchbyte(data[i], searchpattern.at(pos))) //check if our pattern matches the current byte
  130. // {
  131. // pos++;
  132. // if (pos == searchpatternsize) //everything matched
  133. // {
  134. // if (offset >= 0)
  135. // return startAddress + i - searchpatternsize + 1 + offset;
  136. // if (offset < 0)
  137. // return startAddress + i - searchpatternsize + 1 - offset;
  138. // }
  139. // }
  140. // else if (pos > 0) //fix by Computer_Angel
  141. // {
  142. // i -= pos;
  143. // pos = 0; //reset current pattern position
  144. // }
  145. // /*}
  146. // else
  147. // i += mbi.RegionSize;*/
  148. // }
  149. // return (size_t)-1;
  150. // }
  151. // // Find all occurences of the Pattern until a wildcard is hit
  152. // std::vector<uintptr_t> FindAllOccurences(std::vector<char *> pattern, std::vector<char> streamToSearch)
  153. // {
  154. // std::vector<uintptr_t> positions;
  155. // // Length of the pattern to look for
  156. // unsigned int patternLength = pattern.size();
  157. // // Total length of file to look through
  158. // unsigned int totalLength = streamToSearch.size();
  159. // // First Byte of the pattern to look for
  160. // //unsigned char* firstMatchByte;
  161. // auto firstMatchByte = std::strtol(reinterpret_cast<const char *>(pattern[0]), nullptr, 16);
  162. // std::vector<unsigned char> parsedPattern;
  163. // parsedPattern.reserve(pattern.size());
  164. // for (auto &pat : pattern)
  165. // {
  166. // parsedPattern.push_back((unsigned char)std::strtoul(reinterpret_cast<const char *>(pat), nullptr, 16));
  167. // }
  168. // for (unsigned int i = 0; i < totalLength; i++)
  169. // {
  170. // //auto cmp = (unsigned char)streamToSearch[i];
  171. // //auto cmp2 = (unsigned char)firstMatchByte;
  172. // //auto cmp2 = std::strtol(reinterpret_cast<const char*>(streamToSearch.data()[i]), nullptr, 16);
  173. // //auto second = streamToSearch;
  174. // //memcpy(&firstMatchByte, streamToSearch[i], sizeof (unsigned char*));
  175. // // If the first Byte of the Searchpattern is at the current location of i
  176. // // and the totalLength - i is greater or equal to the pattern length
  177. // //if(i == 0x00000000000dca41)
  178. // //{
  179. // //Q_ASSERT(false);
  180. // //}
  181. // if ((unsigned char)streamToSearch[i] == firstMatchByte && totalLength - i >= patternLength)
  182. // //if (pattern.data()[0] == *(streamToSearch.begin() +i) && totalLength - i >= patternLength)
  183. // {
  184. // std::vector<unsigned char> match; //[patternLength];
  185. // match.resize(patternLength);
  186. // memcpy(&match[0], &streamToSearch[i], patternLength);
  187. // // If the current range of the search matches the searchPattern
  188. // // add the current position(i) to the positionList and break
  189. // if (memcmp(match.data(), parsedPattern.data(), patternLength) == 0)
  190. // {
  191. // positions.push_back(static_cast<uintptr_t>(i));
  192. // }
  193. // else
  194. // {
  195. // memset(&match, 0, patternLength);
  196. // }
  197. // }
  198. // }
  199. // return positions;
  200. // }
  201. // // Find all occurences of the Pattern until a wildcard is hit
  202. // std::vector<uintptr_t> FindAllOccurences(std::vector<char *> pattern, uintptr_t startAddress, uintptr_t totalSize = 0x7FFFFFFF)
  203. // {
  204. // std::vector<uintptr_t> positions;
  205. // // Length of the pattern to look for
  206. // unsigned int patternLength = pattern.size();
  207. // // Total length of file to look through
  208. // unsigned int totalLength = totalSize - startAddress;
  209. // // First Byte of the pattern to look for
  210. // //unsigned char* firstMatchByte;
  211. // auto firstMatchByte = std::strtol(reinterpret_cast<const char *>(pattern[0]), nullptr, 16);
  212. // std::vector<unsigned char> parsedPattern;
  213. // parsedPattern.reserve(pattern.size());
  214. // for (auto &pat : pattern)
  215. // {
  216. // parsedPattern.push_back((unsigned char)std::strtol(reinterpret_cast<const char *>(pat), nullptr, 16));
  217. // }
  218. // for (unsigned int i = 0; i < totalLength; i++)
  219. // {
  220. // if ((*(PBYTE)startAddress + i) == firstMatchByte && totalLength - i >= patternLength)
  221. // {
  222. // std::vector<unsigned char> match; //[patternLength];
  223. // match.resize(patternLength);
  224. // memcpy(&match[0], (LPVOID)(*(PBYTE)startAddress + i), patternLength);
  225. // // If the current range of the search matches the searchPattern
  226. // // add the current position(i) to the positionList and break
  227. // if (memcmp(match.data(), parsedPattern.data(), patternLength) == 0)
  228. // {
  229. // positions.push_back(static_cast<uintptr_t>(i));
  230. // }
  231. // else
  232. // {
  233. // memset(&match, 0, patternLength);
  234. // }
  235. // }
  236. // }
  237. // return positions;
  238. // }
  239. // // Search the given Pattern iconst n the given& char-vector
  240. // uintptr_t SearchBytePattern(const std::string &pattern, std::vector<char> streamToSearch, int offset)
  241. // {
  242. // std::istringstream buf(pattern);
  243. // std::istream_iterator<std::string> beg(buf), end;
  244. // std::vector<std::string> tokens(beg, end);
  245. // std::vector<char *> patternArray;
  246. // patternArray.reserve(tokens.size());
  247. // for (auto &data : tokens)
  248. // {
  249. // patternArray.push_back(_strdup(data.c_str()));
  250. // }
  251. // std::vector<char *> temp;
  252. // for (unsigned int i = 0; i < tokens.size(); i++)
  253. // {
  254. // // Using QString for the "startsWith function
  255. // // auto value = QString(patternArray[i]);
  256. // // if(!value.startsWith('?', Qt::CaseInsensitive))
  257. // auto value = std::string(patternArray[i]);
  258. // if (!_strnicmp(value.c_str(), "?", sizeof("?")))
  259. // {
  260. // temp.push_back(patternArray[i]);
  261. // }
  262. // else
  263. // break;
  264. // }
  265. // auto occurences = FindAllOccurences(temp, streamToSearch);
  266. // std::vector<unsigned char> parsedPattern;
  267. // parsedPattern.reserve(patternArray.size());
  268. // for (auto &pat : patternArray)
  269. // {
  270. // parsedPattern.push_back((unsigned char)std::strtol(reinterpret_cast<const char *>(pat), nullptr, 16));
  271. // }
  272. // std::vector<char> check(patternArray.size());
  273. // for (auto &occ : occurences)
  274. // {
  275. // memset(check.data(), 0, patternArray.size());
  276. // memcpy(check.data(), &streamToSearch[occ], patternArray.size());
  277. // for (unsigned int o = 0; o < patternArray.size(); o++)
  278. // {
  279. // // If the current Patterncharacter is a wildcard, go to next index
  280. // if (isalnum(*patternArray[o]) == 0) // == 0 || isalpha(*patternArray[0]) == 0)
  281. // continue;
  282. // // Convert current Patternindex
  283. // char pat = (char)std::stoul(std::string(patternArray[o]), nullptr, 16);
  284. // // Compare memory, if equal, result is 0
  285. // int mem = memcmp(&check[o], &pat, 1);
  286. // // If memory is not equal, the pattern doesn't match
  287. // if (mem != 0)
  288. // {
  289. // break;
  290. // }
  291. // // o can only be the size of the pattern if it matches
  292. // if (o == patternArray.size() - 1)
  293. // {
  294. // if (offset < 0)
  295. // return occ - offset;
  296. // if (offset > 0)
  297. // return occ + offset;
  298. // return occ;
  299. // }
  300. // }
  301. // }
  302. // // No result found
  303. // return 0;
  304. // }
  305. // uintptr_t SearchBytePattern(uintptr_t startAddress, uintptr_t fileSize, const std::string &pattern, int offset)
  306. // {
  307. // MODULEINFO miInfos = {NULL};
  308. // HMODULE hmModule = GetModuleHandle(NULL);
  309. // if (hmModule)
  310. // {
  311. // GetModuleInformation(GetCurrentProcess(), hmModule, &miInfos, sizeof(MODULEINFO));
  312. // }
  313. // std::istringstream buf(pattern);
  314. // std::istream_iterator<std::string> beg(buf), end;
  315. // std::vector<std::string> tokens(beg, end);
  316. // std::vector<char *> patternArray;
  317. // patternArray.reserve(tokens.size());
  318. // for (auto &data : tokens)
  319. // {
  320. // patternArray.push_back(_strdup(data.c_str()));
  321. // }
  322. // std::vector<char *> temp;
  323. // for (unsigned int i = 0; i < tokens.size(); i++)
  324. // {
  325. // // Using QString for the "startsWith function
  326. // auto value = std::string(patternArray[i]);
  327. // if (_strnicmp(value.c_str(), "?", sizeof("?")))
  328. // {
  329. // temp.push_back(patternArray[i]);
  330. // }
  331. // else
  332. // break;
  333. // }
  334. // auto occurences = FindAllOccurences(temp, startAddress);
  335. // std::vector<unsigned char> parsedPattern;
  336. // parsedPattern.reserve(patternArray.size());
  337. // for (auto &pat : patternArray)
  338. // {
  339. // parsedPattern.push_back((unsigned char)std::strtol(reinterpret_cast<const char *>(pat), nullptr, 16));
  340. // }
  341. // std::vector<char> check(patternArray.size());
  342. // for (auto &occ : occurences)
  343. // {
  344. // memset(check.data(), 0, patternArray.size());
  345. // memcpy(check.data(), (LPVOID)(startAddress + occ), patternArray.size());
  346. // for (unsigned int o = 0; o < patternArray.size(); o++)
  347. // {
  348. // // If the current Patterncharacter is a wildcard, go to next index
  349. // if (isalnum(*patternArray[o]) == 0) // == 0 || isalpha(*patternArray[0]) == 0)
  350. // continue;
  351. // // Convert current Patternindex
  352. // char pat = (char)std::stoul(std::string(patternArray[o]), nullptr, 16);
  353. // // Compare memory, if equal, result is 0
  354. // int mem = memcmp(&check[o], &pat, 1);
  355. // // If memory is not equal, the pattern doesn't match
  356. // if (mem != 0)
  357. // {
  358. // break;
  359. // }
  360. // // o can only be the size of the pattern if it matches
  361. // if (o == patternArray.size() - 1)
  362. // {
  363. // if (offset < 0)
  364. // return occ - offset;
  365. // if (offset > 0)
  366. // return occ + offset;
  367. // return occ;
  368. // }
  369. // }
  370. // }
  371. // // No result found
  372. // return 0;
  373. // }
  374. // /**
  375. // * \brief Returns first occurrence of byte pattern in a module
  376. // * \param module Base address of module
  377. // * \param signature IDA-style byte pattern
  378. // * \return Pointer to first occurrence
  379. // * \see CSGOSimple by MarkHC
  380. // */
  381. // inline std::uint8_t *patternScan(void *module, std::string signature)
  382. // {
  383. // static auto pattern_to_byte = [](const char *pattern) {
  384. // auto bytes = std::vector<int>{};
  385. // auto start = const_cast<char *>(pattern);
  386. // auto end = const_cast<char *>(pattern) + strlen(pattern);
  387. // for (auto current = start; current < end; ++current)
  388. // {
  389. // if (*current == '??')
  390. // {
  391. // ++current;
  392. // if (*current == '??')
  393. // ++current;
  394. // bytes.push_back(-1);
  395. // }
  396. // else
  397. // bytes.push_back(strtoul(current, &current, 16));
  398. // }
  399. // return bytes;
  400. // };
  401. // auto dosHeader = (PIMAGE_DOS_HEADER)module;
  402. // auto ntHeaders = (PIMAGE_NT_HEADERS)((std::uint8_t *)module + dosHeader->e_lfanew);
  403. // auto sizeOfImage = ntHeaders->OptionalHeader.SizeOfImage;
  404. // auto patternBytes = pattern_to_byte(signature.c_str());
  405. // auto scanBytes = reinterpret_cast<std::uint8_t *>(module);
  406. // auto s = patternBytes.size();
  407. // auto d = patternBytes.data();
  408. // for (auto i = 0ul; i < sizeOfImage - s; ++i)
  409. // {
  410. // bool found = true;
  411. // for (auto j = 0ul; j < s; ++j)
  412. // {
  413. // if (scanBytes[i + j] != d[j] && d[j] != -1)
  414. // {
  415. // found = false;
  416. // break;
  417. // }
  418. // }
  419. // if (found)
  420. // return &scanBytes[i];
  421. // }
  422. // return nullptr;
  423. // }
  424. // static std::vector<unsigned char> ParseSignature(std::string &pattern)
  425. // {
  426. // std::vector<unsigned char> bytes;
  427. // for (unsigned int i = 0; i < pattern.length(); i += 2)
  428. // {
  429. // std::string byteString = pattern.substr(i, 2);
  430. // char byte = (char)strtol(byteString.c_str(), NULL, 16);
  431. // bytes.push_back(byte);
  432. // }
  433. // return bytes;
  434. // }
  435. // static DWORD FindMySignature(const char *szModule, std::string szSignature, int offset)
  436. // {
  437. // /*AllocConsole();
  438. // freopen("CONIN$", "r", stdin);
  439. // freopen("CONOUT$", "w", stdout);
  440. // freopen("CONOUT$", "w", stderr);*/
  441. // MODULEINFO modInfo;
  442. // GetModuleInformation(GetCurrentProcess(), GetModuleHandleA(szModule), &modInfo, sizeof(MODULEINFO));
  443. // DWORD startAddress = (DWORD)modInfo.lpBaseOfDll;
  444. // DWORD endAddress = startAddress + modInfo.SizeOfImage;
  445. // std::string pattern = szSignature;
  446. // std::string::iterator end_pos = std::remove(szSignature.begin(), szSignature.end(), ' ');
  447. // szSignature.erase(end_pos, szSignature.end());
  448. // //const char* pat = szSignature.c_str();
  449. // auto pat = ParseSignature(szSignature);
  450. // DWORD firstMatch = 0;
  451. // //std::vector<char> check(sizeof(szSignature));
  452. // //auto firstMatchByte = std::strtol(&pat[0], nullptr, 16);
  453. // auto firstMatchByte = (int)pat[0];
  454. // std::cout << std::hex << (int)*(unsigned char *)startAddress << '\n';
  455. // std::cout << "Pattern to search for: " << szSignature << '\n';
  456. // std::cout << "Length of Pattern: " << szSignature.length() << '\n';
  457. // std::cout << "FirstMatchByte: " << std::hex << firstMatchByte << '\n';
  458. // SYSTEM_INFO sysinf;
  459. // GetSystemInfo(&sysinf);
  460. // MEMORY_BASIC_INFORMATION mbi;
  461. // //startAddress += 0x4F318C;
  462. // /*for (int i = 0; i < pat.size(); i++)
  463. // std::cout << (int)pat[i];*/
  464. // for (DWORD pCur = startAddress; pCur < 0x7FFFFFFF; pCur++)
  465. // {
  466. // if (VirtualQuery((LPVOID)pCur, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) != 0
  467. // //&& ((mBI.State != MEM_COMMIT) || !(mBI.Protect & MEMORY_READABLE) || (mBI.Protect & PAGE_GUARD)))
  468. // && mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS && !(mbi.Protect & PAGE_GUARD))
  469. // {
  470. // //CREDITS: learn_more
  471. // #define INRANGE(x, a, b) (x >= a && x <= b)
  472. // #define getBits(x) (INRANGE((x & (~0x20)), 'A', 'F') ? ((x & (~0x20)) - 'A' + 0xa) : (INRANGE(x, '0', '9') ? x - '0' : 0))
  473. // #define getByte(x) (getBits(x[0]) << 4 | getBits(x[1]))
  474. // const char *patt = pattern.c_str();
  475. // if (!*patt)
  476. // return firstMatch;
  477. // if (*(PBYTE)patt == '\?' || *(BYTE *)pCur == getByte(patt))
  478. // {
  479. // if (!firstMatch)
  480. // firstMatch = pCur;
  481. // if (!patt[2])
  482. // return firstMatch;
  483. // if (*(PWORD)patt == '\?\?' || *(PBYTE)patt != '\?')
  484. // patt += 3;
  485. // else
  486. // patt += 2; //one ?
  487. // }
  488. // else
  489. // {
  490. // patt = szSignature.c_str();
  491. // firstMatch = 0;
  492. // }
  493. // if ((int)*(unsigned char *)pCur == (int)firstMatchByte && endAddress - pCur >= szSignature.length())
  494. // {
  495. // //if (pattern.data()[0] == *(streamToSearch.begin() +i) && totalLength - i >= patternLength)
  496. // for (unsigned int o = 0; o < pat.size(); o++)
  497. // {
  498. // // If the current Patterncharacter is a wildcard, go to next index
  499. // //if (isalnum(szSignature[o]) == 0)// == 0 || isalpha(*patternArray[0]) == 0)
  500. // if (pat[o] == strtol("??", 0, 16))
  501. // {
  502. // //std::cout << "Current Patternindex is a wildcard: " << pat[o] << '\n';
  503. // continue;
  504. // }
  505. // auto currentPat = (int)pat[o];
  506. // /*std::cout << '\n\n';
  507. // std::cout << "Startaddress: 0x" << std::hex << (DWORD)modInfo.lpBaseOfDll << '\n';
  508. // std::cout << "Currentaddress: 0x" << std::hex << pCur + o << '\n';
  509. // std::cout << "Current Byte is: " << std::hex << (int)*(unsigned char*)(pCur + o) << '\n';
  510. // std::cout << "Current Pattern is: " << std::hex << currentPat << '\n';
  511. // std::cout << '\n';*/
  512. // if ((int)*(unsigned char *)(pCur + o) != currentPat)
  513. // {
  514. // //std::cout << "Cur Val: 0x" << std::hex << (int)*(unsigned char*)(pCur + o) << " Pattern: 0x" << std::hex << currentPat << '\n';
  515. // break;
  516. // }
  517. // // o can only be the size of the pattern if it matches
  518. // if (o == pat.size() - 1)
  519. // {
  520. // if (offset < 0)
  521. // return pCur - offset;
  522. // if (offset > 0)
  523. // return pCur + offset;
  524. // return pCur;
  525. // }
  526. // }
  527. // }
  528. // }
  529. // else
  530. // pCur += mbi.RegionSize;
  531. // }
  532. // return NULL;
  533. // }
  534. static uintptr_t FindSignature(const char *szModule, const char *szSignature)
  535. {
  536. //CREDITS: learn_more
  537. #define INRANGE(x, a, b) (x >= a && x <= b)
  538. #define getBits(x) (INRANGE((x & (~0x20)), 'A', 'F') ? ((x & (~0x20)) - 'A' + 0xa) : (INRANGE(x, '0', '9') ? x - '0' : 0))
  539. #define getByte(x) (getBits(x[0]) << 4 | getBits(x[1]))
  540. MODULEINFO modInfo;
  541. GetModuleInformation(GetCurrentProcess(), GetModuleHandleA(szModule), &modInfo, sizeof(MODULEINFO));
  542. uintptr_t startAddress = (uintptr_t)modInfo.lpBaseOfDll;
  543. uintptr_t endAddress = startAddress + modInfo.SizeOfImage;
  544. const char *pat = szSignature;
  545. uintptr_t firstMatch = 0;
  546. for (uintptr_t pCur = startAddress; pCur < endAddress; pCur++)
  547. {
  548. if (!*pat)
  549. return firstMatch;
  550. if (*(PBYTE)pat == '\?' || *(BYTE *)pCur == getByte(pat))
  551. {
  552. if (!firstMatch)
  553. firstMatch = pCur;
  554. if (!pat[2])
  555. return firstMatch;
  556. if (*(PWORD)pat == '\?\?' || *(PBYTE)pat != '\?')
  557. //if (*(PWORD)pat == '\?' || *(PBYTE)pat != '\?')
  558. pat += 3;
  559. else
  560. pat += 2; //one ?
  561. }
  562. else
  563. {
  564. pat = szSignature;
  565. firstMatch = 0;
  566. }
  567. }
  568. return 0;
  569. }
  570. } // namespace PatternScan