#pragma once #include #include #include #include #include #include #include #include #pragma comment(lib, "urlmon.lib") #pragma comment(lib, "Wininet.lib") using namespace std; #ifndef typeof #define typeof(x) decltype(x) #endif // !typeof #ifndef PROPERTY #define PROPERTY(t,n) __declspec( property (put = property__set_##n, get = property__get_##n)) t n #define READONLY_PROPERTY(t,n) __declspec( property (get = property__get_##n) ) t n #define WRITEONLY_PROPERTY(t,n) __declspec( property (put = property__set_##n) ) t n #define GET(t,n) t property__get_##n() #define SET(t,n) void property__set_##n(const t& value) #endif // !PROPERTY #ifndef ENCRYPT_SYSTEM_TYPE #define ENCRYPT_SYSTEM_TYPE(type,name)\ unsigned long long _##name;\ PROPERTY(type, name);\ GET(type, name)\ {\ unsigned long long tmpval = _##name ^ ((unsigned long long)&_##name);\ type result;\ memcpy(&result, &tmpval, sizeof(result));\ return result;\ }\ SET(type, name)\ {\ unsigned long long tmpval = 0;\ memcpy(&tmpval, &value, sizeof(value));\ _##name = tmpval ^ ((unsigned long long)&_##name);\ } #endif // !ENCRYPT_SYSTEM_TYPE #ifndef _IMAGE_DEBUG_DIRECTORY_RAW_ #define _IMAGE_DEBUG_DIRECTORY_RAW_ typedef struct _IMAGE_DEBUG_DIRECTORY_RAW { uint8_t format[4]; uint8_t PdbSignature[16]; uint32_t PdbDbiAge; uint8_t ImageName[256]; const char* GuidString() { char buf[128]; sprintf_s(buf, "%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X", this->PdbSignature[3], this->PdbSignature[2], this->PdbSignature[1], this->PdbSignature[0], this->PdbSignature[5], this->PdbSignature[4], this->PdbSignature[7], this->PdbSignature[6], this->PdbSignature[8], this->PdbSignature[9], this->PdbSignature[10], this->PdbSignature[11], this->PdbSignature[12], this->PdbSignature[13], this->PdbSignature[14], this->PdbSignature[15] ); return buf; } } IMAGE_DEBUG_DIRECTORY_RAW, * PIMAGE_DEBUG_DIRECTORY_RAW; #endif #pragma region TPattern class TPattern { std::string sMask; std::string sPattern; std::vector bytes; bool bIdaStyle = false; private: void Parse() { if (bIdaStyle) { ParsePatternIDA(); } else { ParsePattern(); } } void ParsePattern() { auto uLen = sMask.length(); for (uint32_t i = 0; i < uLen; i++) { if (i < uLen && sPattern[i] == 0) { sPattern[i] = (char)0xFF; } if (sMask[i] == '?') { bytes.push_back(0); } else { auto sub = sPattern.substr(i, 1); auto byte = uint8_t(sub[0]); bytes.push_back(byte); } } } void ParsePatternIDA() { auto uLen = sPattern.length(); sMask.clear(); int b = 0; char x, byteBuf = 0; for (uint32_t i = 0; i < uLen; i++) { char c = (char)sPattern[i]; if (c >= '0' && c <= '9') { x = (0x0F & c); byteBuf += (b) ? x : x << 4; b++; } else if (c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f') { if (c > 0x46) { c -= 0x20; } x = c - 0x37; byteBuf += (b) ? x : x << 4; b++; } else if (c == '?') { if (sPattern[i + 1] == '?') { i++; } bytes.push_back(0); sMask += '?'; } if (b > 1) { bytes.push_back(byteBuf); b = 0; byteBuf = 0; sMask += 'x'; } } } public: TPattern(const char* sPattern) { bIdaStyle = true; this->sPattern = sPattern; Parse(); } TPattern(const char* sPattern, const char* sMask) { this->sMask = sMask; bytes.resize(this->sMask.length()); memcpy(&bytes[0], sPattern, bytes.size()); Parse(); } std::vector Get() { return bytes; } std::string GetMask() { return sMask; } size_t Size() { return bytes.size(); } }; static void* Scan(void* pAddress, size_t size, TPattern* pattern) { auto pat = pattern->Get(); auto mask = pattern->GetMask(); uint8_t* pByte = (uint8_t*)pAddress; size_t j = 0; for (size_t i = 0; i < size; i++) { if (IsBadReadPtr(pByte + i, pat.size())) { continue; } if (pByte[i] == pat[j] || mask[j] == '?') { j++; if (j == pat.size() - 1) { return (void*)((uintptr_t)pByte + i - pat.size() + 2); } } else { j = 0; } } return nullptr; } static void* ScanPattern(const char* szModule, const char* sPattern) { TPattern* pattern = new TPattern(sPattern); OutputDebugStringA(pattern->GetMask().c_str()); MODULEINFO mi{ }; GetModuleInformation(GetCurrentProcess(), GetModuleHandleA(szModule), &mi, sizeof(mi)); LPVOID dwBaseAddress = mi.lpBaseOfDll; const auto dwModuleSize = mi.SizeOfImage; return Scan(dwBaseAddress, dwModuleSize - pattern->Size(), pattern); } template T FindPattern(const char* szModule, std::string pattern, DWORD_PTR SizeOfImage = NULL) { #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])) HMODULE hModule = GetModuleHandleA(szModule); const char* pat = pattern.c_str(); DWORD_PTR firstMatch = 0; DWORD_PTR rangeStart = (T)hModule; MODULEINFO miModInfo; if (!SizeOfImage) GetModuleInformation(GetCurrentProcess(), hModule, &miModInfo, sizeof(MODULEINFO)); DWORD_PTR rangeEnd = SizeOfImage ? rangeStart + SizeOfImage : rangeStart + (DWORD_PTR)miModInfo.SizeOfImage; for (DWORD_PTR pCur = rangeStart; pCur < rangeEnd; pCur++) { if (!*pat) return (T)firstMatch; if (*(PBYTE)pat == '\?' || *(BYTE*)pCur == getByte(pat)) { if (!firstMatch) firstMatch = pCur; if (!pat[2]) return (T)firstMatch; if (*(PWORD)pat == '\?\?' || *(PBYTE)pat != '\?') pat += 3; else pat += 2; //one ? } else { pat = pattern.c_str(); firstMatch = 0; } } return NULL; } #pragma endregion static char* TCHAR2char(const wchar_t* STR) { int size = WideCharToMultiByte(CP_ACP, 0, STR, -1, NULL, 0, NULL, FALSE); char* str = new char[sizeof(char) * size]; WideCharToMultiByte(CP_ACP, 0, STR, -1, str, size, NULL, FALSE); return str; } static wchar_t* Char2TCHAR(const char* _char) { int iLength; iLength = MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, NULL, 0); wchar_t* tchar = new wchar_t[sizeof(wchar_t) * iLength]; MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, tchar, iLength); return tchar; } static string wstring_to_string(wstring s) { return string(TCHAR2char(s.c_str())); } static wstring string_to_wstring(string s) { return wstring(Char2TCHAR(s.c_str())); } static char* ToHex(const char* data, size_t len) { const char* key = "0123456789ABCDEF"; char* result = new char[(len * 2) + 1]; result[(len * 2)] = '\0'; for (int i = 0; i < len; i++) { result[i * 2] = key[((unsigned char)data[i]) / 0x10]; result[(i * 2) + 1] = key[((unsigned char)data[i]) % 0x10]; } return result; } static char* ToHex(const BYTE* data, size_t len) { const char* key = "0123456789ABCDEF"; char* result = new char[(len * 2) + 1]; for (int i = 0; i < len; i++) { result[i * 2] = key[((unsigned char)data[i]) / 0x10]; result[(i * 2) + 1] = key[((unsigned char)data[i]) % 0x10]; } result[len * 2] = '\0'; return result; } static vector ParseHex(const char* hex) { vector result = vector(); int len = strlen(hex); BYTE* buffer = new BYTE[len]; bool ish = true; BYTE val = 0; for (int i = 0; i < len; i++) { bool isval = false; BYTE v = 0; if (hex[i] >= '0' && hex[i] <= '9') { v = (hex[i] - '0'); isval = true; } else if (hex[i] >= 'A' && hex[i] <= 'F') { v = 10 + (hex[i] - 'A'); isval = true; } else if (hex[i] >= 'a' && hex[i] <= 'f') { v = 10 + (hex[i] - 'a'); isval = true; } if (isval) { if (ish) { val = (v << 4) | val; } else { val = v | val; result.push_back(val); val = 0; } ish = !ish; } } return result; } static initializer_list* ReadAllBytes(const char* filePath) { HANDLE pFile; DWORD fileSize; char* buffer, * tmpBuf; DWORD dwBytesRead, dwBytesToRead, tmpLen; pFile = CreateFileA(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (pFile == INVALID_HANDLE_VALUE) { CloseHandle(pFile); return nullptr; } fileSize = GetFileSize(pFile, NULL); buffer = (char*)malloc(fileSize); if (!buffer) { return nullptr; } ZeroMemory(buffer, fileSize); dwBytesToRead = fileSize; dwBytesRead = 0; tmpBuf = buffer; do { if (!ReadFile(pFile, tmpBuf, dwBytesToRead, &dwBytesRead, NULL) || dwBytesRead == 0) break; dwBytesToRead -= dwBytesRead; tmpBuf += dwBytesRead; } while (dwBytesToRead > 0); CloseHandle(pFile); return new initializer_list(&buffer[0], &buffer[fileSize]); } static BOOL WriteAllBytes(const char* filePath, char* buffer, int len) { HANDLE pFile; char* tmpBuf; DWORD dwBytesWrite, dwBytesToWrite; pFile = CreateFileA(filePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (pFile == INVALID_HANDLE_VALUE) { CloseHandle(pFile); return FALSE; } dwBytesToWrite = len; dwBytesWrite = 0; tmpBuf = buffer; do { WriteFile(pFile, tmpBuf, dwBytesToWrite, &dwBytesWrite, NULL); dwBytesToWrite -= dwBytesWrite; tmpBuf += dwBytesWrite; } while (dwBytesToWrite > 0); CloseHandle(pFile); return TRUE; } static BOOL WriteAllBytes(const char* filePath, BYTE* buffer, int len) { return WriteAllBytes(filePath, (char*)buffer, len); } static BOOL WriteAllBytes(const char* filePath, vector buffer) { return WriteAllBytes(filePath, (char*)buffer.data(), buffer.size()); } static BOOL WriteAllBytes(const char* filePath, initializer_list buffer) { return WriteAllBytes(filePath, (char*)buffer.begin(), buffer.size()); } static BOOL WriteAllBytes(const char* filePath, initializer_list buffer) { return WriteAllBytes(filePath, (char*)buffer.begin(), buffer.size()); } static BOOL WriteAllText(const char* filePath, const char* text) { return WriteAllBytes(filePath, (char*)text, strlen(text)); } static vector HttpRequest(const char* url) { #define MAXSIZE 4096 vector result = vector(); BYTE* val = new BYTE[MAXSIZE]; ULONG len = 1; HINTERNET hSession = InternetOpenA(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hSession != NULL) { HINTERNET hHttp = InternetOpenUrlA(hSession, url, NULL, 0, INTERNET_FLAG_DONT_CACHE, 0); if (hHttp != NULL) { while (len > 0) { InternetReadFile(hHttp, val, MAXSIZE - 1, &len); if (len > 0) { int ldx = result.size(); result.resize(result.size() + len); memcpy(&result.operator[](ldx), &val[0], len); } } InternetCloseHandle(hHttp); hHttp = NULL; } InternetCloseHandle(hSession); hSession = NULL; } return result; } static string WebRequest(const char* url) { #define BLOCK_READ 4096 IStream* stream; HRESULT result = URLOpenBlockingStreamA(0, url, &stream, 0, 0); if (result != 0) { return ""; } char buffer[BLOCK_READ]; unsigned long bytesRead; stringstream ss; stream->Read(buffer, BLOCK_READ, &bytesRead); while (bytesRead > 0U) { ss.write(buffer, (long long)bytesRead); stream->Read(buffer, BLOCK_READ, &bytesRead); } stream->Release(); return ss.str(); } static BYTE* _get_jmp_address(BYTE* ptr) { if (*ptr == 0xE9) { return (ptr + 5) + (*(UINT32*)&ptr[1]); } return ptr; } static int _get_index(BYTE* ptr) { if (*(UINT16*)ptr == 0x20FF) { return 0; } if (*(UINT16*)ptr == 0x60FF) { return ptr[2] / sizeof(void*); } if (*(UINT16*)ptr == 0xA0FF) { return *(UINT32*)&ptr[2] / sizeof(void*); } return -1; } template static int GetVTableIndex(T funcaddr) { void* proc = (void*&)funcaddr; BYTE* addr = _get_jmp_address((BYTE*)proc); for (int i = 0; i < 32; i++) { if (addr[i] == 0xFF) { auto dx = _get_index(&addr[i]); if (dx >= 0) return dx; } } return -1; } static POINT GetMousePos(HWND Hwnd) { POINT p; GetCursorPos(&p); ScreenToClient(Hwnd, &p); return p; } static bool InRect(POINT point, POINT LOC, SIZE SIZ) { int xf = point.x - LOC.x; int yf = point.y - LOC.y; return xf >= 0 && xf <= SIZ.cx && yf >= 0 && yf <= SIZ.cy; }