Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Хук функций winsock

1.9K
29 мая 2006 года
disasm
232 / / 06.02.2006
Помогите! Пишу прогу, которая имеет WoW.exe по нужнам API функциям. Нужно ли мне при перехвате функций
recv
recvfrom
send
sendto
дублировать дескрипторы сокетов? Если да, то как это сделать???
Пробовал захукать connect без изменения запроса (т.е. в хуке вызывается родной коннект с теми же параметрами), а он обламывается...
Я еще веду перехват GetProcAddress и если ВоВ запрашивает одну из функций, которую перехватывает моя прога, то функция возвращает адрес моей функции - хука.
406
29 мая 2006 года
vitaly2003s
481 / / 27.07.2004
Цитата:
Originally posted by disasm
Помогите! Пишу прогу, которая имеет WoW.exe по нужнам API функциям. Нужно ли мне при перехвате функций
recv
recvfrom
send
sendto
дублировать дескрипторы сокетов? Если да, то как это сделать???
Пробовал захукать connect без изменения запроса (т.е. в хуке вызывается родной коннект с теми же параметрами), а он обламывается...
Я еще веду перехват GetProcAddress и если ВоВ запрашивает одну из функций, которую перехватывает моя прога, то функция возвращает адрес моей функции - хука.


Зачем те перехватывать пакеты? Ты знаеш заголовки и формат передаваемых данных и их содержимое? Есть спецификация или еще что?

1.9K
30 мая 2006 года
disasm
232 / / 06.02.2006
Цитата:
Originally posted by vitaly2003s
Зачем те перехватывать пакеты? Ты знаеш заголовки и формат передаваемых данных и их содержимое? Есть спецификация или еще что?


Формат содержимого не нужен вообще.
Мне надо только лишь защитить пакеты от изменения
(WPE PRO, ...).
Для этого я перехватываю исходные данные, а отправляю закодированные.
Изначально данные не шифруються и в то же время во время передачи возникают ошибки. Не может ли это быть связано с тем, что хук, в отличие от главного модуля, может "не знать" каких-либо дескрипторов сокетов? Т.е. если бы отправлял главный модуль, то все ОК, а если отправляет мой хук то отправка идет в "неизвестный сокет".

406
30 мая 2006 года
vitaly2003s
481 / / 27.07.2004
Цитата:
Originally posted by disasm
Формат содержимого не нужен вообще.
Мне надо только лишь защитить пакеты от изменения
(WPE PRO, ...).
Для этого я перехватываю исходные данные, а отправляю закодированные.
Изначально данные не шифруються и в то же время во время передачи возникают ошибки. Не может ли это быть связано с тем, что хук, в отличие от главного модуля, может "не знать" каких-либо дескрипторов сокетов? Т.е. если бы отправлял главный модуль, то все ОК, а если отправляет мой хук то отправка идет в "неизвестный сокет".


Интересно ты знаеш как пользоваться WPE PRO,perm_edit,bwh поведуй или скинь мне на ящик инфу. А насчет сокетов,это надо смотреть каким образом перехватываемая функция отправляет данные. приведи участок кода ответсвенный за данное действие.

1.9K
31 мая 2006 года
disasm
232 / / 06.02.2006
Цитата:
Originally posted by vitaly2003s
Интересно ты знаеш как пользоваться WPE PRO,perm_edit,bwh поведуй или скинь мне на ящик инфу. А насчет сокетов,это надо смотреть каким образом перехватываемая функция отправляет данные. приведи участок кода ответсвенный за данное действие.


Конкретного руководства по читам нет, толком я не разобрался сам.
А вот функция перехвата

