PDA

Просмотр полной версии : Содержимое пакетов в своем "боте"


Kilatif
14.07.2011, 21:14
Решил побаловаться и для своих нужд создать что-то типа ООГ бота. Мучился, маялся, в итоге смог зайти в игру и отправить EnterWorld. А вот дальше, вроде казалось бы уже ничего препятствовать не должно было, ан нет, появилась проблемка.... Вполне возможно, что проблема очень легко решаема, но все же решил спросить, может кто знает в чем дело точно.

Итак....

После отправки EnterWorld у меня содержимое пакетов от сервера слишком большое, причем, как правило каждый новый пакет больше предыдущего размерами. Иногда первый после EnterWorld отображается нормально, а следующий уже начинает ерозить нечто непонятное, а иногда и даже первый пакет после EnterWorld уже какой-то корявый.

- Пакеты я смотрел прям с того момента, как их получал от сервера
- Бот мой стоит в гиране, т.е. поток пакетов достаточно большой, в других местах, где поток пакетов меньше не тестил (не успеваю, интернет фиг знает когда будет).
- Когда перехватываю своего бота L2phx-ом, то тот спокойно все показывает
- Когда юзал снифер пакетов (Wireshark), то там тоже пакеты от сервера были корявые, кроме первого (как и в моем боте)
- Сам бот вообще написан путем подправки выложенного негде тут парсера Логин-пакетов L2EmuSrc (не помню только кто выкладывал), в котором принцип работы с сокетами мной совершенно не был изменен

Если что-то забыл сказать, что нужно для того что бы мне можно было помочь - скажите - напишу.

Кто нибудь знает что это за ерезь?

P.S. У меня есть лишь одно объяснение всему этому - мой бот просто тупо не успевает обрабатывать пакеты и поэтому они накладываются друг на друга оО. Или же может это особенности работы с сервером, о которых я не знаю? Но я думаю врятли сервер будет присылать пакеты размером с 11 тыс. байт....

xkor
15.07.2011, 00:47
Kilatif, ты бы хоть код принимающий пакеты показал, а так гадать долго можно что там не так...

supernewbie
15.07.2011, 07:31
мб юзаешь расшифровку траффика от лса?

Kilatif
15.07.2011, 22:34
supernewbie, нет, дело совсем не в этом, ибо 1) я же дошел уже до EnterWorld. 2) Я написал, что анализирую пакеты сразу после того как их получаю и там уже сразу они слишком большие.


xkor, вот WMSOCK_RS_EVENT, в котором я принимаю пакеты (прошу не обращать внимания на всякие тупости, связанные с RecvPktCount и numpck, ибо это лишь тестовая версия :)):

procedure TForm1.WMSOCK_RS_EVENT(var Msg: TMessage);
var
SockError: integer;
Len:integer;
s : string;
begin
//проверка на ошибки
SockError:=WSAGetSelectError(Msg.lParam);
if (SockError<>0) then begin
if SockError=10053 then RichEdit1.Lines.Add('RS was Disconnected')
else RichEdit1.Lines.Add('RS error: '+inttostr(SockError));
CloseSock(RS_sock);
Exit;
end;
//если нет ошибок:
case WSAGetSelectEvent(Msg.lParam) of
FD_Read: begin
FillChar(main_buff,Length(main_buff),0);
Len:=recv(RS_Sock,main_buff,MAX_PKT_SIZE,0);
s := IntToStr(numpck) + '.txt';
numpck := numpck + 1;

if numpck > 100 then numpck := 101;
// SaveBuf(s, len);
inc(RecvPktCount);
if RecvPktCount > 13 then RecvPktCount := 14;

if RecvPktCount <= 4
then LS_parser(main_buff,Len)
else GS_parser(main_buff,Len);

end;
FD_Close: begin
RichEdit1.Lines.Add('RS was Disconnected');
CloseSocket(RS_Sock);
end;
end;
end;

Собственно из этого всего главная строка:
Len:=recv(RS_Sock,main_buff,MAX_PKT_SIZE,0);

и вот main_buff (main_buff: array[0..MAX_PKT_SIZE-1] of byte) у меня и заполняется до 11 или 16 кбайт

Вот, кстати, лог пакетов с моей программы (первых 2 после EnterWorld, а точнее 1 и лишь маленький кусок второго).
Пакеты декодированы:

Server MSG, Length: 200 (0xC8)
-------------------------------------------------------
0x0000| C8 00 0C DE BF 50 10 AC BF 0F 00 00 00 00 00 08
0x0010| 15 00 00 C8 9D FF FF 5A F4 FF FF A8 F5 00 00 00
0x0020| 00 00 00 F4 01 00 00 16 01 00 00 84 00 00 00 58
0x0030| 00 00 00 84 00 00 00 58 00 00 00 84 00 00 00 58
0x0040| 00 00 00 84 00 00 00 58 00 00 00 00 00 00 A0 99
0x0050| 99 F1 3F EC 5F A8 52 B3 07 F0 3F 00 00 00 00 00
0x0060| 00 F0 3F 00 00 00 00 00 00 89 40 00 00 00 00 00
0x0070| 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00
0x0080| 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0090| 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00A0| 02 00 00 00 00 00 00 00 F0 3F 00 00 00 00 00 00
0x00B0| 89 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00C0| 00 00 01 01 00 00 00 00


Server MSG, Length: 1231 (0x4CF)
-------------------------------------------------------
0x0000| 1F 00 2F DE BF 50 10 C8 1D 00 00 88 9B FF FF 49
0x0010| F4 FF FF 08 15 00 00 C8 9D FF FF 4A F4 FF FF ED
0x0020| F9 4C 10 CD E5 8E D0 73 9A EC B7 B8 92 A0 55 49
0x0030| A6 40 85 FC 58 61 48 19 6A 13 36 C8 92 A0 CD 5D
0x0040| A6 40 49 52 A7 9E 3E EA 95 EC 0A B8 92 A0 95 5D
0x0050| A6 40 01 53 A7 9E 70 EB 95 EC 0A B8 92 A0 95 5D
0x0060| A6 40 01 53 A7 9E 70 EB 95 EC B6 B8 92 00 54 C4
0x0070| 57 7F 51 0C 0F CC 9B EC 65 D3 B6 B8 92 A0 CD 5D
0x0080| 88 00 BD 53 A7 3E B1 72 D7 AC B6 B8 92 A0 CD 5D
0x0090| A6 40 BD 53 A7 9E 29 EB 95 EC B6 B8 92 A0 CD 5D
0x00A0| A6 40 BD 53 A7 9E 28 EB 95 EC B6 B8 92 A0 CD 5D
0x00B0| A6 40 BD 53 A7 9E 28 EB 95 EC B6 B8 92 A0 CD 5D
0x00C0| A6 40 BD 53 A7 9E 28 C5 D5 EC B6 B8 32 39 54 1F
0x00D0| E6 40 BD 53 A7 9E 28 EB 95 EC B6 B8 92 A0 CD 5D
0x00E0| A6 41 BC 53 A7 9E 28 17 0B 8D 58 8C 4F 11 71 37
0x00F0| 68 17 FA F9 38 3F 64 0B 54 81 DF BC F2 FE 21 5D
0x0100| 98 E8 FB 79 38 3F 6C 19 54 81 03 13 0D 01 9F AE
0x0110| 67 17 47 F9 38 3F 34 19 54 81 4B 12 0D 01 D1 AF
0x0120| 67 17 47 F9 38 3F 34 19 54 81 4B 12 0D 01 D1 AF
0x0130| 67 17 FB F9 38 9F F5 80 A5 BE 1B 4D A5 53 3A A8
0x0140| 97 28 FB F9 38 3F 6C 19 7A C1 F7 12 0D A1 10 36
0x0150| 25 57 FB F9 38 3F 6C 19 54 81 F7 12 0D 01 88 AF
0x0160| 67 17 FB F9 38 3F 6C 19 54 81 F7 12 0D 01 89 AF
0x0170| 67 17 FB F9 38 3F 6C 19 54 81 F7 12 0D 01 89 AF
0x0180| 67 17 FB F9 38 3F 6C 19 54 81 F7 12 0D 01 89 81
0x0190| 27 17 FB F9 98 A6 F5 5B 14 81 F7 12 0D 01 89 AF
0x01A0| 67 17 FB F9 38 3F 6C 19 54 80 F6 12 0D 01 89 6E
0x01B0| F9 4C 0D CD E5 8E D0 73 9A 10 B1 B8 92 A0 25 4F
0x01C0| A6 40 B5 FC 58 61 48 19 6A EF AB 55 92 A0 CD 5D
0x01D0| A6 40 49 52 A7 9E 3E EA 95 10 0C B8 92 A0 95 5D
0x01E0| A6 40 01 53 A7 9E 70 EB 95 10 0C B8 92 A0 95 5D
0x01F0| A6 40 01 53 A7 9E 70 EB 95 10 B0 B8 92 00 54 C4
0x0200| 57 7F 51 0C 0F CC 9B EC 65 2F B0 B8 92 A0 CD 5D
0x0210| 88 00 BD 53 A7 3E B1 72 D7 50 B0 B8 92 A0 CD 5D
0x0220| A6 40 BD 53 A7 9E 29 EB 95 10 B0 B8 92 A0 CD 5D
0x0230| A6 40 BD 53 A7 9E 28 EB 95 10 B0 B8 92 A0 CD 5D
...............
...............
...............
...............

