Другое С/С++ Вопрос - Ответ

Cake_

Известный
Проверенный
263
313
У меня появился другой вопрос. Вот я отлавливаю пакеты.
Вот по этому уроку у меня получилось это сделать https://blast.hk/wiki/tutorials:api_lesson_raknet
Я понимаю как он отлавливает пакеты и как читает. (Конечно есть некоторые вопросы, но походу разберусь).

Я не понимаю одного. Зачем нужны 2 вида отправка пакетов Pacet и RPC ? Что, когда нужно использовать ?
В интернете я ничего не нашел по этому вопросу. Пожалуйста, если вы знаете ответ, или знаете источник где этот ответ есть скажите мне!
рпк и пакеты это разные вещи. рпк отправляются / приходят в момент какого-то события например сервер показал нам диалог в этот момент нам приходит ShowDialog - ID: 61. а пакеты же используются для того чтобы отправлять информацию серверу об твоём хп / позиции / положении твоей камеры / являешься ли ты наблюдателем / отправка BULLET SYNC(в момент стрельбы) пример, когда мы двигаемся отправляется он фут дата (ID_PLAYER_SYNC), оно отправляется даже когда персонаж не двигается(отправляется с меньшей частотой)

update: https://github.com/BrunoBM16/samp-packet-list/wiki/RPC-List тут можешь глянуть инфу об всех пакетах / rpc
 
  • Нравится
Реакции: MuhaPW

Stiopko

Известный
Проверенный
307
218
@Stiopko, код, реализующий перенаправление из функции в другое место хоть и говноплоховат, но свою задачу выполняет (не поленился, проверил дебагером).
Возможно, ты создал объект Hook на стеке, в результате чего после выхода из области видимости, автоматически вызвался деструктор. Попробуй создавать его на куче через new
а что в коде говно, хочу узнать чтоби в будущем писать меньше говна

upd: нашел ошибку там вместо memset((void*)(addr - 4), 0x90, size-4);
нужно memset((void*)(addr + 4), 0x90, size-4);
@Stiopko
Возможно, ты создал объект Hook на стеке, в результате чего после выхода из области видимости, автоматически вызвался деструктор. Попробуй создавать его на куче через new
upd: не знал что такое может быть, я просто его в вектор записываю, попробую указатель записывать
upd: все работает, спасибо
 
Последнее редактирование:

ШPEK

Известный
1,476
524
Здарова, сделал я структуру для хука, но она почему-то не ставит хук, хотя просто функция работала нормально, как можно решить?

C++:
struct Hook {
    DWORD addr = NULL;
    byte* data = nullptr;
    size_t size = NULL;

    Hook(const DWORD& addr, const DWORD& func, const size_t& size = 5) {
        this->data = new byte[size];
        this->size = size;
        this->addr = addr;

        DWORD dwProt = PAGE_EXECUTE_READWRITE;
        VirtualProtect((void*)addr, size, dwProt, &dwProt);

        memcpy(data, (void*)addr, size);
        memset((void*)(addr-4), 0x90, size-4);
        *(byte*)(addr) = 0xE9; // jmp
        *(unsigned int*)(addr + 1) = func - (addr + 5);

        VirtualProtect((void*)addr, size, dwProt, NULL);
       
    }

    ~Hook() {
        if (data != nullptr) {
            DWORD dwProt = PAGE_EXECUTE_READWRITE;
            VirtualProtect((void*)addr, size, dwProt, &dwProt);
            memcpy((void*)addr, data, size);
            VirtualProtect((void*)addr, size, dwProt, NULL);
            delete[] data;
        }
    }
};
C++:
void injectCall(char* mainaddrress, char* target, size_t bytes = 5)
{
 DWORD protection = PAGE_READWRITE;
 VirtualProtect(mainaddrress, bytes, protection, &protection);
 *mainaddrress = 0xE8;
 *reinterpret_cast<DWORD*>(mainaddrress + 1) = reinterpret_cast<DWORD>(target) - (reinterpret_cast<DWORD>(mainaddrress) + 5);
 for (size_t i = 5; i < bytes; i++) *(mainaddrress + i) = 0x90;
 VirtualProtect(mainaddrress, bytes, protection, &protection);
}
 
void injectJump(char* mainaddrress, char* target, size_t bytes = 5)
{
 DWORD protection = PAGE_READWRITE;
 VirtualProtect(mainaddrress, bytes, protection, &protection);
 *mainaddrress = 0xE9;
 *reinterpret_cast<DWORD*>(mainaddrress + 1) = reinterpret_cast<DWORD>(target) - (reinterpret_cast<DWORD>(mainaddrress) + 5);
 for (size_t i = 5; i < bytes; i++) *(mainaddrress + i) = 0x90;
 VirtualProtect(mainaddrress, bytes, protection, &protection);
 retaddr = (DWORD)mainaddrress + bytes;
}
 

p1cador

cerf
Проверенный
220
359
а что в коде говно, хочу узнать чтоби в будущем писать меньше говна
не предусмотрена возможность вызова оригинальной функции
не предусмотрена возможность установки более одного хука на функцию
не сохранены значения регистров
 
  • Нравится
Реакции: Stiopko

Stiopko

Известный
Проверенный
307
218
не предусмотрена возможность вызова оригинальной функции
не предусмотрена возможность установки более одного хука на функцию
не сохранены значения регистров
не предусмотрена возможность установки более одного хука на функцию
Будит)

Только, что закончил
C++:
struct Hook {
    DWORD addr = NULL;
    byte* data = nullptr;
    size_t size = NULL;

    DWORD trampoline = NULL;
    size_t addBytesSize = NULL;

    Hook(const DWORD& addr, const DWORD& func, const char* addBytes, const size_t &addBytesSize, const size_t& size = 5) { // addBytes для пуша аргументов функции func
        this->data = new byte[size];
        this->size = size;
        this->addr = addr;
        this->addBytesSize = addBytesSize;
        DWORD dwProt = PAGE_EXECUTE_READWRITE;
        VirtualProtect((void*)addr, size, dwProt, &dwProt);

        memcpy(data, (void*)addr, size);
        
        trampoline = (DWORD)VirtualAlloc(0, addBytesSize + size + 12, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); // pushad / addBytes / call func / popad / замененные байты / джамп назад
        *(byte*)trampoline = 0x60; // pushad
        memcpy((void *)(trampoline + 1), addBytes, addBytesSize); // addBytes
        *(byte*)(trampoline + addBytesSize + 1) = 0xE8; //call
        *(size_t*)(trampoline + addBytesSize + 2) = func - (trampoline + addBytesSize + 6); // func
        *(byte*)(trampoline + addBytesSize + 6) = 0x61; // popad
        memcpy((void*)(trampoline + addBytesSize + 7), data, size); // замененные байты
        *(byte*)(trampoline + addBytesSize + size + 7) = 0xE9; // jmp
        *(size_t*)(trampoline + addBytesSize + size + 8) = addr + 5 - (trampoline + addBytesSize + size + 12); // jmp to

        memset((void*)(addr + 4), 0x90, size-4);
        *(byte*)(addr) = 0xE9; // jmp
        *(unsigned int*)(addr + 1) = trampoline - (addr + 5);

        VirtualProtect((void*)addr, size, dwProt, NULL);
    }

    ~Hook() {
        if (data != nullptr) {
            DWORD dwProt = PAGE_EXECUTE_READWRITE;
            VirtualProtect((void*)addr, size, dwProt, &dwProt);
            memcpy((void*)addr, data, size);
            VirtualProtect((void*)addr, size, dwProt, NULL);
            memset((void*)trampoline, NULL, addBytesSize + size + 12);
            VirtualFree((void*)trampoline, addBytesSize + size + 12, MEM_RELEASE);
            delete[] data;
        }
    }
};
 

Stiopko

Известный
Проверенный
307
218
Ты используешь jmp, вместо ret
где, я не понил?


Есть ли у кого-то адрес функции которая вызывается когда в чате нажимают ентер? Мне просто нужно заменить текст, я искал в СЕ, всегда когда я заменял текст было уже поздно и плагин узнавал что его вызывают

-----------------------
Решено, если кому надо вот по этому адресу 0x65DB4 делаем хук там сохраняем регистры , потом lea ebp,[esi+000014E5] и все в ebp адрес нашей строки далее пушим в стек и вызываем функу
 
Последнее редактирование:

MuhaPW

Новичок
6
0
рпк и пакеты это разные вещи. рпк отправляются / приходят в момент какого-то события например сервер показал нам диалог в этот момент нам приходит ShowDialog - ID: 61. а пакеты же используются для того чтобы отправлять информацию серверу об твоём хп / позиции / положении твоей камеры / являешься ли ты наблюдателем / отправка BULLET SYNC(в момент стрельбы) пример, когда мы двигаемся отправляется он фут дата (ID_PLAYER_SYNC), оно отправляется даже когда персонаж не двигается(отправляется с меньшей частотой)

update: https://github.com/BrunoBM16/samp-packet-list/wiki/RPC-List тут можешь глянуть инфу об всех пакетах / rpc

Здравствуйте. Это опять я :)
Ссылку которую вы отправили, там кажется некоторые устарели (или я что то не понял, вообщем иногда данные не правильно берутся). Как мне понять это самому по RPC ? Ну например я перехватил RPC которую отправил клиент -> сервер. Как мне его прочитать ? Есть ли какой либо способ сделать так, что бы я мог определять параметры пакета ?
 

ALF

Известный
Проверенный
320
537
Здравствуйте. Это опять я :)
Ссылку которую вы отправили, там кажется некоторые устарели (или я что то не понял, вообщем иногда данные не правильно берутся). Как мне понять это самому по RPC ? Ну например я перехватил RPC которую отправил клиент -> сервер. Как мне его прочитать ? Есть ли какой либо способ сделать так, что бы я мог определять параметры пакета ?
 
  • Нравится
Реакции: MuhaPW

Cake_

Известный
Проверенный
263
313
Здравствуйте. Это опять я :)
Ссылку которую вы отправили, там кажется некоторые устарели (или я что то не понял, вообщем иногда данные не правильно берутся). Как мне понять это самому по RPC ? Ну например я перехватил RPC которую отправил клиент -> сервер. Как мне его прочитать ? Есть ли какой либо способ сделать так, что бы я мог определять параметры пакета ?
Нечего там не устарело. Читать битсрим нужно строго в той последовательности которой они иницилизированы на гитхабе.
 

enziweee

Участник
28
32
hi
как правильно настроить проект так, чтобы не оставалось всяких следов в памяти связанных с твоей учетной записью, самой студией и тд
и еще, имгуи тоже оставляет следы, как исправить?
37604
 

ALF

Известный
Проверенный
320
537
Последнее редактирование:
  • Нравится
Реакции: enziweee

MuhaPW

Новичок
6
0
Нечего там не устарело. Читать битсрим нужно строго в той последовательности которой они иницилизированы на гитхабе.

Значит я где то ошибаюсь, но вот где ? Я хочу вывести текст команды в чат (Например /s Hello world!). У меня получилось это с помощью RakLogger+, который мне посоветовали с верху. Но я все ровно хочу узнать где я ошибся.

Вот мой код:
Внутри блока switch (pacetId):
case RPC_ServerCommand:
            UINT32 length;
            byte endCommandText;
            char commandText[50];

            params->bitStream->ResetReadPointer();
            params->bitStream->Read(length);
            params->bitStream->Read(commandText, endCommandText);
            commandText[endCommandText] = '\0';
            params->bitStream->ResetReadPointer();

            SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(230, 46, 46), "Lenght - %d, Command - %s",
                length, commandText);
            break;

Ввод: /s Крик
Вывод: Lenght - 7, Command -

Lenght правильный, но Command все время пустой. Иногда, выходит не понятные буквы. И если повторить команду то он опять будет пустым. Вообщем я не смог отловить в каких случаях он выводит не понятные буквы.
 

Stiopko

Известный
Проверенный
307
218
Значит я где то ошибаюсь, но вот где ? Я хочу вывести текст команды в чат (Например /s Hello world!). У меня получилось это с помощью RakLogger+, который мне посоветовали с верху. Но я все ровно хочу узнать где я ошибся.

Вот мой код:
Внутри блока switch (pacetId):
case RPC_ServerCommand:
            UINT32 length;
            byte endCommandText;
            char commandText[50];

            params->bitStream->ResetReadPointer();
            params->bitStream->Read(length);
            params->bitStream->Read(commandText, endCommandText);
            commandText[endCommandText] = '\0';
            params->bitStream->ResetReadPointer();

            SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(230, 46, 46), "Lenght - %d, Command - %s",
                length, commandText);
            break;

Ввод: /s Крик
Вывод: Lenght - 7, Command -

Lenght правильный, но Command все время пустой. Иногда, выходит не понятные буквы. И если повторить команду то он опять будет пустым. Вообщем я не смог отловить в каких случаях он выводит не понятные буквы.
удали переменную endcomandtext и замени ее использование на переменную length
 

traceattack

Известный
218
119
Как задать позицию машины относительно себя самой? Допустим Y += 2 и чтобы она сдвинулась вперед на 2 метра