Ru-MaNGOS

Вернуться   Ru-MaNGOS > Ядро > Опкоды, Формулы, Клиент

Важная информация

Опкоды, Формулы, Клиент Разбор и изучение взаимодействия клиента с сервером

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 01.06.2010, 18:25   #41
RomanRom2
WowCore Dev
 
Аватар для RomanRom2
 
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
RomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всем
По умолчанию

прокси не будет работать с батлнетом, сколько не старайтесь. не тратьте время.
надо либо pcap, либо инжектор, либо lsp. pcap по проще.

Цитата:
Сообщение от YuruY Посмотреть сообщение
ну мы же раздавали сниферы, и снифы выкладывали. как показала практика пользы всем не будет. а только больше геморроя сниферописателям. все тупо садятся на шею и орут "дай еще, дай новую версию, дай дай дай". снифами никто не делится. а снифер подавай. увы, опыт отрицательный.

но все это фигня легко переживаемая по сравнением с тем, что паблик сниффер может стать гвоздем в заднице. баном на оффе по меньшей мере.
RomanRom2 вне форума   Ответить с цитированием
Старый 01.06.2010, 18:32   #42
YuruY
YTDB Dev
 
Аватар для YuruY
 
Регистрация: 01.02.2010
Сообщений: 288
Сказал(а) спасибо: 125
Поблагодарили 97 раз(а) в 53 сообщениях
YuruY Скоро придёт к известностиYuruY Скоро придёт к известности
По умолчанию

Цитата:
ну мы же раздавали сниферы, и снифы выкладывали. как показала практика пользы всем не будет. а только больше геморроя сниферописателям. все тупо садятся на шею и орут "дай еще, дай новую версию, дай дай дай". снифами никто не делится. а снифер подавай. увы, опыт отрицательный.

но все это фигня легко переживаемая по сравнением с тем, что паблик сниффер может стать гвоздем в заднице. баном на оффе по меньшей мере.
.....
Цитата:
но всем подряд его раздавать не стоит, чтобы не ...
__________________
http://ytdb.ru/
http://svn2.assembla.com/svn/ytdbase/
YuruY вне форума   Ответить с цитированием
Старый 01.06.2010, 18:41   #43
Neverdie
Kobold Dev
 
Аватар для Neverdie
 
Регистрация: 11.03.2010
Сообщений: 22
Сказал(а) спасибо: 5
Поблагодарили 3 раз(а) в 3 сообщениях
Neverdie На верном пути
Отправить сообщение для Neverdie с помощью ICQ
По умолчанию

Цитата:
Сообщение от YuruY Посмотреть сообщение
Я и предложил вам объедениться, а не вариться в собственном соку.
мыы уже с константином обсудили все и каг
авось из нас всех выйдет толк
а не сразу "баны" не там написал и читай правила шучу -)

и с колидой тоже отписали всеровно в одной каше варимся
__________________
Вообще-то я не специалист по этим гравицаппам...
Neverdie вне форума   Ответить с цитированием
Старый 01.06.2010, 18:43   #44
Neverdie
Kobold Dev
 
Аватар для Neverdie
 
Регистрация: 11.03.2010
Сообщений: 22
Сказал(а) спасибо: 5
Поблагодарили 3 раз(а) в 3 сообщениях
Neverdie На верном пути
Отправить сообщение для Neverdie с помощью ICQ
По умолчанию

Цитата:
Сообщение от RomanRom2 Посмотреть сообщение
прокси не будет работать с батлнетом, сколько не старайтесь. не тратьте время.
надо либо pcap, либо инжектор, либо lsp. pcap по проще.


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

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

наслышаны сами -)

"прокси не будет работать с батлнетом, сколько не старайтесь. не тратьте время.
надо либо pcap, либо инжектор, либо lsp. pcap по проще."

хз хз против лома нету приема если нету другого лома
__________________
Вообще-то я не специалист по этим гравицаппам...
Neverdie вне форума   Ответить с цитированием
Старый 01.06.2010, 19:04   #45
abdula123
Пользователь
 
Регистрация: 22.03.2010
Сообщений: 41
Сказал(а) спасибо: 7
Поблагодарили 25 раз(а) в 15 сообщениях
abdula123 На верном пути
По умолчанию

Цитата:
Сообщение от RomanRom2 Посмотреть сообщение
прокси не будет работать с батлнетом, сколько не старайтесь. не тратьте время.
надо либо pcap, либо инжектор, либо lsp. pcap по проще.
pcap никогда проще не был. и не будет.

а под прокси мы наверное имеем в виду разные вещи.

если речь идет об L7-прокси, который изображает для клиента близардовский сервер - то тут действительно ой. перспектив никаких не видно.

а если о жутком кадавре, который для LSP-редиректора выглядит как L4-прокси (socks4/5), а по сути - реализует MITM-атаку. - то тут всё очень даже перспективно.

+ не нужно заморачиваться с реализацией LSP
+ не нужно заморачиваться с косяками сборки потока из пакетов. (4х потоков, точнее)
+ есть возмножность активно влиять на передаваемые данные. в том числе и данные, передаваемые варденом внутри дополнительного крипто-потока.
+ существенно меньший объем работ по реализации, в сравнении с pcap и своим lsp (насчет хуков - не уверен).
+ гораздо более легкая миграция на новые версии, по сравнению с хуками.
abdula123 вне форума   Ответить с цитированием
Старый 03.06.2010, 11:30   #46
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

хм... заставить трафик ходить через указанный адрес. Читал про это в интернете...
Цитата:
есть возмножность активно влиять на передаваемые данные.
вот это уже очень интересно, получается:
декриптовать -> внести свою лепту -> обратно зашифровать и пускай идет дальше.

Цитата:
а если о жутком кадавре, который для LSP-редиректора выглядит как L4-прокси (socks4/5), а по сути - реализует MITM-атаку. - то тут всё очень даже перспективно.
Но очень смущает то, что нужно работать с WinAPI, тобиш мне как человеку незнающему толком С++ будет тяжело приаттачить необходимые либы и заставить их работать на себя, но это все решается с помощью гугда и танца с бубном.

Неясным осталось только то,
Цитата:
L4-прокси (socks4/5)
Не нашел внятного описания всему этому делу, и вообще-то хотелось узнать реализуемо ли это средствами С# (без написания отдельных длл-ок)?

Что-то чем дальше тем сложнее все становится.
__________________
Konctantin вне форума   Ответить с цитированием
Старый 03.06.2010, 14:56   #47
abdula123
Пользователь
 
Регистрация: 22.03.2010
Сообщений: 41
Сказал(а) спасибо: 7
Поблагодарили 25 раз(а) в 15 сообщениях
abdula123 На верном пути
По умолчанию

Цитата:
Сообщение от Konctantin Посмотреть сообщение
вот это уже очень интересно, получается:
декриптовать -> внести свою лепту -> обратно зашифровать и пускай идет дальше.


Но очень смущает то, что нужно работать с WinAPI, тобиш мне как человеку незнающему толком С++ будет тяжело приаттачить необходимые либы и заставить их работать на себя, но это все решается с помощью гугда и танца с бубном.
никуда не нужно зарываться.

1. идем на http://www.proxycap.com/download.html , скачиваем и устанавливаем этот "proxifier". (ну или любой другой по вкусу, они все практически одинаковые). ВСЁ!!! про LSP и связанные с ним заморочки можно забыть - эта программа занимается ими сама.

