PDA

Просмотр полной версии : Mail.ru SMS sender


Gar|k
05.08.2009, 16:14
Пишем альтернативный клиент


ВВЕДЕНИЕ:
После того как я выложил в паблик Mail.ru Spam base generator (http://forum.antichat.ru/threadnav114112-1-10.html) меня многие просили выложить исходник или хотя бы рассказать как работать с MMP протоколом. Собственно этому и будет посвящен этот пост, а чтобы было еще интереснее я опишу, как отравлять СМС используя протокол.
Ассемблер я выбрал не случайно, так как надеюсь, что он отпугнет неверных :)

АЛГОРИТМ:
Протокол довольно хорошо описан самими разработчиками (http://agent.mail.ru/ru/developers/protocol.html).
После установки соединения сервер постоянно посылает пакеты, которые клиент должен успевать обрабатывать и адекватно отвечать. Прием и отправка должны происходить асинхронно, а на блокируемых сокетах подобное можно реализовать лишь используя многопоточность.

Я опишу принцип работы моего клиента, остальное можно будет понять из комментариев к коду.

Получаем адрес рекомендуемого сервера MMP по адресу mrim.mail.ru:2042 он передается в текстовом формате ip : port
Подключаемся к серверу и создаем поток отправки и приема.

Потоки синхронизируется событиями.
Поток отправки представляет из себя процедуру, которая ждет появления события отправки и отправляет заголовок пакета и нужно данные расположенные в общем буфере. Заголовок и данные для отправки заполняются предварительно.
Поток приема представляет из себя бесконечный цикл, который постоянно принимает и анализирует заголовки отправленные сервером.


Отправляем MRIM_CS_HELLO
Получаем MRIM_CS_HELLO_ACK и создаем поток пинга, который через указанный в пакете интервал отправляет MRIM_CS_PING.
Посылаем MRIM_CS_LOGIN2. Mail.ru Agent отправляет очень странный пакет, полностью который разобрать мне так и не удалось, а все мои попытки самостоятельно сформировать MRIM_CS_LOGIN2 оказывались неудачными, поэтому я просто скопировал часть дампа )
В случае успешной авторизации сервер присылает MRIM_CS_LOGIN_ACK и MRIM_CS_LOGIN_REJ в случае неудачи.
После авторизации необходимо принять полностью MRIM_CS_USER_INFO и только после этого отправлять свои данные. Все мои попытки отправлять запросы сразу после MRIM_CS_LOGIN_ACK заканчивались неудачей.

СМС:
Эта возможность никак не освещена в официальной документации, но стоит немножко поснифать...
EFBEADDE
12000100
DD711940
39100000 команда 0x1039 отправка смс
2E000000 длина сообщения

00000000
00000000
00000000
00000000
00000000
00000000


00000000

lps номер телефона кому

0C000000
2B3739313233353435363731 // +79123545671

lps сообщение в UNICODE

16000000

67006100720069006B0020006D007500740069007400 // garik mutit
После успешной отправки сервер присылает пакет 0x1040, а в случае неудачи MRIM_CS_MESSAGE_ACK в котором красиво написано почему, не ушла СМС.

WWW:
Для тех, кто хочет понять, как вообще это все работает, я рекомендую почитать:
http://www.wasm.ru/publist.php?list=1
http://www.insidepro.com/kk/006/006r.shtml

P.S

Автор не несет ответственности за возможно последующие брут форсы email (пока тестировал сервер даже не ругнулся, что я так часто подключаюсь), генераторы спам баз на основе MRIM_CS_WP_REQUEST, спамерские рассылки СМС и MRIM_CS_MESSAGE, и распространение червей через MRIM_CS_FILE_TRANSFER ;)

Приложение А
Текст программы

