Рейтинг темы:
  • 0 Голос(ов) - 0 в среднем
  • 1
  • 2
  • 3
  • 4
  • 5
C++ перехват пакетов
#71
К сожалению, без отправки пакетов на клиент - никак.
Ответ
#72
Почему?
Ответ
#73
Zubastic Написал:Это понятно, но как быть с размером структуры?) Клиент знает один размер, а я заменяю его другим размером.

На сколько я помню, клиент при удалении берет размер из UNetworkPacket, так что самое простое, хук на DispatchNetworkQueue, дальше, если нужен чисто свой пакет, то через малок выделил память, правильно заполнил поля, и клиент сам его нормально удалит. Второй вариант, нужно подхачить чужой пакет, тогда вызываешь оригинал, меняешь, отдаешь клиенту. Третий вариант, самый противный, но тоже ничего сложного, это когда нужно чужой пакет расширить, например html, multisell, ну или дописать каждому, кто пишет в чат, его профу перед ником, мало ли что в голову взбредет. В этом случае вызываем оригинал, сохраняем пакет к себе куда нибудь, можно на стек, потом удаляем пакет через free, выделяем сколько нужно места malloc'ом, копируем туда пакет со стека, расширяем, как надо, и отдаем клиенту. Во всех случаях нужно не забывать фиксить размер в структуре пакета, или будет падать

Добавлено через 3 минуты
flopix Написал:Я когда писал торгового бота для руоффа обошелся без отправки пакетов клиенту, зачем это вам?

Например, можно выводить менюшки динамические, с длительностью эффектов/еще чем то, писать в чатик статистику, и много других интересных вещей.
Ответ
#74
flopix Написал:Я когда писал торгового бота для руоффа обошелся без отправки пакетов клиенту, зачем это вам?
Обмануть клиент: например, вывод информации о каком-либо действии или же что-то еще.

Добавлено через 8 минут
f1redark Написал:На сколько я помню, клиент при удалении берет размер из UNetworkPacket, так что самое простое, хук на DispatchNetworkQueue, дальше, если нужен чисто свой пакет, то через малок выделил память, правильно заполнил поля, и клиент сам его нормально удалит. Второй вариант, нужно подхачить чужой пакет, тогда вызываешь оригинал, меняешь, отдаешь клиенту. Третий вариант, самый противный, но тоже ничего сложного, это когда нужно чужой пакет расширить, например html, multisell, ну или дописать каждому, кто пишет в чат, его профу перед ником, мало ли что в голову взбредет. В этом случае вызываем оригинал, сохраняем пакет к себе куда нибудь, можно на стек, потом удаляем пакет через free, выделяем сколько нужно места malloc'ом, копируем туда пакет со стека, расширяем, как надо, и отдаем клиенту. Во всех случаях нужно не забывать фиксить размер в структуре пакета, или будет падать
Изменяли размер существующего пакета в структуре, как и изменяли указатель данных. В итоге крит Smile
Вопрос в подмене 1го пакета и добавлении его одного.
f1redark Написал:Например, можно выводить менюшки динамические, с длительностью эффектов/еще чем то, писать в чатик статистику, и много других интересных вещей.
Именно так Smile
[Изображение: 4e38c909fcd08c5fcdf363b54a62.png]
Ответ
#75
Zubastic Написал:Обмануть клиент: например, вывод информации о каком-либо действии или же что-то еще.

Добавлено через 8 минут

Изменяли размер существующего пакета в структуре, как и изменяли указатель данных. В итоге крит Smile
Вопрос в подмене 1го пакета и добавлении его одного.

Именно так Smile

Да, перепутал, там бестолку менять, free из пула берет размер, а не из пакета. Ну тогда каждый раз сам выделяй, формируй пакет, и отдавай клиенту)
Ответ
#76
f1redark Написал:Да, перепутал, там бестолку менять, free из пула берет размер, а не из пакета. Ну тогда каждый раз сам выделяй, формируй пакет, и отдавай клиенту)
Если честно не совсем понимаю как это сделать, чтобы не словить критец Smile
[Изображение: 4e38c909fcd08c5fcdf363b54a62.png]
Ответ
#77
Кто-то наигрался с u и решил копать глубже? Хватит насиловать бедный клиентSmile
Aka Stels
Ответ
#78
Shayne Написал:Кто-то наигрался с u и решил копать глубже? Хватит насиловать бедный клиентSmile
[Изображение: ?c=1&o1=wi400.he260&url=http%3A%2F%2Fs2....05e8ca.jpg]
[Изображение: 4e38c909fcd08c5fcdf363b54a62.png]
Ответ
#79
В принципе ничего сложного. Ниже пример, который перед приходом любого сообщения в общий чат (белый), отправляет клиенту новый пакет, в котором изменяется ник, и тип чата, так же перед текстом добавляется текущее время отправки). Код на скорую руку, многие вещи можно повыносить в классы\функции, и т п, с другой стороны, это просто пример, так что сойдет) 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:Confusedtring 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:Confusedtring(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, &current_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:Confusedtring 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]

[Изображение: 2b2b91885c2a.png]
Ответ
#80
Спасибо, вечером проверю, А модификация существующих пакетов работает корректно?
[Изображение: 4e38c909fcd08c5fcdf363b54a62.png]
Ответ


Возможно похожие темы ...
Тема Автор Ответы Просмотры Последний пост
  Свой сниффер и редактор пакетов SiriusED 0 462 03-22-2024, 03:28 AM
Последний пост: SiriusED
  Реконструкция пакетов из WSARecv\WSASend ANZO 3 2,492 04-17-2016, 08:34 PM
Последний пост: Necroz-Team
  Подмен пакетов katanasmil 4 3,091 06-16-2014, 07:24 PM
Последний пост: PROGRAMMATOR
  Опкоды пакетов при хуке Mifesto 3 2,435 07-09-2013, 04:18 PM
Последний пост: Mifesto

Перейти к форуму:


Пользователи, просматривающие эту тему: 6 Гость(ей)