/** * @file common.cpp * @author Sina Karvandi (sina@rayanfam.com) * @brief HyperDbg general functions for reading and converting and etc * @details * @version 0.1 * @date 2020-05-27 * * @copyright This project is released under the GNU Public License v3. * */ #include "..\hprdbgctrl\pch.h" /** * @brief add ` between 64 bit values and convert them to string * * @param Value * @return string */ string SeparateTo64BitValue(UINT64 Value) { ostringstream OstringStream; string Temp; OstringStream << setw(16) << setfill('0') << hex << Value; Temp = OstringStream.str(); Temp.insert(8, 1, '`'); return Temp; } /** * @brief print bits and bytes for d* commands * * @param size * @param ptr * @return VOID */ VOID PrintBits(size_t const size, void const * const ptr) { unsigned char * b = (unsigned char *)ptr; unsigned char byte; int i, j; for (i = size - 1; i >= 0; i--) { for (j = 7; j >= 0; j--) { byte = (b[i] >> j) & 1; ShowMessages("%u", byte); } ShowMessages(" ", byte); } } /** * @brief general replace all function * * @param str * @param from * @param to * @return VOID */ BOOL Replace(std::string & str, const std::string & from, const std::string & to) { size_t start_pos = str.find(from); if (start_pos == std::string::npos) return FALSE; str.replace(start_pos, from.length(), to); return TRUE; } /** * @brief general replace all function * * @param str * @param from * @param to * @return VOID */ VOID ReplaceAll(string & str, const string & from, const string & to) { size_t SartPos = 0; if (from.empty()) return; while ((SartPos = str.find(from, SartPos)) != std::string::npos) { str.replace(SartPos, from.length(), to); // // In case 'to' contains 'from', like replacing // 'x' with 'yx' // SartPos += to.length(); } } /** * @brief general split command * * @param s target string * @param c splitter (delimiter) * @return const vector */ const vector Split(const string & s, const char & c) { string buff {""}; vector v; for (auto n : s) { if (n != c) buff += n; else if (n == c && buff != "") { v.push_back(buff); buff = ""; } } if (buff != "") v.push_back(buff); return v; } /** * @brief check if given string is a numeric string or not * * @param str * @return BOOLEAN */ BOOLEAN IsNumber(const string & str) { // // std::find_first_not_of searches the string for the first character // that does not match any of the characters specified in its arguments // return !str.empty() && (str.find_first_not_of("[0123456789]") == std::string::npos); } /** * @brief Function to split string str using given delimiter * * @param str * @param delim * @return vector */ vector SplitIp(const string & str, char delim) { int i = 0; vector list; size_t pos; pos = str.find(delim); while (pos != string::npos) { list.push_back(str.substr(i, pos - i)); i = ++pos; pos = str.find(delim, pos); } list.push_back(str.substr(i, str.length())); return list; } /** * @brief check whether the string is hex or not * * @param s * @return BOOLEAN */ BOOLEAN IsHexNotation(string s) { BOOLEAN IsAnyThing = FALSE; for (char & c : s) { IsAnyThing = TRUE; if (!isxdigit(c)) { return FALSE; } } if (IsAnyThing) { return TRUE; } return FALSE; } /** * @brief converts hex to bytes * * @param hex * @return vector */ vector HexToBytes(const string & hex) { vector Bytes; for (unsigned int i = 0; i < hex.length(); i += 2) { std::string byteString = hex.substr(i, 2); char byte = (char)strtol(byteString.c_str(), NULL, 16); Bytes.push_back(byte); } return Bytes; } /** * @brief check and convert string to a 64 bit unsigned integer and also * check for special notations like 0x etc. * * @param TextToConvert the target string * @param Result result will be save to the pointer * * @return BOOLEAN shows whether the conversion was successful or not */ BOOLEAN ConvertStringToUInt64(string TextToConvert, PUINT64 Result) { if (TextToConvert.rfind("0x", 0) == 0 || TextToConvert.rfind("0X", 0) == 0 || TextToConvert.rfind("\\x", 0) == 0 || TextToConvert.rfind("\\X", 0) == 0) { TextToConvert = TextToConvert.erase(0, 2); } else if (TextToConvert.rfind("x", 0) == 0 || TextToConvert.rfind("X", 0) == 0) { TextToConvert = TextToConvert.erase(0, 1); } // // Remove '`' (if any) // TextToConvert.erase(remove(TextToConvert.begin(), TextToConvert.end(), '`'), TextToConvert.end()); if (!IsHexNotation(TextToConvert)) { return FALSE; } const char * Text = TextToConvert.c_str(); errno = 0; unsigned long long result = strtoull(Text, NULL, 16); *Result = result; if (errno == EINVAL) { return FALSE; } else if (errno == ERANGE) { return TRUE; } return TRUE; } /** * @brief check and convert string to a 32 bit unsigned it and also * check for special notations like 0x etc. * @param TextToConvert the target string * @param Result result will be save to the pointer * @return BOOLEAN shows whether the conversion was successful or not */ BOOLEAN ConvertStringToUInt32(string TextToConvert, PUINT32 Result) { if (TextToConvert.rfind("0x", 0) == 0 || TextToConvert.rfind("0X", 0) == 0 || TextToConvert.rfind("\\x", 0) == 0 || TextToConvert.rfind("\\X", 0) == 0) { TextToConvert = TextToConvert.erase(0, 2); } else if (TextToConvert.rfind("x", 0) == 0 || TextToConvert.rfind("X", 0) == 0) { TextToConvert = TextToConvert.erase(0, 1); } TextToConvert.erase(remove(TextToConvert.begin(), TextToConvert.end(), '`'), TextToConvert.end()); UINT32 TempResult; if (!IsHexNotation(TextToConvert)) { return FALSE; } TempResult = stoi(TextToConvert, nullptr, 16); // // Apply the results // *Result = TempResult; return TRUE; } /** * @brief checks whether the string ends with a special string or not * * @param fullString * @param ending * @return BOOLEAN if true then it shows that string ends with another string * and if false then it shows that this string is not ended with the target * string */ BOOLEAN HasEnding(string const & fullString, string const & ending) { if (fullString.length() >= ending.length()) { return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending)); } else { return FALSE; } } /** * @brief Function to validate an IP address * * @param ip * @return BOOLEAN */ BOOLEAN ValidateIP(string ip) { // // split the string into tokens // vector list = SplitIp(ip, '.'); // // if token size is not equal to four // if (list.size() != 4) return FALSE; // // validate each token // for (string str : list) { // // verify that string is number or not and the numbers // are in the valid range // if (!IsNumber(str) || stoi(str) > 255 || stoi(str) < 0) return FALSE; } return TRUE; } /** * @brief Detect whether the VMX is supported or not * * @return true if vmx is supported * @return false if vmx is not supported */ BOOLEAN VmxSupportDetection() { // // Call asm function // return AsmVmxSupportDetection(); } /** * @brief SetPrivilege enables/disables process token privilege * * @param hToken * @param lpszPrivilege * @param bEnablePrivilege * @return BOOL */ BOOL SetPrivilege(HANDLE hToken, // access token handle LPCTSTR lpszPrivilege, // name of privilege to enable/disable BOOL bEnablePrivilege // to enable or disable privilege ) { TOKEN_PRIVILEGES tp; LUID luid; if (!LookupPrivilegeValue(NULL, // lookup privilege on local system lpszPrivilege, // privilege to lookup &luid)) // receives LUID of privilege { ShowMessages("err, in LookupPrivilegeValue (%x)\n", GetLastError()); return FALSE; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; // // Enable the privilege or disable all privileges. // if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) { ShowMessages("err, in AdjustTokenPrivileges (%x)\n", GetLastError()); return FALSE; } if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) { ShowMessages("err, the token does not have the specified privilege\n"); ShowMessages("make sure to run it with administrator privileges\n"); return FALSE; } return TRUE; } /** * @brief trim from start of string (in place) * * @param s */ static inline void ltrim(std::string & s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) { return !std::isspace(ch); })); } /** * @brief trim from the end of string (in place) * * @param s */ static inline void rtrim(std::string & s) { s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) { return !std::isspace(ch); }) .base(), s.end()); } /** * @brief trim from both ends and start of a string (in place) * * @param s */ void Trim(std::string & s) { ltrim(s); rtrim(s); } /** * @brief Remove all the spaces in a string * * @param str */ std::string RemoveSpaces(std::string str) { str.erase(remove(str.begin(), str.end(), ' '), str.end()); return str; } /** * @brief check if a file exist or not (ASCII) * * @param FileName path of file * @return BOOLEAN shows whether the file exist or not */ BOOLEAN IsFileExistA(const char * FileName) { struct stat buffer; return (stat(FileName, &buffer) == 0); } /** * @brief check if a file exist or not (wide-char) * * @param FileName path of file * @return BOOLEAN shows whether the file exist or not */ BOOLEAN IsFileExistW(const wchar_t * FileName) { struct _stat64i32 buffer; return (_wstat(FileName, &buffer) == 0); } /** * @brief Is empty character * * @param Text */ BOOLEAN IsEmptyString(char * Text) { if (Text == NULL || Text[0] == '\0') { return TRUE; } for (size_t i = 0; i < strlen(Text); i++) { if (Text[i] != ' ' && Text[i] != '\t' && Text[i] != ' \n') { return FALSE; } } return TRUE; } /** * @brief Get config path * * @param ConfigPath */ VOID GetConfigFilePath(PWCHAR ConfigPath) { WCHAR CurrentPath[MAX_PATH] = {0}; // // Get path file of current exe // GetModuleFileNameW(NULL, CurrentPath, MAX_PATH); // // Remove exe file name // PathRemoveFileSpecW(CurrentPath); // // Combine current exe path with config file name // PathCombineW(ConfigPath, CurrentPath, CONFIG_FILE_NAME); }