2. добавляем socks4 прокси с адресом 127.0.0.1:наш_порт.
добавляем правила "wow.exe перекидывать на этот прокси, остальное не трогать".

3. идем на http://ftp.icm.edu.pl/packages/socks...OCKS4.protocol , читаем описание протокола. проще не придумать.
реализуем сервер этого счастья хоть на C#, хоть на чём угодно другом.

4. добавляем логику типа такой:

Код:
принять соединение
соединиться с запрашиваемым адресом
ответить ок
принять первые 4 байта данных от клиента
если 3-4 байты равны "\xed\x01"(SMSG_AUTH_SESSION) или "\x12\x05" (SMSG_AUTH_SECOND_SESSION):
    значит в этом соединении идут интересующие нас данные и его нада обрабатывать 
иначе:
    просто и тупо прокидывать данные между клиентом и сервером (battle.net / запрос новостей и т.п.)
5. думаем на тему "а как обрабатывать параллельно 2 и более соединения". select или треды - в помощь.

6. прикидываем (ida в помощь) когда и где в памяти wow.exe образуются интересующие нас ключи и читаем их оттуда.


Цитата:
Сообщение от Konctantin Посмотреть сообщение
Неясным осталось только то,

Не нашел внятного описания всему этому делу, и вообще-то хотелось узнать реализуемо ли это средствами С# (без написания отдельных длл-ок)?
у меня весь прокси полностью написан на питоне, так что на C# тоже можно.


Цитата:
Сообщение от Konctantin Посмотреть сообщение
Что-то чем дальше тем сложнее все становится.
это только в начале, потом легче пойдет.
abdula123 вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
Konctantin (03.06.2010)
Старый 03.06.2010, 20:17   #48
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Спасибо, я вашем посте я получил почти все что меня интересовало.
Теперь, как немного освобожусь от роботы, попытаюсь все это дело реализовать.

Еще раз спасибо.

ЗЫ. Не вы случайно автор адской трупожерки?
__________________

Последний раз редактировалось Konctantin; 03.06.2010 в 20:25.
Konctantin вне форума   Ответить с цитированием
Старый 04.06.2010, 09:18   #49
zhenya
Пользователь
 
Регистрация: 12.03.2010
Сообщений: 85
Сказал(а) спасибо: 5
Поблагодарили 42 раз(а) в 17 сообщениях
zhenya Скоро придёт к известности
По умолчанию

Цитата:
Сообщение от Konctantin Посмотреть сообщение

ЗЫ. Не вы случайно автор адской трупожерки?
именно он...
zhenya вне форума   Ответить с цитированием
Старый 04.06.2010, 09:35   #50
Neverdie
Kobold Dev
 
Аватар для Neverdie
 
Регистрация: 11.03.2010
Сообщений: 22
Сказал(а) спасибо: 5
Поблагодарили 3 раз(а) в 3 сообщениях
Neverdie На верном пути
Отправить сообщение для Neverdie с помощью ICQ
По умолчанию

Цитата:
Сообщение от zhenya Посмотреть сообщение
именно он...
гыы
тогда ему респект и уважуха
__________________
Вообще-то я не специалист по этим гравицаппам...
Neverdie вне форума   Ответить с цитированием
Старый 04.06.2010, 10:55   #51
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Вчера посидел немного, и сделал "прозрачный" прокси сервер,
С помощью проксификатора заставил клиент ходить через свой прокси.

Теперь вот как будет время, перенесу все наработки по снифферу в прокси.

Но, у меня такой вопрос:
пакеты будут приходить ферментированные?
ну скажем так: размер в заголовке 20 а длинна пакета 15, значить записать этот пакет в буффер и принять следующий пакет, объединить и обработать
__________________
Konctantin вне форума   Ответить с цитированием
Старый 04.06.2010, 11:20   #52
abdula123
Пользователь
 
Регистрация: 22.03.2010
Сообщений: 41
Сказал(а) спасибо: 7
Поблагодарили 25 раз(а) в 15 сообщениях
abdula123 На верном пути
По умолчанию

Цитата:
Сообщение от Konctantin Посмотреть сообщение
Но, у меня такой вопрос:
пакеты будут приходить ферментированные?
ну скажем так: размер в заголовке 20 а длинна пакета 15, значить записать этот пакет в буффер и принять следующий пакет, объединить и обработать
таки фрагментированные. ферментированное - пиво (и не только).

то, что пакеты будут фрагментироваться при приеме - бывает, но очень редко. а вот обратная ситуация - когда "одинм куском" приходит несколько пакетов - вполне себе нормальное явление.

так что разбиение потока на пакеты делать обязательно.
abdula123 вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
Konctantin (04.06.2010)
Старый 04.06.2010, 12:07   #53
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Цитата:
несколько пакетов - вполне себе нормальное явление.
Ну это я уже почувствовал на своей шкуре.
__________________
Konctantin вне форума   Ответить с цитированием
Старый 12.06.2010, 21:14   #54
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Мдя, как не везет, так не везет, при логине клиентом говорит что готово, и ничего (доступен только список миров)
__________________
Konctantin вне форума   Ответить с цитированием
Старый 13.06.2010, 06:04   #55
GriffonHeart
Гость
 
Сообщений: n/a
По умолчанию

А я скучаю по временам адской трупожорки
Там всё так просто было и можно было снифить много-много чего. Сейчас, увы, такого удобного снифера нет
  Ответить с цитированием
Старый 13.06.2010, 08:40   #56
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Ностальгия...
Мне вот интересно, кто-то уже реализовал проксю или сниффер, или все сделано только в теории?

Вот лично мне, как человеку далекому от программирования в сфере сетевых протоколов очень трудно сделать то, чего до конца не понимаешь. Сами понимаете, все это хобби, и есть еще реальная жизнь, пока получается - делаешь, как только зашел в тупик проект сразу уходит с "рабочего стола" в "архив" до лучших времен.

Бывает такое, что загвоздка в том самом "да" или "нет", и требуется мизерная подсказка, но увы...

До сих пор. я не нашел в интернете никаких примеров "рабочих" прокси, чтобы изучить сам принцип действия.

Максимум что у меня получилось, так это получения списка миров, дальше ничего не выходит

Выше я писал:
Цитата:
Вчера посидел немного, и сделал "прозрачный" прокси сервер,
С помощью проксификатора заставил клиент ходить через свой прокси.
А заходило потому, что перенаправил enUS клиент, а заходил enGB клиентом.
Так был рад, а оно оказалось лажа...

И все таки, надо по чуть чуть по изучать все это и сделать то, что задумал.
__________________
Konctantin вне форума   Ответить с цитированием
Старый 14.06.2010, 17:10   #57
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Давайте вернемся к нашим баранам и продолжим тему

ЗЫ. Естественно америку я не открою, но просто опишу суть.

В даном случае использован проксификатор, с правилами следуещего содержания:

Если приложение wow.exe соединяется с конечной точкой 213.248.127.130:1119,
тогда перенаправить его на 127.0.0.1:9998 (Login - сервер)
иначе если приложение wow.exe соеденяется (адресс не указан, тобиш 0.0.0.0:0),
тогда перенаправляем его на 127.0.0.1:9999 (World - сервер)

Значит, нам надо создать прокси, который бы создал 2 соединения, это соединение с клиентом и соединение с сервером:
* Соединение с клиентом, прокси выступает в качестве сервера и общается с клиентом
* Соединение с сервером, прокси выступает в качестве клиента и общается с сервером (Login - сервером)

но это все у нас пока процесс общения сервером авторизации. (213.248.127.130:1119)

Мы просто выступаем посредником и пересылаем пакеты при этом слушая их.

Но, клиент же должен подключится к World - серверу.
По этому, когда приходит пакет AUTH_REALM в котором приходит IPAdress:port сервера к которому надо подключится,
запоминаем этот IPAdress:port.

Создаем опять 2 подключения, аналогичные первым, только с адресом который мы прочитали и запомнили.

И далее выполняем обмен сообщениями между World - сервером и клиентом.

Для дальнейшей обработки пакетом их можно декриптовать и складывать, или делать с ними что захотим.

Далее, по скольку ввели новую систему распределения нагрузки World - сервер может прислать пакет, который указывает,
что нужно переподключится на новый World - сервер, и присылает данные:
1) SMSG_REDIRECT_CLIENT он присылает адрес нового сервера
2) SMSG_AUTH_CHALLENGE приходят новые сиды

Не знаю, может я что-то упустил, если так, то поправьте пожалуйста.
__________________
Konctantin вне форума   Ответить с цитированием
Старый 15.06.2010, 17:32   #58
abdula123
Пользователь
 
Регистрация: 22.03.2010
Сообщений: 41
Сказал(а) спасибо: 7
Поблагодарили 25 раз(а) в 15 сообщениях
abdula123 На верном пути
По умолчанию

Цитата:
Сообщение от Konctantin Посмотреть сообщение
Ностальгия...
Мне вот интересно, кто-то уже реализовал проксю или сниффер, или все сделано только в теории?
ну, как минимум, мой реализован и работает.

у других, думаю, тоже есть. вот только делиться и тем более выкладывать в паблик тут "почему-то" непринято


Цитата:
Сообщение от Konctantin Посмотреть сообщение
В даном случае использован проксификатор, с правилами следуещего содержания:

Если приложение wow.exe соединяется с конечной точкой 213.248.127.130:1119,
тогда перенаправить его на 127.0.0.1:9998 (Login - сервер)
иначе если приложение wow.exe соеденяется (адресс не указан, тобиш 0.0.0.0:0),
тогда перенаправляем его на 127.0.0.1:9999 (World - сервер)
лишние сложности.
у меня, например, нет разделения на login/world.
всё, что не начинается с нужного пакета - просто и тупо перекидывается без обработки. ну или можно на диск писать, если желание есть.


Цитата:
Значит, нам надо создать прокси, который бы создал 2 соединения, это соединение с клиентом и соединение с сервером:
* Соединение с клиентом, прокси выступает в качестве сервера и общается с клиентом
* Соединение с сервером, прокси выступает в качестве клиента и общается с сервером (Login - сервером)

но это все у нас пока процесс общения сервером авторизации. (213.248.127.130:1119)

Мы просто выступаем посредником и пересылаем пакеты при этом слушая их.

Но, клиент же должен подключится к World - серверу.
По этому, когда приходит пакет AUTH_REALM в котором приходит IPAdressort сервера к которому надо подключится,
запоминаем этот IPAdressort.
повторяю - лишние сложности!
для упрощения начать с такой конфигурации:

1. клиент у нас ровно одна штука, в начальный момент времени загружен, но не залогинен.

2. прокси запускается строго перед логином


в таком случае - какая разница, какой там адрес отдал клиенту сервер авторизации???
интересующее нас соединение, один черт, начнется с SMSG_AUTH_CHALLENGE
больше оно в нашем раскладе ни с чего начаться не может!

значит:
0. открываем (bind) сокет на нужном порту и ждем подключений (listen) от проксификатора

1. принимаем (accept) соединение от проксификатора

2. разбираем socks4 запрос, подключаемся (connect) к указанному адресу, отдаем проксификатору socks4-ответ "ОК"

3. тут я прошлый раз неправильно написал.
нужно делать так:
ждем, пока клиент что-нибудь пошлет, проверяем у этого "чего-нибудь" 3й+4й байты - и если они не равны опкоду CMSG_AUTH_SESSION (а не SMSG_AUTH_SESSION - такого опкода вообще нету) - забиваем на это соединение. ничего интересного тут не предвидится.
естественно продолжая прокидывать через него данные в обе стороны

5. если таки интересующие нас байты найдены - то ВЫВОДИМ НА КОНСОЛЬ МНОГО РАЗНОЦВЕТНЫХ БУКВ И РАДУЕМСЯ, ЧТО НАКОНЕЦ ЧТО-ТО ПОЛУЧИЛОСЬ.
пишем поток на диск (естественно каждое направление в свой файл. разделять на отдельные пакеты не нужно.)

6. летим подальше от любимого даларана, желательно в сторону пристани Моа'ки а оттуда - на самую дальнюю льдину, какую получится найти.

7. выходим из игры и смотрим на то месиво, что записалось в файлы.
ничего осмысленного, т.к. данные пошифрованы.
и скорее всего запишется очень мало данных, т.к. SMSG_SECOND_CONNECTION приходит почти сразу.
но прервый шаг уже сделан, в соединение вклинились!!!





вот так выглядит функция, занимающаяся пересылкой данных: http://paste2.org/p/878723 (шаги 2-3)

это, конечно, не C#, но представление дает

на yield не смотреть, они для реализации со-процедур (самопальной и весьма корявой, но "и так работает").

на read_session_key() и вытаскивания сидов из SMSG_AUTH_CHALLENGE не смотреть, она осталась со времен, когда по этим сидам я генерил крипто-состояния сам, а не читал их готовыми из памяти. не судьба убрать, "и так работает".

разбиение на пакеты, расшифровка пакетов, расшифровка вардена, логика, шифровка вардена, шифровка пакетов, сборка пакетов в поток - они все в WorldFilter

код коряв и страшен, как моя жизнь. однако "и так работает" ))

Последний раз редактировалось abdula123; 15.06.2010 в 18:32.
abdula123 вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
Konctantin (15.06.2010)
Старый 15.06.2010, 22:21   #59
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

меня просто в большей сложности смущает то, что нужно из одного потока разделять на на 2 потока, тобиш приходят пакеты которые должны идти на LoginServer и WorldServer но как их потом разделять, чтоб определить куда какой перенаправлять???

надо или знать все опкоды бнет пакетов или сразу на стадии соединения определить куда они направлены клиентом.

Просто я понимаю такую реализацию:
получаем соединение от клиента, и соединяемся с сервером: но, чтобы соединится с сервером, надо знать конечную точку. Тобиш работать в так званом клиент серверном режиме.

Или же можно реализовать "слепую прокси" которой не надо явно указывать куда подключатся, но я себе такое слабо представляю.

Черт, я еще больше запутался, или может это так пиво повлияло...
__________________
Konctantin вне форума   Ответить с цитированием
Старый 16.06.2010, 05:47   #60
abdula123
Пользователь
 
Регистрация: 22.03.2010
Сообщений: 41
Сказал(а) спасибо: 7
Поблагодарили 25 раз(а) в 15 сообщениях
abdula123 На верном пути
По умолчанию

Цитата:
Сообщение от Konctantin Посмотреть сообщение
меня просто в большей сложности смущает то, что нужно из одного потока разделять на на 2 потока, тобиш приходят пакеты которые должны идти на LoginServer и WorldServer но как их потом разделять, чтоб определить куда какой перенаправлять???
для начала - просто и тупо реализуй socks4-proxy, способный прокидывать через себя произвольное кол-во произвольных соединений параллельно.

