08-02-2016, 10:05 PM
К сожалению, без отправки пакетов на клиент - никак.
C++ перехват пакетов
|
08-02-2016, 10:05 PM
К сожалению, без отправки пакетов на клиент - никак.
08-02-2016, 10:14 PM
Почему?
Zubastic Написал:Это понятно, но как быть с размером структуры?) Клиент знает один размер, а я заменяю его другим размером. На сколько я помню, клиент при удалении берет размер из UNetworkPacket, так что самое простое, хук на DispatchNetworkQueue, дальше, если нужен чисто свой пакет, то через малок выделил память, правильно заполнил поля, и клиент сам его нормально удалит. Второй вариант, нужно подхачить чужой пакет, тогда вызываешь оригинал, меняешь, отдаешь клиенту. Третий вариант, самый противный, но тоже ничего сложного, это когда нужно чужой пакет расширить, например html, multisell, ну или дописать каждому, кто пишет в чат, его профу перед ником, мало ли что в голову взбредет. В этом случае вызываем оригинал, сохраняем пакет к себе куда нибудь, можно на стек, потом удаляем пакет через free, выделяем сколько нужно места malloc'ом, копируем туда пакет со стека, расширяем, как надо, и отдаем клиенту. Во всех случаях нужно не забывать фиксить размер в структуре пакета, или будет падать Добавлено через 3 минуты flopix Написал:Я когда писал торгового бота для руоффа обошелся без отправки пакетов клиенту, зачем это вам? Например, можно выводить менюшки динамические, с длительностью эффектов/еще чем то, писать в чатик статистику, и много других интересных вещей. flopix Написал:Я когда писал торгового бота для руоффа обошелся без отправки пакетов клиенту, зачем это вам?Обмануть клиент: например, вывод информации о каком-либо действии или же что-то еще. Добавлено через 8 минут f1redark Написал:На сколько я помню, клиент при удалении берет размер из UNetworkPacket, так что самое простое, хук на DispatchNetworkQueue, дальше, если нужен чисто свой пакет, то через малок выделил память, правильно заполнил поля, и клиент сам его нормально удалит. Второй вариант, нужно подхачить чужой пакет, тогда вызываешь оригинал, меняешь, отдаешь клиенту. Третий вариант, самый противный, но тоже ничего сложного, это когда нужно чужой пакет расширить, например html, multisell, ну или дописать каждому, кто пишет в чат, его профу перед ником, мало ли что в голову взбредет. В этом случае вызываем оригинал, сохраняем пакет к себе куда нибудь, можно на стек, потом удаляем пакет через free, выделяем сколько нужно места malloc'ом, копируем туда пакет со стека, расширяем, как надо, и отдаем клиенту. Во всех случаях нужно не забывать фиксить размер в структуре пакета, или будет падатьИзменяли размер существующего пакета в структуре, как и изменяли указатель данных. В итоге крит Вопрос в подмене 1го пакета и добавлении его одного. f1redark Написал:Например, можно выводить менюшки динамические, с длительностью эффектов/еще чем то, писать в чатик статистику, и много других интересных вещей.Именно так
08-02-2016, 11:00 PM
Zubastic Написал:Обмануть клиент: например, вывод информации о каком-либо действии или же что-то еще. Да, перепутал, там бестолку менять, free из пула берет размер, а не из пакета. Ну тогда каждый раз сам выделяй, формируй пакет, и отдавай клиенту)
08-02-2016, 11:11 PM
f1redark Написал:Да, перепутал, там бестолку менять, free из пула берет размер, а не из пакета. Ну тогда каждый раз сам выделяй, формируй пакет, и отдавай клиенту)Если честно не совсем понимаю как это сделать, чтобы не словить критец
08-02-2016, 11:33 PM
Кто-то наигрался с u и решил копать глубже? Хватит насиловать бедный клиент
Aka Stels
08-02-2016, 11:35 PM
Shayne Написал:Кто-то наигрался с u и решил копать глубже? Хватит насиловать бедный клиент
08-03-2016, 01:34 PM
В принципе ничего сложного. Ниже пример, который перед приходом любого сообщения в общий чат (белый), отправляет клиенту новый пакет, в котором изменяется ник, и тип чата, так же перед текстом добавляется текущее время отправки). Код на скорую руку, многие вещи можно повыносить в классы\функции, и т п, с другой стороны, это просто пример, так что сойдет) Hf.
[SRC="c++"] #pragma pack(push, 1) struct UNetworkPacket { uint8_t id; uint8_t res; uint16_t id2; uint32_t size; void *data; }; struct CreatureSayPartialPacket { uint32_t object_id; uint32_t text_type; }; #pragma pack(pop) using GMallocType = void * (*) (wchar_t *type, uint32_t size); using GFreeType = void (*) (void *addr); using DispatchNetworkQueueType = int(__fastcall *)(void *This, int, UNetworkPacket **packet); DispatchNetworkQueueType DispatchNetworkQueueOrig = nullptr; //-- //-- //-- //-- void *gmalloc(uint32_t alloc_size) { static const auto gmalloc_export_name = "?GMalloc@@3PAVFMalloc@@A"; static const auto gmalloc_export = reinterpret_cast<void **>( GetProcAddress( GetModuleHandleA("core.dll"), gmalloc_export_name)); static const auto fmalloc_object = *gmalloc_export; static const auto gmalloc = ***reinterpret_cast<GMallocType ***>(gmalloc_export); __asm { push 0 push alloc_size mov ecx, fmalloc_object call gmalloc } } void gfree(void *addr) { static const auto gmalloc_export_name = "?GMalloc@@3PAVFMalloc@@A"; static const auto gmalloc_export = reinterpret_cast<void **>( GetProcAddress( GetModuleHandleA("core.dll"), gmalloc_export_name)); static const auto fmalloc_object = *gmalloc_export; static const auto gfree = *(**reinterpret_cast<GMallocType ***>(gmalloc_export) + 2); __asm { push addr mov ecx, fmalloc_object call gfree } } std:tring current_time() { time_t now = time(0); tm tstruct; char buf[0x10]; localtime_s(&tstruct, &now); strftime(buf, sizeof(buf), "%X", &tstruct); // strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct); return std:tring(buf); } int __fastcall DispatchNetworkQueue(void *This, int, UNetworkPacket **packet) { static const uint8_t creature_say_id = 0x4a; UNetworkPacket *current_packet = nullptr; static std::queue< UNetworkPacket * > packets; //-- //-- int result = 0; if (!packets.empty()) { *packet = packets.front(); packets.pop(); result = 1; } else { // Call original func result = (*DispatchNetworkQueueOrig)(This, 0, ¤t_packet); if (result) { *packet = current_packet; if (creature_say_id == current_packet->id) { auto creature_say_packet = reinterpret_cast<CreatureSayPartialPacket *>(current_packet->data); enum class ChatType : uint32_t { ALL = 0, HERO_VOICE = 17, }; if (ChatType::ALL == static_cast<ChatType>(creature_say_packet->text_type)) { //-- // Parse packet //-- auto ptr = reinterpret_cast<uint8_t *>(creature_say_packet); auto object_id = reinterpret_cast<uint32_t *>(ptr); ptr += sizeof(*object_id); auto text_type = reinterpret_cast<uint32_t *>(ptr); ptr += sizeof(*text_type); auto char_name = reinterpret_cast<wchar_t *>(ptr); ptr += (wcslen(char_name) + 1) * sizeof(wchar_t); auto npc_string = reinterpret_cast<uint32_t *>(ptr); ptr += sizeof(*npc_string); auto text = reinterpret_cast<wchar_t *>(ptr); ptr += (wcslen(text) + 1) * sizeof(wchar_t); //-- //-- wchar_t new_char_name[] = L"GOD"; wchar_t new_text[0x200] = { 0 }; std:tring cur_time = current_time(); swprintf_s(new_text, L"[%S] %s", cur_time.c_str(), text); auto new_char_name_length = sizeof(new_char_name); auto new_text_length = (wcslen(new_text) + 1) * sizeof(wchar_t); auto new_packet_data_size = sizeof(*object_id) + sizeof(*text_type) + new_char_name_length + sizeof(*npc_string) + new_text_length; //-- //-- //-- // Create new packet //-- auto new_packet = reinterpret_cast<UNetworkPacket *>(gmalloc(sizeof(UNetworkPacket))); new_packet->id = creature_say_id; new_packet->id2 = 0xFFFF; new_packet->size = new_packet_data_size; new_packet->data = gmalloc(new_packet_data_size); ptr = reinterpret_cast<uint8_t *>(new_packet->data); *reinterpret_cast<uint32_t *>(ptr) = *object_id; ptr += sizeof(*object_id); *reinterpret_cast<uint32_t *>(ptr) = static_cast<uint32_t>(ChatType::HERO_VOICE); ptr += sizeof(*text_type); wcscpy_s(reinterpret_cast<wchar_t *>(ptr), new_char_name_length, new_char_name); ptr += new_char_name_length; *reinterpret_cast<uint32_t *>(ptr) = *npc_string; ptr += sizeof(*npc_string); wcscpy_s(reinterpret_cast<wchar_t *>(ptr), new_text_length, new_text); ptr += new_text_length; //-- //-- *packet = new_packet; // Here we can delete old packet, or add it to queue for send to client // gfree(p->data); // gfree(p); packets.push(current_packet); } } } } return result; } void hook_dispatch_network_queue() { static const auto dispatch_network_queue_offset = 0x84; static const auto uobject_export_name = "??_7UNetworkHandler@@6BUObject@@@"; auto UNetworkHandler_vftable = reinterpret_cast<void **>( GetProcAddress( GetModuleHandleA("Engine.dll"), uobject_export_name)); auto DispatchNetworkQueueVMT = reinterpret_cast<DispatchNetworkQueueType *>( UNetworkHandler_vftable + dispatch_network_queue_offset / sizeof(UNetworkHandler_vftable)); DispatchNetworkQueueOrig = *DispatchNetworkQueueVMT; *DispatchNetworkQueueVMT = DispatchNetworkQueue; } DWORD WINAPI init_thread(LPVOID) { hook_dispatch_network_queue(); return 0; } [/SRC]
08-03-2016, 01:45 PM
Спасибо, вечером проверю, А модификация существующих пакетов работает корректно?
|
« Предыдущая | Следующая »
|
Возможно похожие темы ... | |||||
Тема | Автор | Ответы | Просмотры | Последний пост | |
Свой сниффер и редактор пакетов | 0 | 462 |
03-22-2024, 03:28 AM Последний пост: SiriusED |
||
Реконструкция пакетов из WSARecv\WSASend | 3 | 2,492 |
04-17-2016, 08:34 PM Последний пост: Necroz-Team |
||
Подмен пакетов | 4 | 3,091 |
06-16-2014, 07:24 PM Последний пост: PROGRAMMATOR |
||
Опкоды пакетов при хуке | 3 | 2,435 |
07-09-2013, 04:18 PM Последний пост: Mifesto |