К сожелению она получилась настолько здоровая, что тупо не умещается в пост ) поэтому вот ссылочки:
mra.inc (http://zona-chat.narod.ru/smssend/mra.inc), string.inc (http://zona-chat.narod.ru/smssend/string.inc), sms.asm (http://zona-chat.narod.ru/smssend/sms.asm)

Приложение Б
Контрольный пример работы программы

http://zona-chat.narod.ru/smssend/sms.jpg
Рисунок Б.1 – Главное окно программы


Кому лень компилировать, можете посмотреть сразу как все это работает sms.exe (http://zona-chat.narod.ru/smssend/sms.exe) (7168 байт). Лично у меня антивить ругается, что это "TR/Crypr.XPACK.Gen", эх зналбы он что это просто асм программа, труд 3х ночей )

ex3me
05.08.2009, 16:43
Отлично =)
На делфи вариант только не выкладывай, ибо начнется массовая продажа СМС-спамеров через м.ру

Gar|k
05.08.2009, 16:51
2 ex3me, не бойся я делфи знаю на уровне школьника :)

ex3me
05.08.2009, 16:56
Gar|k, кстати у меня тоже орет Авира на XPACK, может пару левых модулей еще подключить? :D

З.Ы. Значит я не буду выкладывать вариант отсылки на Delphi :D

Gar|k
30.08.2009, 13:25
ну че ктонить написал спаммер? ))

AKYLA
05.09.2009, 00:55
Gar|k
А как же ))) осталось только побороть 50 смс в сутки, путем использования множества аков и синхронизации оных )) и будет около 2500 смс за сутки ))
Только здаеться мне, маил.ру прикроет дыру в виде возможности отправки без добавления в список контактов.

_nic
05.09.2009, 01:26
На Украину шлет?