просто прокси, без всякой специфики wow.


потом уже, когда будет не "понимание", а работающий код - к нему уже можно будет дописывать нужный функционал.
abdula123 вне форума   Ответить с цитированием
Старый 16.06.2010, 12:38   #61
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

вот тут я и застрял, я не могу понять как прокси будет знать куда перебрасывать соединение, если в сокете, конечный адресс уже выглядит как localhost:port
__________________
Konctantin вне форума   Ответить с цитированием
Старый 16.06.2010, 15:06   #62
abdula123
Пользователь
 
Регистрация: 22.03.2010
Сообщений: 41
Сказал(а) спасибо: 7
Поблагодарили 25 раз(а) в 15 сообщениях
abdula123 На верном пути
По умолчанию

Цитата:
Сообщение от Konctantin Посмотреть сообщение
вот тут я и застрял, я не могу понять как прокси будет знать куда перебрасывать соединение, если в сокете, конечный адресс уже выглядит как localhostort
http://ftp.icm.edu.pl/packages/socks...OCKS4.protocol

читать до просветления.
abdula123 вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
Konctantin (16.06.2010)
Старый 16.06.2010, 18:40   #63
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Черт, биг сенкую. Наконец то мне дошло, в самом пакете все есть
Код:
		+----+----+----+----+----+----+----+----+----+----+....+----+
		| VN | CD | DSTPORT |      DSTIP        | USERID       |NULL|
		+----+----+----+----+----+----+----+----+----+----+....+----+
 # of bytes:	   1    1      2              4           variable       1
Черт, насколько я тупой и неграмотный, спасибо за решающий удар по моей стене, ограждающей от просветления...
__________________
Konctantin вне форума   Ответить с цитированием
Старый 16.06.2010, 20:21   #64
abdula123
Пользователь
 
Регистрация: 22.03.2010
Сообщений: 41
Сказал(а) спасибо: 7
Поблагодарили 25 раз(а) в 15 сообщениях
abdula123 На верном пути
По умолчанию

Цитата:
Сообщение от GriffonHeart Посмотреть сообщение
А я скучаю по временам адской трупожорки
Там всё так просто было и можно было снифить много-много чего. Сейчас, увы, такого удобного снифера нет
адская трупожорка переделывается (без потери функциональности) под нынешние реалии заменой 2х модулей и добавлением еще 2х - чтение из памяти и arc4. + почти без "бесплатно" по затратам времени добавляетя поддержка чтения\изменения вардена.

что и было проделано мною в феврале, когда снова появился интерес копаться.

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


может быть потом выложу потом. тем более, что интерес снова куда-то уходит (бот написан и бегает, сниффер снифит)

Последний раз редактировалось abdula123; 16.06.2010 в 20:28.
abdula123 вне форума   Ответить с цитированием
Старый 16.06.2010, 21:58   #65
RomanRom2
WowCore Dev
 
Аватар для RomanRom2
 
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
RomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всем
По умолчанию

бот наверное имеется ввиду тот, который на запущенном и залогиненном клиенте кнопки нажимает и мышкой шевелит?
RomanRom2 вне форума   Ответить с цитированием
Старый 17.06.2010, 04:13   #66
abdula123
Пользователь
 
Регистрация: 22.03.2010
Сообщений: 41
Сказал(а) спасибо: 7
Поблагодарили 25 раз(а) в 15 сообщениях
abdula123 На верном пути
По умолчанию

Цитата:
Сообщение от RomanRom2 Посмотреть сообщение
бот наверное имеется ввиду тот, который на запущенном и залогиненном клиенте кнопки нажимает и мышкой шевелит?
бот имеется в виду тот, который инжектится в процесс, вызывает нужные функции (и lua, в том числе защищенные, и внутренние C-шные, там где lua не хватает) и шарится в памяти.

тем самым имеющий практически полную информацию об окружении и действующий в соответствии с ней.
abdula123 вне форума   Ответить с цитированием
Старый 17.06.2010, 06:49   #67
GriffonHeart
Гость
 
Сообщений: n/a
По умолчанию

Цитата:
Сообщение от abdula123 Посмотреть сообщение
адская трупожорка переделывается (без потери функциональности) под нынешние реалии заменой 2х модулей и добавлением еще 2х - чтение из памяти и arc4. + почти без "бесплатно" по затратам времени добавляетя поддержка чтения\изменения вардена.

что и было проделано мною в феврале, когда снова появился интерес копаться.

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


может быть потом выложу потом. тем более, что интерес снова куда-то уходит (бот написан и бегает, сниффер снифит)
Было бы не плохо увидеть нововведения в старой svn-ке... или завести новую
А парсеры пакетов подгоним под новые билды и ревизии мангоса, не проблема
  Ответить с цитированием
Старый 17.06.2010, 16:26   #68
abdula123
Пользователь
 
Регистрация: 22.03.2010
Сообщений: 41
Сказал(а) спасибо: 7
Поблагодарили 25 раз(а) в 15 сообщениях
abdula123 На верном пути
По умолчанию

Цитата:
Сообщение от GriffonHeart Посмотреть сообщение
Было бы не плохо увидеть нововведения в старой svn-ке... или завести новую
я пролюбил пароль от старого svn-репозитория.



кстати, а что случилось с Trac'ом проекта? почему он пускает незалогиненых, дает им доступ к коду. и не дает логиниться.

кагбе паблика не очень хочется.

UPD:
а, понятно, проклятые китайцы забили на opensvn

Цитата:
As the site is complety full, the code is very antiquated and buggy, and we just don't have the time to keep maintaining it, we have decided to shutdown this site on 2010/5/15.
Open source projects can consider migrating to SourceForge, Google Code, or any of the other free hosting services.

Update
We will provide read-only access until 2010/5/1. (As of 4/23 our disks are full.)
From 2010/5/1 till 2010/5/15, we will provide the ability to download your repository, either as a dump file, or as a tarball.

Последний раз редактировалось abdula123; 17.06.2010 в 16:29.
abdula123 вне форума   Ответить с цитированием
Старый 19.06.2010, 02:12   #69
RomanRom2
WowCore Dev
 
Аватар для RomanRom2
 
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
RomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всем
По умолчанию

решил тряхнуть стариной - переписал старый zLogger (который работает на pcap) на новый лад. следующую сессию видит и начинает новый снифф. пишет в raw, потом в оффлайне уже декриптую утилиткой. спасибо том_рус что подсказал где брать сиды для нового соединения.
RomanRom2 вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
sven (20.06.2010)
Старый 19.06.2010, 22:17   #70
Neverdie
Kobold Dev
 
Аватар для Neverdie
 
Регистрация: 11.03.2010
Сообщений: 22
Сказал(а) спасибо: 5
Поблагодарили 3 раз(а) в 3 сообщениях
Neverdie На верном пути
Отправить сообщение для Neverdie с помощью ICQ
По умолчанию

Хех -)) запахло порохом ? ))
решили все тряхнуть стариной ? -)
__________________
Вообще-то я не специалист по этим гравицаппам...
Neverdie вне форума   Ответить с цитированием
Старый 20.06.2010, 00:44   #71
RomanRom2
WowCore Dev
 
Аватар для RomanRom2
 
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
RomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всемRomanRom2 Это имя известно всем
По умолчанию

не. просто после затянувшегося перерыва я вернулся
пока вот в роли догоняющего.
RomanRom2 вне форума   Ответить с цитированием
2 пользователя(ей) сказали cпасибо:
sven (20.06.2010), YuruY (20.06.2010)
Старый 22.06.2010, 19:48   #72
user456
Новичок
 
Регистрация: 31.03.2010
Сообщений: 22
Сказал(а) спасибо: 2
Поблагодарили 23 раз(а) в 8 сообщениях
user456 На верном пути
По умолчанию

Цитата:
Сообщение от abdula123 Посмотреть сообщение
ну, как минимум, мой реализован и работает.

у других, думаю, тоже есть. вот только делиться и тем более выкладывать в паблик тут "почему-то" непринято
Ну просто мангосы живут какой-то своей жизнью и до сих пор вроде ни о чем не спрашивали. Я вот месяц без оффа, решил глянуть сервер в локалке (точнее задолбался с тем что инфа в UI клиента разбросана, а у меня не 8 глаз чтобы смотреть за кулдауном на кнопке внизу экрана, мобом в центре и аггро с дотами наверху, короче переделывал один аддон и учил Lua заодно). Так вот: я так понимаю везде стоит Мангос в локалках. Был страшно удивлен что мобы не тапятся (от tap). В то время как я уже делал это, нормальные gameobjects квестовые (те что видел все были активны, даже если некоторые собрал полностью, и оставались активны после квеста) и госсипы гардов табличные в summit (после того как ascent закрылся) еще пару лет назад под 2.4.

Так вот к нашим баранам: можно вообще делать под raw сокетами. Пакеты и правда могут приходить "всё в одном", с повторами, порезаные. Но логика сборки там простая. Я и такой сделал и он куда проще даже проксевого (с проксевым головняк лично у меня с критическими секциями, пока не отправлено надо ж что-то делать с новыми пакетами). У Ромки под PCap принцип тот-же, разве что ему влом пакеты собирать (какая-то у него либа проприетарно-тыреная этим занимается).

Можно было б выложить основной код, но я так понимаю у девелоперов с кодом Дельфи еще хуже чем с СИ.
user456 вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
Konctantin (22.06.2010)
Старый 23.06.2010, 00:24   #73
user456
Новичок
 
Регистрация: 31.03.2010
Сообщений: 22
Сказал(а) спасибо: 2
Поблагодарили 23 раз(а) в 8 сообщениях
user456 На верном пути
По умолчанию обработка пакетов

Вот собсно raw сокеты в 2-х словах. Код на Дельфи, но винапи он и в Африке винапи. PChar соответственно в си char*. Элементарного типа WSAStartup не касаюсь.
Инициализация
Код:
//декларация обработки ивента
const
  WM_ListenSocketEvent = WM_User+1;
....
procedure WMListenSocketEventHandler(var Msg:TMessage);message WM_ListenSocketEvent;

....

function TfrmMain.InitSocket: Boolean;
var
  PromiscuousMode: dword;
  temp: integer;
  BufSize: dword;
begin
     result:=false;
     // создаем сокет
     hSocket := socket(AF_INET, SOCK_RAW, IPPROTO_IP);
     if hSocket = INVALID_SOCKET then begin
        DeInitSocket(WSAGetLastError);
        AddToLog('Raw sockets not supported');
        Exit;
     end;
     FillChar(Addr_in, SizeOf(sockaddr_in), 0);
     Addr_in.sin_family:= AF_INET;
     // указываем за каким интерфейсом будем следить
     Addr_in.sin_addr.s_addr := inet_addr(PChar(Host));
     // связываем сокет с локальным адресом
     if ScktErrorCheck(bind(hSocket, @Addr_in, SizeOf(sockaddr_in))) = SOCKET_ERROR then exit;
     BufSize:=MAX_PACKET_SIZE;
     if ScktErrorCheck(SetSockOpt(hSocket, SOL_SOCKET, SO_RCVBUF, PChar(@BufSize), sizeof(BufSize))) = SOCKET_ERROR then exit;
     temp:=sizeof(integer);
     if ScktErrorCheck(GetSockOpt(hSocket, SOL_SOCKET, SO_RCVBUF, PChar(@BufSize), temp)) = SOCKET_ERROR then exit
     else AddToLog('Buffer size = '+IntToHex(BufSize,4));
     if ScktErrorCheck(WSAAsyncSelect(hSocket,frmMain.Handle,WM_ListenSocketEvent,FD_READ or FD_CLOSE)) = SOCKET_ERROR then exit;

     // Переключаем интерфейс на прием всех пакетов проходящих через интерфейс - promiscuous mode.
     PromiscuousMode := 1;
     if ScktErrorCheck(ioctlsocket(hSocket, SIO_RCVALL, PromiscuousMode)) = SOCKET_ERROR then exit;
     Result := True;
end;
обработчик ивента
Код:
procedure TfrmMain.WMListenSocketEventHandler(var Msg:TMessage);
var
   Sock: TSocket;
   SockError,PacketSize: integer;
begin
     Sock:=TSocket(Msg.WParam);
     SockError:=WSAGetSelectError(Msg.lParam);
     if SockError <> 0 then begin
        CloseSocket(Sock);
        Exit;
     end;
     case WSAGetSelectEvent(Msg.lParam) of
          FD_Read:   begin
             CS.Enter;
             PacketSize := recv(hSocket, Packet, MAX_PACKET_SIZE, 0);
             // Если есть данные - производим их разбор
             ParcePacket(PacketSize);
             CS.Leave;
          end;
          FD_Close: begin
             AddToLog('FD_CLOSE');
          end;
     end;
end;
далее разбор пакета
Код:
     if PacketSize <= SizeOf(TIPHeader) then exit;

     pIpHdr:=PIPHeader(@Packet[0]);
     ipHdrLen:=GetIPHeaderLen(pIpHdr);
     pTcpHdr:=PTCPHeader(@Packet[ipHdrLen]);
     // определяем тип протокола
     if pIpHdr.iph_protocol = IPPROTO_TCP then begin
         PacketType := 'TCP';
     	    // Смотрим порт отправителя и получателя
         SrcPort := pTcpHdr.sourcePort;
         DestPort := pTcpHdr.destinationPort;
     end
     else exit;

     SrcPort := htons(SrcPort);
     DestPort := htons(DestPort);
     if (SrcPort <> frmMain.FListenPort)and(DestPort <> frmMain.FListenPort) then exit;

     // Пишем IP адрес отправителя с портом
     AddrSrc.S_addr := pIpHdr.iph_src;
     // Пишем IP адрес получателя с портом
     AddrDst.S_addr := pIpHdr.iph_dest;

     tcpHdrDataOffs:=ipHdrLen + GetTCPDataOffset(@Packet[ipHdrLen]);

     PacketFlags:=ntohs(pTcpHdr.flags);
...
в общем на основе структур ip и tcp хедеров разбираем, если что читаем доку "RFC793 - Transmission Control Protocol".

продолжение ниже...
user456 вне форума   Ответить с цитированием
2 пользователя(ей) сказали cпасибо:
Konctantin (23.06.2010), zergtmn (23.06.2010)
Старый 23.06.2010, 00:27   #74
user456
Новичок
 
Регистрация: 31.03.2010
Сообщений: 22
Сказал(а) спасибо: 2
Поблагодарили 23 раз(а) в 8 сообщениях
user456 На верном пути
По умолчанию

сама сборка пакетов (для пикапа тоже пригодится)
Код:
constructor TTcpBuffer.Create;
begin
    FCS:=TCriticalSection.Create;
    setlength(FSeqArr, SIZE64);
    FSeqCount:=0;
    FCurrSeq:=0;
    //FNextSeq:=0;
    FDupCount:=0;
    FOorCount:=0;
end;

destructor TTcpBuffer.Destroy;
var
   i: integer;
begin
    FCS.Enter;
    // |--[ack|array] count,first
    // |         |--[seq|wsabuf]
    // |         |--[seq|wsabuf]
    // |         |--[seq|wsabuf]
    for i:=0 to FSeqCount - 1 do
      FreeMem(FSeqArr[i].wsa_buf.buf);
    FSeqArr:=nil;
    FCS.Leave;
    FCS.Free;
    inherited;
end;

procedure TTcpBuffer.ASwap(Lo, Hi: integer);
var
   temp: TSeqRec;
begin
     move(FSeqArr[Lo],temp,sizeof(TSeqRec));
     move(FSeqArr[Hi],FSeqArr[Lo],sizeof(TSeqRec));
     move(temp,FSeqArr[Hi],sizeof(TSeqRec));
end;

procedure TTcpBuffer.QuickSort(iLo, iHi: integer);
var
  Lo, Hi: integer;
  pivot: dword;
begin
    Lo := iLo;
    Hi := iHi;
    pivot:=FSeqArr[(Lo + Hi) div 2].swappedSeq;
    repeat
      while FSeqArr[Lo].swappedSeq < pivot do Inc(Lo);
      while FSeqArr[Hi].swappedSeq > pivot do Dec(Hi);
      if Lo <= Hi then begin
        if Lo <> Hi then ASwap(Lo,Hi);
        Inc(Lo);
        Dec(Hi);
      end;
    until Lo > Hi;
    if Hi > iLo then QuickSort(iLo, Hi);
    if Lo < iHi then QuickSort(Lo, iHi);
end;

{function TTcpBuffer.QuickFind(const looking_for: dword; iLo, iHi: integer):dword;
var
  Mid: dword;
  pivot: dword;
begin
    if (iHi-iLo-1) > 0 then begin
       Mid:=(iLo+iHi) div 2;
       pivot:=FSeqArr[Mid].swappedSeq;
       if pivot < looking_for then result:=QuickFind(looking_for,Mid,iHi)
       else result:=QuickFind(looking_for,iLo,Mid);
    end
    else if looking_for > FSeqArr[iLo].swappedSeq then result:=iHi
    else result:=iLo;
end;}

function TTcpBuffer.Match(Value: dword; ItemIndex: integer): integer;
begin
    result:=0;
    if Value < FSeqArr[ItemIndex].swappedSeq then result:=-1
    else if Value > FSeqArr[ItemIndex].swappedSeq then result:=1;
end;

function TTcpBuffer.QuickSearch(Value: dword; Count: integer; MatchFunction: TMatchFunction): integer;
var
  L, M, C: integer;
begin
  if Count > 0 then
  begin
    L := 0;
    Dec(Count);
    while L <= Count do
    begin
      M := (L + Count) shr 1;
      C := MatchFunction(Value, M);
      if C > 0 then
        L := M + 1
      else if C <> 0 then
        Count := M - 1
      else
      begin
        Result := M;
        Exit;
      end;
    end;
  end;
  Result := -1;
end;

{ Add any match cap sequence to array }
procedure TTcpBuffer.Add2Buffer(data: pointer; swappedSeq,len,dataOffs: dword; isFromServer: boolean);
var
  prev: dword;
  dataLen: dword;
  i: integer;
begin
    prev:=FSeqCount;
    inc(FSeqCount);
    if FSeqCount > length(FSeqArr) then
      setlength(FSeqArr, ((length(FSeqArr) shr 6) + 1) shl 6); //by 64
    GetMem(FSeqArr[prev].wsa_buf.buf, len);
    move(data^, FSeqArr[prev].wsa_buf.buf^, len);
    FSeqArr[prev].wsa_buf.len:=len;
    FSeqArr[prev].swappedSeq:=swappedSeq;
    FSeqArr[prev].dataOffs:=dataOffs;
    dataLen:=len - dataOffs;
    FSeqArr[prev].dataLen:=dataLen;
    //if swappedSeq = FNextSeq then
    //  FNextSeq:=FCurrSeq + dataLen;
    if FSeqCount > 1 then
      QuickSort(0, FSeqCount - 1);
    if FSeqCount = 10 then begin
      if isFromServer then AddToLog('SMSG')
      else AddToLog('CMSG');
      AddToLog('current '+IntToHex(FCurrSeq,8)+' datalen '+IntToHex(dataLen,4));
      AddToLog('expecting '+IntToHex(FCurrSeq + dataLen,8));
      for i := 0 to 9 do AddToLog('seq['+IntToStr(i)+']='+IntToHex(FSeqArr[i].swappedSeq,8));
    end;
end;

{ Add any packet from current to current+MAX_DELTA_BROWSE_SEQUENCE }
procedure TTcpBuffer.AddData(data: pointer; len: dword; isFromServer: boolean);
var
   packetFlags: word;
   ipHdrLen,tcpHdrDataOffs,dataOffs: dword;
   pIpHdr: PIPHeader;
   pTcpHdr: PTCPHeader;
   pseudoHdr: TTCPPseudoHeader;
   pseudohdrCS,cs: word;
   swappedSeq,maxPossibleSeq: dword;
label fin;
begin
     FCS.Enter;
     pIpHdr:=PIPHeader(data);
     ipHdrLen:=GetIPHeaderLen(pIpHdr);
     pTcpHdr:=PTCPHeader(@TBytes(data)[ipHdrLen]);

     //check already in array
     swappedSeq:=ntohl(pTcpHdr.sequenceNumber);
     if FSeqCount > 1 then begin
        if QuickSearch(swappedSeq, FSeqCount, Match) >= 0 then begin
          //AddToLog(Format('skip duplicated seq: %.8x swseq: %.8x',[pTcpHdr.sequenceNumber,swappedSeq]));
          inc(FDupCount); goto fin;
        end;
     end
     else if FSeqCount > 0 then begin
        if FSeqArr[0].swappedSeq = swappedSeq then begin
          //AddToLog(Format('skip duplicated seq: %.8x swseq: %.8x',[pTcpHdr.sequenceNumber,swappedSeq]));
          inc(FDupCount); goto fin;
        end;
     end;
     //check CS
     cs:=GetChecksum(pIpHdr, ipHdrLen);
     if cs <> 0 then begin
        if isFromServer then AddToLog('wrong iphdr cs='+IntToHex(cs,4)+' src=server')
        else AddToLog('wrong iphdr cs='+IntToHex(cs,4)+' src=client');
        if (checkCS)and(isFromServer) then goto fin;
     end;
     if isFromServer then begin
        pseudoHdr.iph_src:=pIpHdr.iph_src;
        pseudoHdr.iph_dest:=pIpHdr.iph_dest;
        pseudoHdr.reserved:=0;
        pseudoHdr.iph_protocol:=pIpHdr.iph_protocol;
        pseudoHdr.tcp_length:=ntohs(len - ipHdrLen); //ntohl shr 16;
        pseudohdrCS:=not(GetChecksum(@pseudoHdr, sizeof(pseudoHdr)));
        cs:=GetChecksum(pTcpHdr, len - ipHdrLen, pseudohdrCS);
        if cs <> 0 then begin
          if isFromServer then AddToLog('wrong iphdr cs='+IntToHex(cs,4)+' src=server')
          else AddToLog('wrong iphdr cs='+IntToHex(cs,4)+' src=client');
          if (checkCS) then goto fin;
        end;
     end;

     packetFlags:=ntohs(pTcpHdr.flags);
     //initial sequences
     if (packetFlags and TCP_FLAG_SYN) <> 0 then begin
        //FNextSeq:=
        FCurrSeq:=swappedSeq + 1; //FNextSeq;
        goto fin;
     end;
     //if (packetFlags and TCP_FLAG_ACK) <> 0 then goto fin;
     maxPossibleSeq:=FCurrSeq + MAX_DELTA_BROWSE_SEQUENCE;
     if ((FCurrSeq < maxPossibleSeq)and((swappedSeq < FCurrSeq)or(swappedSeq > maxPossibleSeq))) //linear
        or ((FCurrSeq > maxPossibleSeq)and((swappedSeq < FCurrSeq)and(swappedSeq > maxPossibleSeq))) then begin
          //AddToLog(Format('skip out of range seq: %.8x swseq: %.8x FCurrSeq: %.8x',[pTcpHdr.sequenceNumber,swappedSeq,FCurrSeq]));
          inc(FOorCount); goto fin;
     end;
     tcpHdrDataOffs:=GetTCPDataOffset(@TBytes(data)[ipHdrLen]);
     dataOffs:=ipHdrLen+tcpHdrDataOffs;
     if len > dataOffs then     
        Add2Buffer(data, swappedSeq, len, dataOffs, isFromServer);
   fin:
     FCS.Leave;