А вот лог первых 3 пакетов после EnterWorld в l2phx, который перехватывает мою прогу для того же соединения:
03810660417CE4E340 C800 0C DEBF5010ACBF0F000000000008150000C89DFFFF5AF4FFFFA8 F5000000000000F40100001601000084000000580000008400 00005800000084000000580000008400000058000000000000 A09999F13FEC5FA852B307F03F000000000000F03F00000000 00008940000000000000000000000000010000000000000000 00000000000000000000000000000000000000000000000000 000000000000000200000000000000F03F0000000000008940 00000000000000000000000000000000010100000000
03251960417CE4E340 1F00 2F DEBF5010C81D0000889BFFFF49F4FFFF08150000C89DFFFF4A F4FFFF
03CA2B60417CE4E340 C800 0C AD9E4210F8980F00010000009814000038AFFFFF60F2FFFF80 70000000000000F401000016010000BC00000058000000BC00 000058000000BC00000058000000BC00000058000000000000 A09999F13FEC5FA852B307F03F0000000000002E40000000A0 99994240000000000000000000000000010000000000000000 00000000000000000000000000000000000000000000000000 0000000000000000000000000000002E40000000A099994240 00000000000000000000000000000000010100000000

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

Yegor
15.07.2011, 23:28
Kilatif, не вижу в процедуре приема контроля длины пакета. Где ты проверяешь сколько реально байт считано с сокета, совсем не обязательно в буфере приема будет весь пакет? Думаю что проблема начинается при приеме первого большого пакета который нужно считывать с сокета более чем за 1 прием.

Kilatif
15.07.2011, 23:40
Yegor, Ну как бы у меня все пакеты помещаются в мой буфер вполне нормально. Пакеты всегда приходят разной длинны, а не какой-то предположительно максимально фиксированной (т.е. например у меня буфер на 16 кб, а приходит всегда фиксировано 14 кб, т.е. сокет обрезает как-то, нет, такого нет). Ну и если проанализировать даже вот те логи, которые я скинул, то видно, что вроде как после той части, что я выделил жирным цветом (это в l2phx полностью второй пакет) сразу должно быть C8 00 - размер следующего пакета, а там не понятно что....

Yegor
16.07.2011, 00:07
Kilatif,уверен что первый пакет принят полностью? Дело не в размере буфера а в том что интернет имеет задержки, и пакеты могут доставляться за несколько приемов даже весьма небольшого размера.

1.Не вижу отдельно приема первых 2х байт из буфера чтобы узнать реальную длину пакета.

2.Почему из буфера пытаешься прочитать сразу все содержимое?
Len:=recv(RS_Sock,main_buff,MAX_PKT_SIZE,0);
В буфере может быть сразу несколько пакетов.


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

supernewbie
16.07.2011, 04:04
В любом случае для безошибочного приема пакета необходимо сначала считывать его длину (первых 2 байта), а затем читать с сокета до той поры пока эта (длина - 2 байта)
на логин сервере тоже 2 байта длинна идет вначале? или только на гейм?

Kilatif
16.07.2011, 10:59
Yegor, хорошо... свои ошибки в приеме пакета в сокете я понял. Но или я тебя понял не до конца или ты меня не понял, но... Если ты говоришь, что несколько пакетов может придти за раз, то почему в моем втором принятом пакете после куска правильного (жирным цветом выделено) не начинается 3ий пакет (пусть и в зашифрованном виде)? Ведь это на мой взгляд было бы логично. Т.е. там сразу после выделенного жирным ведь по логике должно идти первых два байта размера третьего пакета, но там этого вовсе нет.

Добавлено через 1 минуту
supernewbie, да и на логин тоже первых 2 байта это размер пакета.

supernewbie
16.07.2011, 12:37
хм, можно тада тыкнуть пальцем где в l2clientemu при парсе пакетов логин серва идет взятие инфы о длинне из этих двух байтов?

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

Kilatif
16.07.2011, 15:53
supernewbie, я не думаю что будет игнорироваться размер следующего пакета, при отправке сразу нескольких, ведь если игнорируется длина следующего пакета, как тогда узнать настоящую длину при таком слиянии? =)

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

Yegor
17.07.2011, 00:49
supernewbie, да в l2clientemu этот момент упрощен, я тоже изначально по нему учился работать с пакетами и потом очень долго искал в чем ошибка когда сбивалась шифрация пакетов.


Kilatif, а на каком сервере ты тестируешь? Там точно нет доп нестандартной шифрации?


В твоих логах второй пакет начинается с 1F 00 а в заголовке указано что Length: 1231 (0x4CF), откуда взяты эти цифры?