buxmanager
05.09.2009, 02:03
а на украину не отправляет....((((((((

warlok
05.09.2009, 02:07
а на украину не отправляет....((((((((
я пробывал на MTC укр все доходило)

nonamez
05.09.2009, 02:13
а куда кроме раши и укр шлет?

buxmanager
05.09.2009, 02:32
я пробывал на MTC укр все доходило)

а на лайф чето не идут, может подскажешь как ты отправил) ? осемь-девять-88-семь-шесть стукни плиз

AKYLA
05.09.2009, 04:32
Все на Украину шлет (там только и тестил)
На лайф идет на ура, на МТС иногда с задержками, на Киевстар и Диджус не идет (но там помоему система что надо чтоб владелец, дал разрешение на принятие смс с инета).
П.С. Эта прога тоже шлет нормально, но там часто траблы и она грузит проц на 100%, вообщем имеется ввиду что писал я не на асме конечно, а эти исходники только для интереса по изучал и потестил, развивать дальше на асме слишком для меня геморно )) :D

Keltos
05.09.2009, 07:10
а бляйн как?

0rs
05.09.2009, 10:00
А не лучше ли сделать вместо

.ww:
invoke WaitForSingleObject, [hSend], 150
cmp eax, WAIT_OBJECT_0
jne .ww

Вот так:

invoke WaitForSingleObject, [hSend], INFINITE

И еще здесь у меня происходит зависание потока со 100% загрузкой процессора. В какой-то момент recv начинает возвращать 0 и образуется бесконечный цикл.

.ww: ; пока не примем хоть какойто вменяемый пакетик будем крутить цикл )
cmp [s.msg], 0
jne @F
invoke recv, [sock], s, 44, 0
jmp .ww

Gar|k
05.09.2009, 13:07
2 0rs
эмм WaitForSingleObject, [hSend], 150 делает задержку в 150 милисекунд, попробуй поставить 0 и увидишь как быстро скушается все ресурсы процессора...
INFINITE делает вечный цикл... тогда уж проще написать пока один равно один :)

а вот как ты верно заметил с определением начала пакета у меня косяк... я вот реально незнаю как найти начало пакета... может цикл приема по 4 байта и сравнение его с magic num пакета - это решение, нужно попробывать...

Gar|k
05.09.2009, 13:10
нащет того куда уходят смски
Россия
МТС, БиЛайн, Соник Дуо (Мегафон г. Москва), Мобиком - Кавказ, Урал - GSM, Мегафон (СЗФ), Мобиком - Новосибирск, МСС - Поволжье, Мобиком - Хабаровск, Мобиком - Центр, НСС (Нижегородск. Сот. Св.), Астрахань GSM, Мотив, НТК, Utel, Ульновск GSM, Енисей Телеком, Алтай-Связь, Мобиком - Центр (Северный филиал), Мобиком - Центр (Южный филиал). Tele2 (Санкт-Петербург, Ленинградская обл., Архангельская обл., Мурманская обл., Новгородская обл., Республика Коми, Смоленская обл., Курская обл., Воронежская обл., Белгородская обл., Липецкая обл., Брянская обл., Нижегородская обл., Ростовская обл., Краснодарский край, Удмуртская республика, Челябинская обл., Омская обл., Кемеровская обл., Томская обл., Новосибирская обл., Тульская обл., Тамбовская обл., Тверская обл.)

Казахстан
KCell, Beeline, Neo

Узбекистан
МТС-Узбекистан

Украина
Life:), Билайн, МТС

buxmanager
05.09.2009, 16:45
интересно, а у меня пишет в ком строке что отправка пакета при нажатии отправить , но смс не отправляется и никакой реакции..... чтоможет быть?

0rs
05.09.2009, 16:46
В данном случае WaitForSingleObject с таймером 150 и проверкой WAIT_OBJECT_0 делает тоже самое что и WaitForSingleObject с INFINITE. После вызова SetEvent программа в любом случае выйдет из WaitForSingleObject с кодом WAIT_OBJECT_0.
На счет начала пакета: разве новый пакет не начинается после того как заканчивается предыдущий? Или проблема в том чтобы определить момент, когда сервер отослал нам новый пакет, тогда можно попробовать WSASetEvent.

Gar|k
05.09.2009, 20:39
0rs данные идут в потоке, тоесть в одном TCP/IP пакете от сервера может быть 2-3 и тд пакета MMP. Загвоздка в определении начала пакета - чтобы принять заголовок и узнать длинну пакета MMP. В общем нужно придумать правильную обработку приема... тогда все встанет на свои места.

Gar|k
05.09.2009, 20:45
2 buxmanager в mail.ru множество ограничений на отправку смс, временные интервалы, лимит сообщений, неверные номера. Я лишь привел пример, как можно написать клиент. По хорошему еще нужно доработать:

1. Правильный прием данных с сервера
2. Проверку в самом приложении номера телефона, длины сообщения (если сформировать не верный пакет, он естественно ничего не вернет)
3. Обработку ошибок - ответов от сервера.

+ я думаю приложение получится более правильным если использовать изначально ассинхронные сокеты, но тогда теряется кросплатформенность (если писать на Си конечно)

buxmanager
05.09.2009, 21:55
указал номер верно, указал текст верно) и дулька)))

AKYLA
05.09.2009, 23:52
Gar|k
А можно детальнее про временные интервалы, кроме одной минуты и 50 смс в день?

Gar|k
06.09.2009, 01:13
AKYLA, когда я в прошлом году сделал этот клиент я попробывал написать рассылку, но тут же столкнулся с проблемой минутного интервала. Писать обработку сообщений сервера мне было лень и я забросил эту идею. Попробуй, потестируй, погляди что возвращает сервер, обычно это сообщение (1036 вроде) в котором текстом в rtf объясняется причина по которой СМС не может быть доставлена.

buxmanager
06.09.2009, 02:23
так почему не отправляется то? не могу понять:) извините за непонимание, но все верно указываю!

AKYLA
06.09.2009, 05:32
Gar|k
Ну я пока нашел ограничения это - минута, через 10 сообщений если тебе не отвечает абонент так же смс'кой то ты блокируешься на 24 часа. (хитро придумано, ведь ответные смс с тела на агент платные )))
Тесты показали, если с нового ака маил.ру пытаться отправить, ничего не будет, для этого обязательно нужно в контакты занести хотя бы один контакт с номером (потом его можно и удалить) и только тогда будет возможность отсылать без маил агента.

buxmanager
06.09.2009, 11:45
Gar|k
Ну я пока нашел ограничения это - минута, через 10 сообщений если тебе не отвечает абонент так же смс'кой то ты блокируешься на 24 часа. (хитро придумано, ведь ответные смс с тела на агент платные )))
Тесты показали, если с нового ака маил.ру пытаться отправить, ничего не будет, для этого обязательно нужно в контакты занести хотя бы один контакт с номером (потом его можно и удалить) и только тогда будет возможность отсылать без маил агента.

понятно почему не отправлялосЬ))))