end;

procedure TTcpBuffer.RemoveAt(seqArrPos: integer);
begin
    Assert(seqArrPos < FSeqCount);
    FreeMem(FSeqArr[seqArrPos].wsa_buf.buf);
    if seqArrPos < (FSeqCount - 1) then
      move(FSeqArr[seqArrPos+1], FSeqArr[seqArrPos], sizeof(TSeqRec)*(FSeqCount - seqArrPos - 1));
    dec(FSeqCount);
end;

procedure TTcpBuffer.Release(swappedSeq: dword);
var
  maxPossibleSeq: dword;
  i,spos: integer;
begin
    FCS.Enter;
    if FSeqCount > 1 then begin
       //AddToLog(Format('TTcpBuffer.Release seq: %.8x swseq: %.8x FSeqCount: %d',[bswap(swappedSeq),swappedSeq,FSeqCount]));
       //for i := 0 to FSeqCount - 1 do
       //  AddToLog(Format('FSeqArr[%d] swseq: %.8x wsa_buf.buf: %.8x wsa_buf.len: %d',[i,FSeqArr[i].swappedSeq,dword(FSeqArr[i].wsa_buf.buf),FSeqArr[i].wsa_buf.len]));

       spos:=QuickSearch(swappedSeq, FSeqCount, Match);
       if spos >= 0 then begin
         //AddToLog(Format('swseq found at %d',[spos]));
         FCurrSeq:=FCurrSeq + FSeqArr[spos].dataLen;
         RemoveAt(spos);
       end;
       //remove trash
       i:=0;
       while i < FSeqCount do begin
         maxPossibleSeq:=FCurrSeq + MAX_DELTA_BROWSE_SEQUENCE;
         if maxPossibleSeq > FCurrSeq then begin
           if (FSeqArr[i].swappedSeq < FCurrSeq)or(FSeqArr[i].swappedSeq > maxPossibleSeq) then begin
             //AddToLog(Format('FSeqCount: %d removing at: %d FCurrSeq: %.8x maxPossibleSeq: %.8x swseq: %.8x',[FSeqCount,i,FCurrSeq,maxPossibleSeq,FSeqArr[i].swappedSeq]));
             RemoveAt(i);
           end
           else inc(i);
         end
         else if (FSeqArr[i].swappedSeq < FCurrSeq)and(FSeqArr[i].swappedSeq > maxPossibleSeq) then begin
           //AddToLog(Format('FSeqCount: %d removing at: %d FCurrSeq: %.8x maxPossibleSeq: %.8x swseq: %.8x',[FSeqCount,i,FCurrSeq,maxPossibleSeq,FSeqArr[i].swappedSeq]));
           RemoveAt(i);
         end
         else inc(i);
       end;
    end
    else if FSeqCount > 0 then begin
       if FSeqArr[0].swappedSeq = swappedSeq then begin
         FCurrSeq:=FCurrSeq + FSeqArr[0].dataLen;
         RemoveAt(0);
       end;
    end;
    FCS.Leave;
end;

{ Get next matched sequence }
function TTcpBuffer.GetSequence: PSeqRec;
var
  spos: integer;
begin
    result:=nil;
    FCS.Enter;
    if FSeqCount > 1 then begin
       spos:=QuickSearch(FCurrSeq, FSeqCount, Match);
       if spos >= 0 then result:=@FSeqArr[spos];
    end
    else if FSeqCount > 0 then begin
       if FSeqArr[0].swappedSeq = FCurrSeq then
         result:=@FSeqArr[0];
    end;
    FCS.Leave;
end;
и вот тут были вопросы по самой организации обработки (если какой-то пакет не пришел то сколько надо хранить? не гигабайты же. Если потом пришел, но с него другие sequence пошли, то что? А приходили такие порой при глючной сети и жутких лагах). Потом описанная в никсах проверка контрольных сумм шла под ХР и нивкакую под вин7. Пришлось отказаться от проверки КС.
user456 вне форума   Ответить с цитированием
2 пользователя(ей) сказали cпасибо:
Konctantin (23.06.2010), zergtmn (23.06.2010)
Старый 23.06.2010, 00:31   #75
user456
Новичок
 
Регистрация: 31.03.2010
Сообщений: 22
Сказал(а) спасибо: 2
Поблагодарили 23 раз(а) в 8 сообщениях
user456 На верном пути
По умолчанию

да, сама структура "номер пакета" - "пакет"
Код:
  PSeqRec = ^TSeqRec;
  TSeqRec = packed record
    swappedSeq: dword;
    dataOffs,dataLen: dword;
    wsa_buf: WSABUF;
  end;

  TSeqArr = array of TSeqRec;
и вспомогательные функции
Код:
function GetDWordDiff(aLo,aHi: dword):dword;
begin
    if aHi >= aLo then result:=aHi - aLo
    else result:= maxdword - aLo + aHi;
end;

function GetIPHeaderLen(ih: PIPHeader): Word;  // IP header length
begin
     // multiply the low nibble by 4
     // and return the length in bytes
     Result := (ih.iph_verlen and $F) shl 2;
end;

function GetTCPDataOffset(th: PTCPHeader): Word;
begin
     // doff (data offset) stored in 32 bit words,
     // multiply the value by 4 to get byte offset
     Result := ((th.flags and $F0) shr 4) shl 2;
end;

function GetFlags(flags: word): string;
begin
     result := '' ;
     if (flags AND TCP_FLAG_FIN) = TCP_FLAG_FIN then result := result + 'FIN ';
     if (flags AND TCP_FLAG_SYN) = TCP_FLAG_SYN then result := result + 'SYN ';
     if (flags AND TCP_FLAG_RST) = TCP_FLAG_RST then result := result + 'RST ';
     if (flags AND TCP_FLAG_PSH) = TCP_FLAG_PSH then result := result + 'PSH ';
     if (flags AND TCP_FLAG_ACK) = TCP_FLAG_ACK then result := result + 'ACK ';
     if (flags AND TCP_FLAG_URG) = TCP_FLAG_URG then result := result + 'URG ';
     if (flags AND TCP_FLAG_ECH) = TCP_FLAG_ECH then result := result + 'ECH ';
     if (flags AND TCP_FLAG_CWR) = TCP_FLAG_CWR then result := result + 'CWR ';
     result := trim (result);
end;

function GetChecksum(lpBuf: pointer; count: integer; initial_value: word = 0):word;
var
   temp: integer;
begin
     //http://www.faqs.org/rfcs/rfc1071.html
     temp:=initial_value;
     while count > 1 do begin
           temp:=temp + PWord(lpBuf)^;
           inc(integer(lpBuf),sizeof(word));
           dec(count,sizeof(word));
     end;
     if count > 0 then
        temp:=temp + PByte(lpBuf)^;

     while (temp shr 16) <> 0 do
           temp:=(temp and $ffff) + (temp shr 16);

     result:= not(temp);
end;

Последний раз редактировалось user456; 23.06.2010 в 00:33.
user456 вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
zergtmn (23.06.2010)
Старый 23.06.2010, 08:55   #76
abdula123
Пользователь
 
Регистрация: 22.03.2010
Сообщений: 41
Сказал(а) спасибо: 7
Поблагодарили 25 раз(а) в 15 сообщениях
abdula123 На верном пути
По умолчанию

Цитата:
Сообщение от user456 Посмотреть сообщение
Так вот к нашим баранам: можно вообще делать под raw сокетами. Пакеты и правда могут приходить "всё в одном", с повторами, порезаные. Но логика сборки там простая. Я и такой сделал и он куда проще даже проксевого (с проксевым головняк лично у меня с критическими секциями, пока не отправлено надо ж что-то делать с новыми пакетами).

и вся та простыня кода называется "проще"???
ё-маё. как-же всё-таки любят некоторые усложнять себе жизнь.

у меня ВСЯ обработка соединений \ расшифровка \ лог \ зашифровка в разы меньше и проще, чем одно только это чтение и сборка tcp-пакетов.
abdula123 вне форума   Ответить с цитированием
Старый 23.06.2010, 11:24   #77
user456
Новичок
 
Регистрация: 31.03.2010
Сообщений: 22
Сказал(а) спасибо: 2
Поблагодарили 23 раз(а) в 8 сообщениях
user456 На верном пути
По умолчанию

Цитата:
Сообщение от abdula123 Посмотреть сообщение
и вся та простыня кода называется "проще"???
Это не "проще", это другой вариант. Другой уровень выхода на данные. В вашем такой код никуда не исчезает, просто им ось занимается.
user456 вне форума   Ответить с цитированием
Старый 24.06.2010, 17:31   #78
abdula123
Пользователь
 
Регистрация: 22.03.2010
Сообщений: 41
Сказал(а) спасибо: 7
Поблагодарили 25 раз(а) в 15 сообщениях
abdula123 На верном пути
По умолчанию

Цитата:
Сообщение от user456 Посмотреть сообщение
Это не "проще", это другой вариант. Другой уровень выхода на данные. В вашем такой код никуда не исчезает, просто им ось занимается.
код - имеется в виду код написанный для этой задачи.

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


так что в данном случае, это не только другой вариант, но еще и проще
abdula123 вне форума   Ответить с цитированием
Старый 02.07.2010, 12:41   #79
Йоха
Умный
 
Регистрация: 02.07.2010
Сообщений: 434
Сказал(а) спасибо: 27
Поблагодарили 73 раз(а) в 45 сообщениях
Йоха Скоро придёт к известности
По умолчанию

Приветствую,
решил написать свой сниффер, больше из спортивного интереса. В ВоВ играю на офе с 2006 года.
По образованию программист, но уже достаточно давно не кодил ничего

Долого выбирал каким способом перехватывать трафик, сперва была идея сделать свой TDI фильтр драйвер и перенаправлять весь трафик идущий от приложения wow.exe в пользовательское приложение. Почитав DDK на тему создания TDI фильтров - понял что такой подход это как из пушки по воробьям. Слишком сложно.

использовать pcap мне почему-то не понравилось ... И с первого взгляда я не нашел как фильтровать трафик от конкретного приложения.

RAW сокеты - неплохой вариант, один минус - слишком много рутинного кода по обработке сырого tcp потока. Хотя если один раз написать и отладить эту часть или воспользоваться какими-нибудь готовыми наработками, то тоже вполне достойный вариант. Однако у меня нет готовых решений, поэтому пропускаем. Так же проблема с определением к какому приложению относится трафик

Больше всего понравился вариант предложеный abdula123. По сути это и есть первый вариант с TDI фильтром, только фильтр уже написан и отлажен хорошими людьми . Я использую proxifier (www.proxifier.com)
Плюсом такого подхода так же является платформонезависимость, посколько этот проксификатор работает на всех версиях виндовс. К тому же у этого проксификатора есть portable версия, не требующая установки.

Настраиваем правило, для приложения wow весь трафик перенаправлять на localhost, наш порт. И все, весь поток данных от wow.exe у нас.
SOCKS4 - примитивнешйи протокол, имеющий всего две команды CONNECT и BIND.
CONNECT - это запрос на установку соединения с удаленным хостом.
BIND - запрос на открытие порта в режиме прослушивания (для принятия соединений)

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

В общем скачав VisualStudio2010, со скрипом вспоминал програмирование с использованием сокетов. Вчера много тупил, сегодня мой прокси отлично работает. Во всяком случае все приложения с использованием SOCKS4 прокси, и вов через проксифиер - работает без проблем.
Если есть желание, могу показать код, всего 290 строк -)

Двигаемся дальше, вставляем теперь непосредственно разбор трафика вов.
В связи с этим вопрос по поводу получения ключа. Его можно считать на лету ? или только выдергивать из памяти роцесса ?

Последний раз редактировалось Йоха; 02.07.2010 в 12:45.
Йоха вне форума   Ответить с цитированием
Старый 02.07.2010, 13:32   #80
Deamon
WowCore Dev
 
Регистрация: 11.03.2010
Сообщений: 112
Сказал(а) спасибо: 10
Поблагодарили 51 раз(а) в 25 сообщениях
Deamon Скоро придёт к известности
По умолчанию

Цитата:
Сообщение от Йоха Посмотреть сообщение
В связи с этим вопрос по поводу получения ключа. Его можно считать на лету ? или только выдергивать из памяти роцесса ?
Может быть его и можно считать на лету, но сейчас гораздо легче дергать ключ из памяти.
Deamon вне форума   Ответить с цитированием
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.



Текущее время: 05:20. Часовой пояс GMT +3.


ru-mangos.ru - Русское сообщество MaNGOS
Главная цель проекта MaNGOS - обучающая, поэтому разрешается использовать исходный код и собранную программу только для образовательных целей.
Вы не можете использовать MaNGOS в коммерческих целях, а также не разрешается устанавливать публичные серверы на базе MaNGOS.
Любое копирование материалов, информации в любом виде без указания источника - форума Ru-MaNGOS будет считаться нарушением авторских прав и нарушением Уголовного Кодекса РФ, ст. 146 ст. 147.
Перевод vBulletin: zCarot