Kilatif
17.07.2011, 11:07
это число взято при приеме пакета из сокета, т.е. это то самое Len, а не размер из первых 2 байт. ну и я не думаю, что на том серве есть доп шифрация, ибо l2phx видит все нормально, при этом я не использую никаких newxor.dll и даже обход смены xor. ну а вообще, это шоки =)

xkor
17.07.2011, 20:18
хм, можно тада тыкнуть пальцем где в l2clientemu при парсе пакетов логин серва идет взятие инфы о длинне из этих двух байтов?
из за того что логин сервер не посылает подряд больше одного пакета между посылками клиента (и наоборот тоже), а так же учитывая малый размер пакетов, то при общении с логин сервером крайне маловероятно получить TCP пакет (хотя TCP потоковый протокол и правильнее названить это просто порцией данных) не равный игровому пакету, а вот с геймом дело обстоит не так идеально и от него может одной порцией приходить любое, в том числе и дробное количество игровых пакетов, так что там надо обязательно ориентироваться на первые два байта перед каждым пакетом.
ЗЫ через пакетхак всё пашет потому что он разбирает на пакеты и в сокет для твоего бота пакеты попадают "правильными" порциями, а поскольку пакетхак и бот на одном компе то трафик между ними уже не обрабатывается никакими маршрутизаторами и аналогичными устройствами которые могут "склеивать пакеты"

Добавлено через 3 минуты
Ну и если проанализировать даже вот те логи, которые я скинул, то видно, что вроде как после той части, что я выделил жирным цветом (это в l2phx полностью второй пакет) сразу должно быть C8 00 - размер следующего пакета, а там не понятно что....ну дык правильно, у тебя же этот размер типо "дешифровался" вот он и превратился в хз что ибо после реального конца второго пакета шифрация вся сбивается и начинает лишь корёжить данные

Kilatif
18.07.2011, 00:28
ну дык правильно, у тебя же этот размер типо "дешифровался" вот он и превратился в хз что
Ну вот, я же говорю что скорее всего все легко решаемо. :D Спасибо большое за помощь.

Добавлено через 1 час 17 минут
Теперь другая проблема... Ну не столько проблема, сколько очень любопытно, что же это? В общем... После каждого второго пакета NpcInfo (и только его) приходит 8 байт непонятно чего. Причем именно после каждого второго, не больше, не меньше. Это с чем-нибудь конкретно связано?

P.S. В l2phx все также отображается нормально, размер байт все так же является 200 для NpcInfo, не смотря на эти 8 байт лишних после каждого второго пакета.
P.P.S. Пакеты я смотрел Wireshark-ом, а не своей программой.

Yegor
18.07.2011, 00:54
Kilatif, как warshark может разбивать непрерывный поток шифрованных данных от L2 сервера на пакеты?
И как отображает эти пакеты пакетхак? Вообще никак?

Kilatif
18.07.2011, 14:48
Yegor, пакеты от wireshark разбивал я сам, учитывая первых 2 байта каждого пакета, что это размер. в пакетхаке отображаются они нормально, никаких лишних 8 байт нет. Я бы не интересовался бы этим, но просто в моей проге эти 8 байт мне мешают нормально читать пакеты, а считать каждый второй NpcInfo как то не хочется =)

Yegor
18.07.2011, 19:24
Kilatif, дык может wireshark добавляет какую то служебгную информцию?

Kilatif
19.07.2011, 11:00
Yegor, дык я ж говорю, эти 8 байт появляются и в моей программе, вот и получается что после 2 пакетов NpcInfo моя прога ловит эти 8 байт и начинает искать там в первых 2 байтах размер пакета, а в них этого нет.

Kilatif
20.07.2011, 17:04
В общем эти 8 байт моя ошибка.. Все нормально, проблема исчерпана наконец =)

Добавлено через 6 минут
У меня еще один вопрос есть... Вот есть сокет, он принял кусок данных. Этот кусок данных будет хранится в сокете до тех пор пока я его не прочитаю или он может стереться, если я его не успею прочитать? Пример:
Есть в сокете 10 пакетов я читаю из сокета 1 пакет, потом очень долго его обрабатываю, когда в следующий раз читаю сокет - он мне выдает уже 5-ый допустим, а первых 2-4 так и не выдает. Может быть такое? Или сокет будет ждать до тех пор пока я не заберу у него очередную порцию информации?

supernewbie
20.07.2011, 18:02
ниче такого, ты же проста данные читаешь, куда они денуца

Yegor
20.07.2011, 18:55
При создании сокета для приема пакетов выделяется буфер определенного размера. Точно не уверен но по моему если он переполниться то новые данные система принимать не будет, а так как прием ведется по протоколу TCP в которому гарантируется сохранность информации, то сервер не будет слать новых пакетов пока мы не освободим буфер и соответственно просто нас дисконектнет по таймауту через некоторое время.