_nic
01.11.2009, 22:57
Gar|k
Ну я пока нашел ограничения это - минута, через 10 сообщений если тебе не отвечает абонент так же смс'кой то ты блокируешься на 24 часа. (хитро придумано, ведь ответные смс с тела на агент платные )))
Тесты показали, если с нового ака маил.ру пытаться отправить, ничего не будет, для этого обязательно нужно в контакты занести хотя бы один контакт с номером (потом его можно и удалить) и только тогда будет возможность отсылать без маил агента.
А какие ещё есть ограничения?На номер телефона,айпи,или номер мобилы и айпи?

ky_kask
28.02.2010, 07:19
"Бороть" 50 СМС в сутки или 1 минуту не надо. В 1 поток быстрее чем 1 СМС в секунду не отшлешь. Решение - Вешаем 1К акков и вперед. По одному на секунду в цикле 50.
Добавление/удаление телефона в контакты не нужно. Для отправки СМС нужно чтобы хотя бы в один контакт был добавлен номер телефона. Решение - добавляем любой "левый" номер в контакт Support (по умолчанию он у любого акка есть), а потом шлем СМС на любой нужный номер. Вот этот самый номер в контакты можно не писать. Все равно отправляет. Можно добавить проверку на наличие номеров в контактах акка, тогда вообще остается только отправить СМС-ку безо всяких добавлений. ИП вроде не "палится", но это надо массово проверять..

Удачных экспериментов.

_nic
28.02.2010, 18:27
У меня ип от таких приколов в бан на 3е суток уходил где то на 15 - 20й смске

greki_hoy
18.03.2010, 13:29
Gar|k как думаеш это пдойдет для асинхронных ответов серверу ?
отбработки ошибок нет для наглядности



typedef struct THREAD_INFO
{
CONST PCHAR pMsg;
HANDLE hCompleteInit;
} THREAD_INFO, *PTHREAD_INFO;

DWORD WINAPI SendThread(PTHREAD_INFO th)
{
SOCKET s;
PCHAR pMsg = malloc(strlen(th->pMsg)+1);
strcpy(pMsg, th->pMsg);
SetEvent(th->hCompleteInit); /* SendMsg выходиь из ожидания и завершается */
s = conct(MmpAddr); /* connect */
send(s, pMsg, strlen(pMsg), 0);
free(pMsg);
closesocket(s);
return ERROR_SUCCESS;
}

VOID SendMsg(CONST PCHAR pMsg)
{
HANDLE hThread;
THREAD_INFO th = {pMsg};
th.hCompleteInit = CreateEvent(NULL, FALSE, FALSE, NULL);
hThread = CreateThread(NULL, 0, SendThread, &th, 0, NULL);
WaitForSingleObject(th.hCompleteInit, INFINITE);
CloseHandle(th.hCompleteInit);
CloseHandle(hThread);
}



идея такая чтоб если надо часто отправлять ответы количество одновременно работающих потоков увеличивалось все равно они все на вводе выводе приостановятся чтоб отправлять за раз много ответов а когда запросы нечастые нет ни одного потока
крутил крутил как сделать получилось это затраты на создание структур ядра потока и помещение его в очередь небольшие но все равно мне не нравится решение с постоянным созданием потоков сначал думал держать поток на событии но потом прикинул что мне надо например 10 потоков отправляли одновремено 10 событий ?
1 если собитые то или один поток проснется если с автосбросом или все если с ручным сбросом один если просыпатся будет неподходит так как отправка тогда не асинхронно будет выполнятся все тоже не пойдет если я передаю один запрос всего в минуту да и вот еще что допустим из какого то потока вызов SendMsg("MRIM_CS_HELLO"); так как вызов асихронный то она вернет управление и выйдет из функции ее вызывавшей буфер разрушится когда поток получит время начнет отсылать и прочитает из стека черти что поэтому пришлось сделать так
тут блокируем вызывабщий поток пока поток когда получит время не скопирует себе строку в кучу