int WINAPI I_recv(SOCKET s, char FAR* buf, int len, int flags)
{
int f_res;
BYTE* buff;
HGLOBAL mem;
DWORD crc;

mem=GlobalAlloc(GMEM_FIXED+GMEM_ZEROINIT,len);
if(!mem) return SOCKET_ERROR;
//
f_res=precv(s,(char FAR*)mem,len,flags);
if(f_res==SOCKET_ERROR)
{
GlobalFree(mem);
if(f_res==SOCKET_ERROR) send_log_message(s,"recv ERROR 2 ");
else send_log_message(s,"recv ERROR 3 ");
return SOCKET_ERROR;
}
/*crc=crc_data((PVOID)mem,f_res-4);
if(crc != *(DWORD*)((DWORD)mem+f_res-4))
{
GlobalFree(mem);
return SOCKET_ERROR;
}*/ // это проверка CRC32 на совпадение
//CopyMemory((PVOID)buf,(PVOID)mem,f_res-4);
CopyMemory((PVOID)buf,(PVOID)mem,f_res);
GlobalFree(mem);
return f_res;
}

int WINAPI I_send(SOCKET s, const char FAR* buf, int len, int flags)
{
int f_res;
DWORD crc;
HGLOBAL mem;

//mem=GlobalAlloc(GMEM_FIXED+GMEM_ZEROINIT,len+4);
//if(!mem) return SOCKET_ERROR;

//CopyMemory((PVOID)mem,(PVOID)buf,len);
//crc=crc_data((PVOID)buf,len);
//*(DWORD*)((DWORD)mem+len)=crc;

//f_res=psend(s,(const char FAR*)mem,len+4,flags);
f_res=psend(s,(const char FAR*)buf,len,flags);
//GlobalFree(mem);
if(f_res==SOCKET_ERROR) return SOCKET_ERROR;
//
send_log_message(s,"send ok");
return f_res;
}

В функции I_send так вообще преобразований не стоит...

psend,precv - указатели на функции, выдранные еще
при запуске проги из wsock32.dll

