|
- #pragma once
- // #include <istream>
- // #include <fstream>
- // #include <vector>
- #include <string>
- // #include <sstream>
- // #include <Psapi.h>
- // #include <iterator>
- #include <Windows.h>
- // #include <assert.h>
- // #include <iostream>
- // #include <algorithm>
-
- #include <Psapi.h>
-
- // enum EPagePermissions
- // {
- // Execute = PAGE_EXECUTE,
- // ExecuteRead = PAGE_EXECUTE_READ,
- // ExecuteReadWrite = PAGE_EXECUTE_READWRITE,
- // ExecuteWriteCopy = PAGE_EXECUTE_WRITECOPY,
- // Read = PAGE_READONLY,
- // ReadWrite = PAGE_READWRITE,
- // WriteCopy = PAGE_WRITECOPY,
- // WriteCombine = PAGE_WRITECOMBINE
- // };
-
- // struct PatternInfo
- // {
- // const char *Pattern;
- // EPagePermissions Permissions;
- // };
-
- namespace PatternScan
- {
- // struct PatternByte
- // {
- // struct PatternNibble
- // {
- // unsigned char data;
- // bool wildcard;
- // } nibble[2];
- // };
-
- // static std::string formathexpattern(std::string patterntext)
- // {
- // std::string result;
- // int len = patterntext.length();
- // for (int i = 0; i < len; i++)
- // if (patterntext[i] == '?' || isxdigit(patterntext[i]))
- // result += toupper(patterntext[i]);
- // return result;
- // }
-
- // static int hexchtoint(char ch)
- // {
- // if (ch >= '0' && ch <= '9')
- // return ch - '0';
- // else if (ch >= 'A' && ch <= 'F')
- // return ch - 'A' + 10;
- // else if (ch >= 'a' && ch <= 'f')
- // return ch - 'a' + 10;
- // return 0;
- // }
-
- // static bool patterntransform(std::string patterntext, std::vector<PatternByte> &pattern)
- // {
- // pattern.clear();
- // patterntext = formathexpattern(patterntext);
- // int len = patterntext.length();
- // if (!len)
- // return false;
-
- // if (len % 2) //not a multiple of 2
- // {
- // patterntext += '?';
- // len++;
- // }
-
- // PatternByte newByte;
- // for (int i = 0, j = 0; i < len; i++)
- // {
- // if (patterntext[i] == '?') //wildcard
- // {
- // newByte.nibble[j].wildcard = true; //match anything
- // }
- // else //hex
- // {
- // newByte.nibble[j].wildcard = false;
- // newByte.nibble[j].data = hexchtoint(patterntext[i]) & 0xF;
- // }
-
- // j++;
- // if (j == 2) //two nibbles = one byte
- // {
- // j = 0;
- // pattern.push_back(newByte);
- // }
- // }
- // return true;
- // }
-
- // static bool patternmatchbyte(unsigned char byte, const PatternByte &pbyte)
- // {
- // int matched = 0;
-
- // unsigned char n1 = (byte >> 4) & 0xF;
- // if (pbyte.nibble[0].wildcard)
- // matched++;
- // else if (pbyte.nibble[0].data == n1)
- // matched++;
-
- // unsigned char n2 = byte & 0xF;
- // if (pbyte.nibble[1].wildcard)
- // matched++;
- // else if (pbyte.nibble[1].data == n2)
- // matched++;
-
- // return (matched == 2);
- // }
-
- // size_t patternfind(std::string pattern, int offset)
- // {
- // std::vector<PatternByte> searchpattern;
-
- // std::string::iterator end_pos = std::remove(pattern.begin(), pattern.end(), ' ');
- // pattern.erase(end_pos, pattern.end());
-
- // SYSTEM_INFO sysinf;
- // GetSystemInfo(&sysinf);
-
- // DWORD startAddress = (DWORD)sysinf.lpMinimumApplicationAddress;
-
- // unsigned char *data = (unsigned char *)startAddress;
-
- // //MEMORY_BASIC_INFORMATION mbi;
-
- // if (!patterntransform(pattern.c_str(), searchpattern))
- // return (size_t)-1;
-
- // //#define MEMORY_READABLE (PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE)
- // //#define MEMORY_WRITABLE (PAGE_READWRITE | PAGE_EXECUTE_READWRITE)
- // //#define MEMORY_EXECUTABLE (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE)
- // size_t searchpatternsize = searchpattern.size();
- // for (size_t i = 0, pos = 0; i < 0x7FFFFFFF; i++) //search for the pattern
- // {
- // //if (VirtualQuery((LPVOID)i, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) != 0
- // // && ((mbi.State != MEM_COMMIT) || !(mbi.Protect & MEMORY_READABLE) || (mbi.Protect & PAGE_GUARD)))
- // // //&& mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS && !(mbi.Protect & PAGE_GUARD))
- // //{
- // if (patternmatchbyte(data[i], searchpattern.at(pos))) //check if our pattern matches the current byte
- // {
- // pos++;
- // if (pos == searchpatternsize) //everything matched
- // {
- // if (offset >= 0)
- // return startAddress + i - searchpatternsize + 1 + offset;
- // if (offset < 0)
- // return startAddress + i - searchpatternsize + 1 - offset;
- // }
- // }
- // else if (pos > 0) //fix by Computer_Angel
- // {
- // i -= pos;
- // pos = 0; //reset current pattern position
- // }
- // /*}
- // else
- // i += mbi.RegionSize;*/
- // }
- // return (size_t)-1;
- // }
-
- // // Find all occurences of the Pattern until a wildcard is hit
- // std::vector<uintptr_t> FindAllOccurences(std::vector<char *> pattern, std::vector<char> streamToSearch)
- // {
- // std::vector<uintptr_t> positions;
-
- // // Length of the pattern to look for
- // unsigned int patternLength = pattern.size();
-
- // // Total length of file to look through
- // unsigned int totalLength = streamToSearch.size();
-
- // // First Byte of the pattern to look for
- // //unsigned char* firstMatchByte;
- // auto firstMatchByte = std::strtol(reinterpret_cast<const char *>(pattern[0]), nullptr, 16);
- // std::vector<unsigned char> parsedPattern;
- // parsedPattern.reserve(pattern.size());
- // for (auto &pat : pattern)
- // {
- // parsedPattern.push_back((unsigned char)std::strtoul(reinterpret_cast<const char *>(pat), nullptr, 16));
- // }
-
- // for (unsigned int i = 0; i < totalLength; i++)
- // {
- // //auto cmp = (unsigned char)streamToSearch[i];
- // //auto cmp2 = (unsigned char)firstMatchByte;
- // //auto cmp2 = std::strtol(reinterpret_cast<const char*>(streamToSearch.data()[i]), nullptr, 16);
- // //auto second = streamToSearch;
- // //memcpy(&firstMatchByte, streamToSearch[i], sizeof (unsigned char*));
- // // If the first Byte of the Searchpattern is at the current location of i
- // // and the totalLength - i is greater or equal to the pattern length
- // //if(i == 0x00000000000dca41)
- // //{
- // //Q_ASSERT(false);
- // //}
- // if ((unsigned char)streamToSearch[i] == firstMatchByte && totalLength - i >= patternLength)
- // //if (pattern.data()[0] == *(streamToSearch.begin() +i) && totalLength - i >= patternLength)
- // {
- // std::vector<unsigned char> match; //[patternLength];
- // match.resize(patternLength);
- // memcpy(&match[0], &streamToSearch[i], patternLength);
-
- // // If the current range of the search matches the searchPattern
- // // add the current position(i) to the positionList and break
- // if (memcmp(match.data(), parsedPattern.data(), patternLength) == 0)
- // {
- // positions.push_back(static_cast<uintptr_t>(i));
- // }
- // else
- // {
- // memset(&match, 0, patternLength);
- // }
- // }
- // }
- // return positions;
- // }
-
- // // Find all occurences of the Pattern until a wildcard is hit
- // std::vector<uintptr_t> FindAllOccurences(std::vector<char *> pattern, uintptr_t startAddress, uintptr_t totalSize = 0x7FFFFFFF)
- // {
- // std::vector<uintptr_t> positions;
-
- // // Length of the pattern to look for
- // unsigned int patternLength = pattern.size();
-
- // // Total length of file to look through
- // unsigned int totalLength = totalSize - startAddress;
-
- // // First Byte of the pattern to look for
- // //unsigned char* firstMatchByte;
- // auto firstMatchByte = std::strtol(reinterpret_cast<const char *>(pattern[0]), nullptr, 16);
- // std::vector<unsigned char> parsedPattern;
- // parsedPattern.reserve(pattern.size());
-
- // for (auto &pat : pattern)
- // {
- // parsedPattern.push_back((unsigned char)std::strtol(reinterpret_cast<const char *>(pat), nullptr, 16));
- // }
-
- // for (unsigned int i = 0; i < totalLength; i++)
- // {
- // if ((*(PBYTE)startAddress + i) == firstMatchByte && totalLength - i >= patternLength)
- // {
- // std::vector<unsigned char> match; //[patternLength];
- // match.resize(patternLength);
- // memcpy(&match[0], (LPVOID)(*(PBYTE)startAddress + i), patternLength);
-
- // // If the current range of the search matches the searchPattern
- // // add the current position(i) to the positionList and break
- // if (memcmp(match.data(), parsedPattern.data(), patternLength) == 0)
- // {
- // positions.push_back(static_cast<uintptr_t>(i));
- // }
- // else
- // {
- // memset(&match, 0, patternLength);
- // }
- // }
- // }
- // return positions;
- // }
-
- // // Search the given Pattern iconst n the given& char-vector
- // uintptr_t SearchBytePattern(const std::string &pattern, std::vector<char> streamToSearch, int offset)
- // {
- // std::istringstream buf(pattern);
- // std::istream_iterator<std::string> beg(buf), end;
- // std::vector<std::string> tokens(beg, end);
- // std::vector<char *> patternArray;
- // patternArray.reserve(tokens.size());
- // for (auto &data : tokens)
- // {
- // patternArray.push_back(_strdup(data.c_str()));
- // }
-
- // std::vector<char *> temp;
-
- // for (unsigned int i = 0; i < tokens.size(); i++)
- // {
- // // Using QString for the "startsWith function
- // // auto value = QString(patternArray[i]);
- // // if(!value.startsWith('?', Qt::CaseInsensitive))
- // auto value = std::string(patternArray[i]);
- // if (!_strnicmp(value.c_str(), "?", sizeof("?")))
- // {
- // temp.push_back(patternArray[i]);
- // }
- // else
- // break;
- // }
-
- // auto occurences = FindAllOccurences(temp, streamToSearch);
-
- // std::vector<unsigned char> parsedPattern;
- // parsedPattern.reserve(patternArray.size());
- // for (auto &pat : patternArray)
- // {
- // parsedPattern.push_back((unsigned char)std::strtol(reinterpret_cast<const char *>(pat), nullptr, 16));
- // }
-
- // std::vector<char> check(patternArray.size());
- // for (auto &occ : occurences)
- // {
- // memset(check.data(), 0, patternArray.size());
- // memcpy(check.data(), &streamToSearch[occ], patternArray.size());
-
- // for (unsigned int o = 0; o < patternArray.size(); o++)
- // {
- // // If the current Patterncharacter is a wildcard, go to next index
- // if (isalnum(*patternArray[o]) == 0) // == 0 || isalpha(*patternArray[0]) == 0)
- // continue;
-
- // // Convert current Patternindex
- // char pat = (char)std::stoul(std::string(patternArray[o]), nullptr, 16);
-
- // // Compare memory, if equal, result is 0
- // int mem = memcmp(&check[o], &pat, 1);
-
- // // If memory is not equal, the pattern doesn't match
- // if (mem != 0)
- // {
- // break;
- // }
- // // o can only be the size of the pattern if it matches
- // if (o == patternArray.size() - 1)
- // {
- // if (offset < 0)
- // return occ - offset;
- // if (offset > 0)
- // return occ + offset;
- // return occ;
- // }
- // }
- // }
- // // No result found
- // return 0;
- // }
-
- // uintptr_t SearchBytePattern(uintptr_t startAddress, uintptr_t fileSize, const std::string &pattern, int offset)
- // {
- // MODULEINFO miInfos = {NULL};
- // HMODULE hmModule = GetModuleHandle(NULL);
-
- // if (hmModule)
- // {
- // GetModuleInformation(GetCurrentProcess(), hmModule, &miInfos, sizeof(MODULEINFO));
- // }
-
- // std::istringstream buf(pattern);
- // std::istream_iterator<std::string> beg(buf), end;
- // std::vector<std::string> tokens(beg, end);
- // std::vector<char *> patternArray;
- // patternArray.reserve(tokens.size());
- // for (auto &data : tokens)
- // {
- // patternArray.push_back(_strdup(data.c_str()));
- // }
-
- // std::vector<char *> temp;
-
- // for (unsigned int i = 0; i < tokens.size(); i++)
- // {
- // // Using QString for the "startsWith function
- // auto value = std::string(patternArray[i]);
- // if (_strnicmp(value.c_str(), "?", sizeof("?")))
- // {
- // temp.push_back(patternArray[i]);
- // }
- // else
- // break;
- // }
-
- // auto occurences = FindAllOccurences(temp, startAddress);
-
- // std::vector<unsigned char> parsedPattern;
- // parsedPattern.reserve(patternArray.size());
- // for (auto &pat : patternArray)
- // {
- // parsedPattern.push_back((unsigned char)std::strtol(reinterpret_cast<const char *>(pat), nullptr, 16));
- // }
-
- // std::vector<char> check(patternArray.size());
- // for (auto &occ : occurences)
- // {
- // memset(check.data(), 0, patternArray.size());
- // memcpy(check.data(), (LPVOID)(startAddress + occ), patternArray.size());
-
- // for (unsigned int o = 0; o < patternArray.size(); o++)
- // {
- // // If the current Patterncharacter is a wildcard, go to next index
- // if (isalnum(*patternArray[o]) == 0) // == 0 || isalpha(*patternArray[0]) == 0)
- // continue;
-
- // // Convert current Patternindex
- // char pat = (char)std::stoul(std::string(patternArray[o]), nullptr, 16);
-
- // // Compare memory, if equal, result is 0
- // int mem = memcmp(&check[o], &pat, 1);
-
- // // If memory is not equal, the pattern doesn't match
- // if (mem != 0)
- // {
- // break;
- // }
- // // o can only be the size of the pattern if it matches
- // if (o == patternArray.size() - 1)
- // {
- // if (offset < 0)
- // return occ - offset;
- // if (offset > 0)
- // return occ + offset;
- // return occ;
- // }
- // }
- // }
- // // No result found
- // return 0;
- // }
-
- // /**
- // * \brief Returns first occurrence of byte pattern in a module
- // * \param module Base address of module
- // * \param signature IDA-style byte pattern
- // * \return Pointer to first occurrence
- // * \see CSGOSimple by MarkHC
- // */
- // inline std::uint8_t *patternScan(void *module, std::string signature)
- // {
- // static auto pattern_to_byte = [](const char *pattern) {
- // auto bytes = std::vector<int>{};
- // auto start = const_cast<char *>(pattern);
- // auto end = const_cast<char *>(pattern) + strlen(pattern);
-
- // for (auto current = start; current < end; ++current)
- // {
- // if (*current == '??')
- // {
- // ++current;
- // if (*current == '??')
- // ++current;
- // bytes.push_back(-1);
- // }
- // else
- // bytes.push_back(strtoul(current, ¤t, 16));
- // }
- // return bytes;
- // };
-
- // auto dosHeader = (PIMAGE_DOS_HEADER)module;
- // auto ntHeaders = (PIMAGE_NT_HEADERS)((std::uint8_t *)module + dosHeader->e_lfanew);
-
- // auto sizeOfImage = ntHeaders->OptionalHeader.SizeOfImage;
- // auto patternBytes = pattern_to_byte(signature.c_str());
- // auto scanBytes = reinterpret_cast<std::uint8_t *>(module);
-
- // auto s = patternBytes.size();
- // auto d = patternBytes.data();
-
- // for (auto i = 0ul; i < sizeOfImage - s; ++i)
- // {
- // bool found = true;
- // for (auto j = 0ul; j < s; ++j)
- // {
- // if (scanBytes[i + j] != d[j] && d[j] != -1)
- // {
- // found = false;
- // break;
- // }
- // }
- // if (found)
- // return &scanBytes[i];
- // }
-
- // return nullptr;
- // }
-
- // static std::vector<unsigned char> ParseSignature(std::string &pattern)
- // {
- // std::vector<unsigned char> bytes;
- // for (unsigned int i = 0; i < pattern.length(); i += 2)
- // {
- // std::string byteString = pattern.substr(i, 2);
- // char byte = (char)strtol(byteString.c_str(), NULL, 16);
- // bytes.push_back(byte);
- // }
- // return bytes;
- // }
-
- // static DWORD FindMySignature(const char *szModule, std::string szSignature, int offset)
- // {
- // /*AllocConsole();
- // freopen("CONIN$", "r", stdin);
- // freopen("CONOUT$", "w", stdout);
- // freopen("CONOUT$", "w", stderr);*/
-
- // MODULEINFO modInfo;
- // GetModuleInformation(GetCurrentProcess(), GetModuleHandleA(szModule), &modInfo, sizeof(MODULEINFO));
- // DWORD startAddress = (DWORD)modInfo.lpBaseOfDll;
- // DWORD endAddress = startAddress + modInfo.SizeOfImage;
-
- // std::string pattern = szSignature;
- // std::string::iterator end_pos = std::remove(szSignature.begin(), szSignature.end(), ' ');
- // szSignature.erase(end_pos, szSignature.end());
-
- // //const char* pat = szSignature.c_str();
- // auto pat = ParseSignature(szSignature);
-
- // DWORD firstMatch = 0;
-
- // //std::vector<char> check(sizeof(szSignature));
- // //auto firstMatchByte = std::strtol(&pat[0], nullptr, 16);
- // auto firstMatchByte = (int)pat[0];
- // std::cout << std::hex << (int)*(unsigned char *)startAddress << '\n';
- // std::cout << "Pattern to search for: " << szSignature << '\n';
- // std::cout << "Length of Pattern: " << szSignature.length() << '\n';
- // std::cout << "FirstMatchByte: " << std::hex << firstMatchByte << '\n';
-
- // SYSTEM_INFO sysinf;
- // GetSystemInfo(&sysinf);
-
- // MEMORY_BASIC_INFORMATION mbi;
- // //startAddress += 0x4F318C;
-
- // /*for (int i = 0; i < pat.size(); i++)
- // std::cout << (int)pat[i];*/
-
- // for (DWORD pCur = startAddress; pCur < 0x7FFFFFFF; pCur++)
- // {
- // if (VirtualQuery((LPVOID)pCur, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) != 0
- // //&& ((mBI.State != MEM_COMMIT) || !(mBI.Protect & MEMORY_READABLE) || (mBI.Protect & PAGE_GUARD)))
- // && mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS && !(mbi.Protect & PAGE_GUARD))
- // {
-
- // //CREDITS: learn_more
- // #define INRANGE(x, a, b) (x >= a && x <= b)
- // #define getBits(x) (INRANGE((x & (~0x20)), 'A', 'F') ? ((x & (~0x20)) - 'A' + 0xa) : (INRANGE(x, '0', '9') ? x - '0' : 0))
- // #define getByte(x) (getBits(x[0]) << 4 | getBits(x[1]))
-
- // const char *patt = pattern.c_str();
-
- // if (!*patt)
- // return firstMatch;
- // if (*(PBYTE)patt == '\?' || *(BYTE *)pCur == getByte(patt))
- // {
- // if (!firstMatch)
- // firstMatch = pCur;
- // if (!patt[2])
- // return firstMatch;
- // if (*(PWORD)patt == '\?\?' || *(PBYTE)patt != '\?')
- // patt += 3;
- // else
- // patt += 2; //one ?
- // }
- // else
- // {
- // patt = szSignature.c_str();
- // firstMatch = 0;
- // }
-
- // if ((int)*(unsigned char *)pCur == (int)firstMatchByte && endAddress - pCur >= szSignature.length())
- // {
- // //if (pattern.data()[0] == *(streamToSearch.begin() +i) && totalLength - i >= patternLength)
- // for (unsigned int o = 0; o < pat.size(); o++)
- // {
- // // If the current Patterncharacter is a wildcard, go to next index
- // //if (isalnum(szSignature[o]) == 0)// == 0 || isalpha(*patternArray[0]) == 0)
- // if (pat[o] == strtol("??", 0, 16))
- // {
- // //std::cout << "Current Patternindex is a wildcard: " << pat[o] << '\n';
- // continue;
- // }
-
- // auto currentPat = (int)pat[o];
-
- // /*std::cout << '\n\n';
- // std::cout << "Startaddress: 0x" << std::hex << (DWORD)modInfo.lpBaseOfDll << '\n';
- // std::cout << "Currentaddress: 0x" << std::hex << pCur + o << '\n';
- // std::cout << "Current Byte is: " << std::hex << (int)*(unsigned char*)(pCur + o) << '\n';
- // std::cout << "Current Pattern is: " << std::hex << currentPat << '\n';
- // std::cout << '\n';*/
-
- // if ((int)*(unsigned char *)(pCur + o) != currentPat)
- // {
- // //std::cout << "Cur Val: 0x" << std::hex << (int)*(unsigned char*)(pCur + o) << " Pattern: 0x" << std::hex << currentPat << '\n';
- // break;
- // }
-
- // // o can only be the size of the pattern if it matches
- // if (o == pat.size() - 1)
- // {
- // if (offset < 0)
- // return pCur - offset;
- // if (offset > 0)
- // return pCur + offset;
- // return pCur;
- // }
- // }
- // }
- // }
- // else
- // pCur += mbi.RegionSize;
- // }
- // return NULL;
- // }
-
- static uintptr_t FindSignature(const char *szModule, const char *szSignature)
- {
- //CREDITS: learn_more
- #define INRANGE(x, a, b) (x >= a && x <= b)
- #define getBits(x) (INRANGE((x & (~0x20)), 'A', 'F') ? ((x & (~0x20)) - 'A' + 0xa) : (INRANGE(x, '0', '9') ? x - '0' : 0))
- #define getByte(x) (getBits(x[0]) << 4 | getBits(x[1]))
-
- MODULEINFO modInfo;
- GetModuleInformation(GetCurrentProcess(), GetModuleHandleA(szModule), &modInfo, sizeof(MODULEINFO));
- uintptr_t startAddress = (uintptr_t)modInfo.lpBaseOfDll;
- uintptr_t endAddress = startAddress + modInfo.SizeOfImage;
- const char *pat = szSignature;
- uintptr_t firstMatch = 0;
- for (uintptr_t pCur = startAddress; pCur < endAddress; pCur++)
- {
- if (!*pat)
- return firstMatch;
- if (*(PBYTE)pat == '\?' || *(BYTE *)pCur == getByte(pat))
- {
- if (!firstMatch)
- firstMatch = pCur;
- if (!pat[2])
- return firstMatch;
- if (*(PWORD)pat == '\?\?' || *(PBYTE)pat != '\?')
- //if (*(PWORD)pat == '\?' || *(PBYTE)pat != '\?')
- pat += 3;
- else
- pat += 2; //one ?
- }
- else
- {
- pat = szSignature;
- firstMatch = 0;
- }
- }
- return 0;
- }
- } // namespace PatternScan
|