th.hCompleteInit = CreateEvent(NULL, FALSE, FALSE, NULL);
hThread = CreateThread(NULL, 0, SendThread, &th, 0, NULL);
WaitForSingleObject(th.hCompleteInit, INFINITE);

а поток когда проснется первым делом скопирует строку

PCHAR pMsg = malloc(strlen(th->pMsg)+1);
strcpy(pMsg, th->pMsg);
SetEvent(th->hCompleteInit);

маякнет вызывающему потоку что он закончил тот выйдет из вызова
SendMsg("MRIM_CS_HELLO");
и можно уже не опасатся из какого контекста вызывалась функция фактически только задержка на событии для копирования строки получается но мне это не нравится как то есть идеи как лучше отправку организовать ?
еще вариант с пулом поколдовать там хоть не надо создавать треды так часто
QueueUserWorkItem
в коде фактически придется только заменить CreateThread на QueueUserWorkItem
наверно эффективней должно быть хоть потоки завершатся не будут
набрел на твою статью решил поигратся с протоколом )))
кстати запости заголовок пакета которые отправляются перед сообщением который а то у меня маил агентов нет а ставить че то как то не очень то и надо ))
фактически вот сразу попробовал решение с пулом потоков вот что получилось



typedef struct THREAD_INFO
{
CONST PCHAR pMsg;
HANDLE hCompleteInit;
} THREAD_INFO, *PTHREAD_INFO;

DWORD WINAPI SendThread(PTHREAD_INFO th)
{
SOCKET s;
PCHAR pMsg = malloc(strlen(th->pMsg)+1);
strcpy(pMsg, th->pMsg);
SetEvent(th->hCompleteInit);
s = conct(MmpAddr);
send(s, pMsg, strlen(pMsg), 0);
free(pMsg);
closesocket(s);
return ERROR_SUCCESS;
}

VOID SendMsg(CONST PCHAR pMsg)
{
THREAD_INFO th = {pMsg};
th.hCompleteInit = CreateEvent(NULL, FALSE, FALSE, NULL);
QueueUserWorkItem(SendThread, &th,
WT_EXECUTEDEFAULT|WT_EXECUTELONGFUNCTION);
WaitForSingleObject(th.hCompleteInit, INFINITE);
CloseHandle(th.hCompleteInit);
}



работает много параллельных запросов из пула данные тоже корректно на событии
копируются вызывающий поток который хочеит отправить сообщение ждет только
пока потоку в пуле выделится время он скопирует пакет себе в память и тут же освобождает поток который хочет отправить сообщение
уже что то ))

есть мысли как сделать лучше ?))

Gar|k
18.03.2010, 20:06
greki_hoy o_O :)

посмотри это (http://forum.antichat.ru/thread170703.html)
массив сокетов и те же потоки приема и отправки. (сейчас понимаю что прием лучше было бы реализовать через select)

А вообще обмен с клиентом идет асинхронно... и стоит задуматься не проще ли использовать асинхронные сокеты? ) (я с ними никогда не работал... статейка так ничего (http://www.realcoding.net/article/view/1833))

Вон прочитай выше статью и обрати внимание на описание WSAEventSelect. Я удмаю реально запихнуть весь клиент в одну функцию, а потом просто делать много потков на нее основе.

Leon2009
18.03.2010, 22:21
а есть на короткие намера? отправлять отправляю а принимать то незнаю как?

Life7
19.03.2010, 17:59
я пробывал на MTC укр все доходило)


на киевстар не доходит