406
31 мая 2006 года
vitaly2003s
481 / / 27.07.2004
Насчет psend и precv я что то сомневаюсь покажи их объявление,но это потом. Каким образом у тебя происходит подмена оригинальных функций(send,recv) на свои(I_send,I_recv)? В чем проблема в каких именно строчках,в каких функциях,какой возвращяемый код ошибки. По твоему в каком контексте происходит вызов твоих функций(I_send,I_recv) - в твоем или в перехватываемом. Где расположены данные функции((I_send,I_recv,psend,precv)- exe или dll?
1.9K
31 мая 2006 года
disasm
232 / / 06.02.2006
Цитата:
Originally posted by vitaly2003s
Насчет psend и precv я что то сомневаюсь покажи их объявление,но это потом. Каким образом у тебя происходит подмена оригинальных функций(send,recv) на свои(I_send,I_recv)? В чем проблема в каких именно строчках,в каких функциях,какой возвращяемый код ошибки. По твоему в каком контексте происходит вызов твоих функций(I_send,I_recv) - в твоем или в перехватываемом. Где расположены данные функции((I_send,I_recv,psend,precv)- exe или dll?



1.
pLoadLibrary=LoadLibrary;
pGetProcAddress=GetProcAddress;
...
ws32=pLoadLibrary("wsock32.dll");
precv=(PRECV)pGetProcAddress(ws32,"recv");
precvfrom=(PRECVFROM)pGetProcAddress(ws32,"recvfrom");
psend=(PSEND)pGetProcAddress(ws32,"send");
psendto=(PSENDTO)pGetProcAddress(ws32,"sendto");

2.
Метод внедрения - подмена адресов в таблицах импорта. Работает на 100%. Хуки вызываются на 100%.

3.
Мои хуки вызываются из главного процесса, а не из его библиотек, т.к. подмену адресов я делаю только в главном процессе WoW.

4.
Хуки расположены в DLL. эта DLL расположена в адресном пространстве процесса WoWа - я делал LoadLibrary из потока главного процесса.

5.
После инжекта исчезает загрузочный модуль, остается только WoW и моя библиотека.

6.
int WINAPI I_recv(SOCKET s, char FAR* buf, int len, int flags)
{
int f_res;
BYTE* buff;
HGLOBAL mem;
DWORD crc;

mem=GlobalAlloc(GMEM_FIXED+GMEM_ZEROINIT,len);
if(!mem) return SOCKET_ERROR;
//
f_res=precv(s,(char FAR*)mem,len,flags);
if(/*(f_res<=4) || */f_res==SOCKET_ERROR)
{
GlobalFree(mem);
if(f_res==SOCKET_ERROR) send_log_message(s,"recv ERROR 2 "); <<< Тут ошибка, в игре "disconnected from server"
else send_log_message(s,"recv ERROR 3 ");
return SOCKET_ERROR;
}
/*crc=crc_data((PVOID)mem,f_res-4);
if(crc != *(DWORD*)((DWORD)mem+f_res-4))
{
GlobalFree(mem);
return SOCKET_ERROR;
}*/ // это проверка CRC32 на совпадение
//CopyMemory((PVOID)buf,(PVOID)mem,f_res-4);
CopyMemory((PVOID)buf,(PVOID)mem,f_res);
GlobalFree(mem);
return f_res;
}

Перед этим 3 recv с этого же сокета проходят нормально...

Логи:
[31-5-2006 13:59:6] socket af=2, type=SOCK_STREAM, proto=0
[31-5-2006 13:59:6] socket result=0
[31-5-2006 13:59:6] socket af=2, type=SOCK_STREAM, proto=0
[31-5-2006 13:59:6] socket result=1
[31-5-2006 13:59:11] socket af=2, type=SOCK_STREAM, proto=0
[31-5-2006 13:59:11] socket result=3
[31-5-2006 13:59:11] send from 3
[31-5-2006 13:59:11] send ok from 3
[31-5-2006 13:59:12] recv from 3
[31-5-2006 13:59:12] send from 3
[31-5-2006 13:59:12] send ok from 3
[31-5-2006 13:59:12] recv from 3
[31-5-2006 13:59:12] send from 3
[31-5-2006 13:59:12] send ok from 3
[31-5-2006 13:59:12] recv from 3
[31-5-2006 13:59:12] socket af=2, type=SOCK_STREAM, proto=0
[31-5-2006 13:59:12] socket result=4
[31-5-2006 13:59:12] recv from 4
[31-5-2006 13:59:12] recv from 4
[31-5-2006 13:59:12] recv from 4
[31-5-2006 13:59:12] recv ERROR 2 from 4

Цифрами после from обозначены условные номера сокетов.
После socket result= - они же.

PS: После ошибки "recv ERROR 2" WSAGetLastError возвращает 0!!!???

406
31 мая 2006 года
vitaly2003s
481 / / 27.07.2004
Насчет пункта 2 не согласен,почитай в нете о подмене импорта для winsock функций,скоко багов у людей на этом. Не очень надежно.

Попробуй сделать так для начала:

int WINAPI I_recv(SOCKET s, char * buf, int len, int flags)
{
return precv(s,buf,len,flags);
}

и аналогично для I_send

терь инжекть такую длл и смотри не будет ли сбоев в вове. затем сообщиш результаты. Если будет такая же хрень то скорее всего это будет нестабильность данного подхода если же нет будем смотреть дальше.
1.9K
31 мая 2006 года
disasm
232 / / 06.02.2006
Глюканул.

if((f_res<=4) || (f_res==SOCKET_ERROR))
{
GlobalFree(mem);
if(f_res==SOCKET_ERROR) send_log_message(s,"recv ERROR 2 ");
else send_log_message(s,"recv ERROR 3 ");
//send_log_message_error(s,err);
return SOCKET_ERROR;
}

Надо

if((f_res<=4) || (f_res==SOCKET_ERROR))
{
err=WSAGetLastError();
GlobalFree(mem);
if(f_res==SOCKET_ERROR) send_log_message(s,"recv ERROR 2 ");
else send_log_message(s,"recv ERROR 3 ");
//send_log_message_error(s,err);
WSASetLastError(err);
return SOCKET_ERROR;
}

Проверил. Работает, правда в игре пинг под 3000.
Добавил подсчет CRC - стала игра вылетать.
Полная версия хуков во вложении.
18K
01 июня 2006 года
ADMAX
4 / / 01.06.2006
Вообще я сделал подобное только для DarkSwords. Но можно сделать проще: создать свою библиотеку WSOCK32 и положить её рядом с исполнимым файлом.
406
01 июня 2006 года
vitaly2003s
481 / / 27.07.2004
Зачем те нужен подсчет crc не пойму? Если нужен то его суть и алгоритм.
1.9K
01 июня 2006 года
disasm
232 / / 06.02.2006
Цитата:
Originally posted by vitaly2003s
Вообще я сделал подобное только для DarkSwords. Но можно сделать проще: создать свою библиотеку WSOCK32 и положить её рядом с исполнимым файлом.


Можно конечно. Но приложение может воспользоваться методом LoadLibrary/GetProcAddress, и тогда все рухнет.

Цитата:
Originally posted by vitaly2003s
Зачем те нужен подсчет crc не пойму? Если нужен то его суть и алгоритм.


Я пишу античит. Я должен защитить данные от изменения читами или хотя бы обнаружить это изменение. Для этого после каждого пакета я отправляю контрольную сумму этого пакета. Если произойдет изменение то изменится содержимое пакета и/или контрольная сумма. При получении пакета сервером хук на сервере сверяет контрольную сумму с реальной и если они не равны, то делает вид, что произошла ошибка сокета.
Контрольная сумма считается на сервере и на клиенте одним и тем же алгоритмом и одним и тем же полиномом (я бы даже сказал одним и тем же кодом).

--- Код, реализующий подсчет CRC32 ---
#include <windows.h>

// standart polynom
#define CRC_POLYNOM 0xedb88320

// non-standart polynom
//#define CRC_POLYNOM 0xde8b3802

DWORD crc_table[256];
DWORD crc_poly=0;

void crc_calc_table(DWORD poly)
{
int i,j;
DWORD z;

for(i=255;i>=0;i--)
{
z=i;
for(j=0;j<8;j++)
{
if(z & 1)
z = (z >> 1) ^ poly;
else
z >>= 1;
}
crc_table=z;
}
}

DWORD crc_data_polynom(DWORD poly,PVOID data,DWORD size)
{
DWORD i,crc;
BYTE b;

if(crc_poly!=poly) crc_calc_table(poly);
crc=(DWORD)(-1);
for(i=0;i<size;i++)
{
b=(BYTE)(crc & 0xff);
crc=crc >> 8;
b=b ^ (*(BYTE *)((DWORD)data+i));
crc=crc ^ crc_table;
}
return crc ^ ((DWORD)(-1));
}

DWORD crc_data(PVOID data,DWORD size)
{
return crc_data_polynom(CRC_POLYNOM,data,size);
}

DWORD crc_file(LPCSTR fname)
{
HFILE f;
DWORD crc;
int res;
BYTE c,b;

f=_lopen(fname,OF_READ);
if(f==HFILE_ERROR) return 0;

if(crc_poly!=CRC_POLYNOM) crc_calc_table(CRC_POLYNOM);
crc=(DWORD)(-1);
while(1)
{
res=_lread(f,&c,1);
if(res!=1) break;
b=(BYTE)(crc & 0xff);
crc=crc >> 8;
b=b ^ c;
crc=crc ^ crc_table;
}
_lclose(f);
return crc ^ ((DWORD)(-1));
}

1.9K
02 июня 2006 года
disasm
232 / / 06.02.2006
Нашел еще глюк:

#define ENABLE_LOGGING
...
В коде хуков
#ifdef ENABLE_LOGGING
log_data(1,(PVOID)mem,f_res);
#endif

Из-за этого пинг у меня поднимался аж до 17000.
Когда убрал "#define ENABLE_LOGGING" - 2ms

Еще одна проблема (и самая главная):
Мой хук не перехватывает ни одной функции сети WowEmu. Надо искать другие методы. Вы можете мне что-нибудь предложить? Есть какие-нибудь другие подходы?
Есть ли какой-нибудь метод, который подходит и для WoWWoW (он на C#.NET написан)?
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог