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

Cake_

Известный
Проверенный
263
313
Пробовал в хуке вот так:
Код:
if (params->packetId == ScriptRPCEnumeration::RPC_ScrShowTextDraw)
{
    stTextDrawTransmit txd;
    WORD txdID, cTextLen; char cText[800];
    params->bitStream->ResetReadPointer();
    params->bitStream->Read(txdID);
    params->bitStream->Read((PCHAR)&txd, sizeof(stTextDrawTransmit));
    params->bitStream->Read(cTextLen);
    params->bitStream->Read(cText, cTextLen);
    params->bitStream->ResetReadPointer();
    cText[cTextLen] = '\0';

    if (txdID == 6) {
        params->bitStream->ResetWritePointer();
        params->bitStream->Write(txdID);
        params->bitStream->Write((PCHAR)&txd, sizeof(stTextDrawTransmit));
        strcpy_s(cText, "Test");
        params->bitStream->Write(cText, strlen(cText));
    }
    return true;
}
Видно я не правильно перезаписываю, потому что в чат выбивает вот это: Warning: ignoring large TextDraw size=25940
Вот так надо
C++:
bool CALLBACK incomingRPC(stRakNetHookParams *params) 
{
    if (params->packetId == ScriptRPCEnumeration::RPC_ScrShowTextDraw)
    {
        WORD wTextID, cTextLen;
        stTextDrawTransmit data;
        char cText[65535];
        BitStream *bsData = params->bitStream;
        bsData->Read(wTextID);
        bsData->Read((PCHAR)&data, sizeof(stTextDrawTransmit));
        bsData->Read(cTextLen);
        bsData->Read(cText, cTextLen);
        cText[cTextLen] = '\0';

        stTextDrawTransmit MyTD;

        SF->getSAMP()->getInfo()->pPools->pTextdraw->GetTransmit(125, MyTD);
        MyTD.fBoxHeight =  0.249999;
        MyTD.fLetterWidth = 0.300000;
        MyTD.dwBoxColor = -16776961;
        MyTD.byteShadow = 0;
        MyTD.byteOutline = -1;
        MyTD.dwBackgroundColor = -1;
        MyTD.byteStyle = 2;
        MyTD.byteProportional = 1;
        SF->getSAMP()->getInfo()->pPools->pTextdraw->Delete(125);
        SF->getSAMP()->getInfo()->pPools->pTextdraw->Create(125, &MyTD, "DIAMOND");

        SF->getSAMP()->getInfo()->pPools->pTextdraw->Delete(126);
        SF->getSAMP()->getInfo()->pPools->pTextdraw->Delete(127);
        SF->getSAMP()->getInfo()->pPools->pTextdraw->Delete(128);
        SF->getSAMP()->getInfo()->pPools->pTextdraw->Delete(129);
    };

    return true;
};
 

Adder

Известный
22
0
Вот так надо
C++:
bool CALLBACK incomingRPC(stRakNetHookParams *params)
{
    if (params->packetId == ScriptRPCEnumeration::RPC_ScrShowTextDraw)
    {
        WORD wTextID, cTextLen;
        stTextDrawTransmit data;
        char cText[65535];
        BitStream *bsData = params->bitStream;
        bsData->Read(wTextID);
        bsData->Read((PCHAR)&data, sizeof(stTextDrawTransmit));
        bsData->Read(cTextLen);
        bsData->Read(cText, cTextLen);
        cText[cTextLen] = '\0';

        stTextDrawTransmit MyTD;

        SF->getSAMP()->getInfo()->pPools->pTextdraw->GetTransmit(125, MyTD);
        MyTD.fBoxHeight =  0.249999;
        MyTD.fLetterWidth = 0.300000;
        MyTD.dwBoxColor = -16776961;
        MyTD.byteShadow = 0;
        MyTD.byteOutline = -1;
        MyTD.dwBackgroundColor = -1;
        MyTD.byteStyle = 2;
        MyTD.byteProportional = 1;
        SF->getSAMP()->getInfo()->pPools->pTextdraw->Delete(125);
        SF->getSAMP()->getInfo()->pPools->pTextdraw->Create(125, &MyTD, "DIAMOND");

        SF->getSAMP()->getInfo()->pPools->pTextdraw->Delete(126);
        SF->getSAMP()->getInfo()->pPools->pTextdraw->Delete(127);
        SF->getSAMP()->getInfo()->pPools->pTextdraw->Delete(128);
        SF->getSAMP()->getInfo()->pPools->pTextdraw->Delete(129);
    };

    return true;
};
Такой метод я пробовал, да он работает. Но вопрос как также сделать в собе, т.к. там нет функций pPools->pTextdraw->Delete() и pPools->pTextdraw->Create()
 

Roger571

Известный
58
31
Такой метод я пробовал, да он работает. Но вопрос как также сделать в собе, т.к. там нет функций pPools->pTextdraw->Delete() и pPools->pTextdraw->Create()
Есть несколько путей решения данной проблемы.
Первый - реализовать класс textdraw (обертку над пулом). Можно взять реализацию из SAMPAPI, благо он опенсурс.
Но если тебе нужны лишь эти две функции, то смысла тянуть весь класс в проект не особо вижу.
Второй - просто добавить эти две функции.
C++:
stTextdraw *CreateTextDraw(int nId, stTextDrawTransmit *pTransmit, const char *szText)
{
    return ((stTextdraw *(__thiscall *)(stTextdrawPool *, int, stTextDrawTransmit *, const char *))(g_dwSAMP_Addr + 0x1AE20))(g_SAMP->pPools->pTextdraw, nId, pTransmit, szText);
}

void DeleteTextDraw(uint16_t nId)
{
    ((void(__thiscall *)(stTextdrawPool *, uint16_t))(g_dwSAMP_Addr + 0x1AD00))(g_SAMP->pPools->pTextdraw, nId);
}
Не факт, что работает - проверь. У самого нет возможности проверить.
 
Последнее редактирование:
  • Нравится
Реакции: Adder

Adder

Известный
22
0
Есть несколько путей решения данной проблемы.
Первый - реализовать класс textdraw (обертку над пулом). Можно взять реализацию из SAMPAPI, благо он опенсурс.
Но если тебе нужны лишь эти две функции, то смысла тянуть весь класс в проект не особо вижу.
Второй - просто добавить эти две функции.
C++:
stTextdraw *CreateTextDraw(int nId, stTextDrawTransmit *pTransmit, const char *szText)
{
    return ((stTextdraw *(__thiscall *)(stTextdrawPool *, int, stTextDrawTransmit *, const char *))(g_dwSAMP_Addr + 0x1AE20))(g_SAMP->pPools->pTextdraw, nId, pTransmit, szText);
}

void DeleteTextDraw(uint16_t nId)
{
    ((void(__thiscall *)(stTextdrawPool *, uint16_t))(g_dwSAMP_Addr + 0x1AD00))(g_SAMP->pPools->pTextdraw, nId);
}
Не факт, что работает - проверь. У самого нет возможности проверить.
Не знал, что он в открытом доступе есть. Теперь буду знать.
И перезаписать получилось, я что-то тупанул и забыл длину записать. Поэтому нормально не перезаписывало.
За функции спасибо
 
Последнее редактирование:

Stiopko

Известный
Проверенный
307
218
Всем привет, пытаюсь поставит хук на самповскую функцию SAMP_FUNC_SENDCMD 0x65C60

ставлю через https://blast.hk/threads/30412/

C++:
DWORD Trampoline = 0x0;
byte prologue[6];

void UserHook(void* _this, char* message)
{
    MessageBoxA(NULL, message, "sadasd", NULL);
    __asm jmp Trampoline
}

// устанавливаю
DWORD Addr = SF->getSAMP()->getSAMPAddr() + SAMP_FUNC_SENDCMD;
Trampoline = MakeJump(Addr, (DWORD)& UserHook, prologue, 6);

но при вызове команды происходит краш

вот скрины с енжина
до
37046

и после установки
37049

по моему выглядит красиво, но все же я где-то проебался

пробовал и с __stdcall функцию UserHook, и брал размер пролога 8 вместо 6 тоже не помогло, что я делаю не так?
 

Roger571

Известный
58
31
Скорее я тупой и не вижу очевидного.
Возникла проблема с получением имени сетевого адаптера и я в душе не чаю, что не так и в какой магической кодировке оно находится.
Самое интересное, описание в нормальном виде. У обоих тип char*, ес шо.
Вот, сообсна, код.
C++:
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
    while (pAdapter)
    {
        Log("Adapter Name: %s %s\n", pAdapter->AdapterName, pAdapter->Description);
        Log("IP Address: %s\n", pAdapter->IpAddressList.IpAddress.String);
        pAdapter = pAdapter->Next;
    }
Вот лог:
{D387BCE2-FD49-4AFA-AA49-E7634ED15008} Intel(R) Ethernet Connection (2) I219-V
А теперь главный вопрос, как привести имя адаптера в человеческий вид?
 

Cake_

Известный
Проверенный
263
313
Скорее я тупой и не вижу очевидного.
Возникла проблема с получением имени сетевого адаптера и я в душе не чаю, что не так и в какой магической кодировке оно находится.
Самое интересное, описание в нормальном виде. У обоих тип char*, ес шо.
Вот, сообсна, код.
C++:
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
    while (pAdapter)
    {
        Log("Adapter Name: %s %s\n", pAdapter->AdapterName, pAdapter->Description);
        Log("IP Address: %s\n", pAdapter->IpAddressList.IpAddress.String);
        pAdapter = pAdapter->Next;
    }
Вот лог:

А теперь главный вопрос, как привести имя адаптера в человеческий вид?
вот тут должно быть то, что тебе нужно https://books.google.com.ua/books?i...oECAgQAQ#v=onepage&q=имя адаптера c++&f=false
 
  • Нравится
Реакции: LaRossa

Roger571

Известный
58
31
вот тут должно быть то, что тебе нужно
Оно то есть, да и в других примерах работы с этой библиотекой у людей все нормально и имя адаптера выводится в читаемом формате.
Если интересно, можешь попробовать у себя
C++:
#pragma comment (lib, "Iphlpapi.lib")
#include "Windows.h"
#include "stdio.h"
#include "iphlpapi.h"

int main()
{
    IP_ADAPTER_INFO  *pAdapterInfo;
    ULONG            ulOutBufLen;
    DWORD            dwRetVal;

    pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
    ulOutBufLen = sizeof(IP_ADAPTER_INFO);

    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) != ERROR_SUCCESS)
    {
        free(pAdapterInfo);
        pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
    }

    if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) != ERROR_SUCCESS)
    {
        free(pAdapterInfo);
    }

    PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
    while (pAdapter)
    {
        printf("Adapter Name: %s %s\n", pAdapter->AdapterName, pAdapter->Description);
        printf("IP Address: %s\n", pAdapter->IpAddressList.IpAddress.String);
        pAdapter = pAdapter->Next;
    }

    if (pAdapterInfo)
        free(pAdapterInfo);

    system("pause");
    return 0;
}
 

Stiopko

Известный
Проверенный
307
218
Оно то есть, да и в других примерах работы с этой библиотекой у людей все нормально и имя адаптера выводится в читаемом формате.
Если интересно, можешь попробовать у себя
C++:
#pragma comment (lib, "Iphlpapi.lib")
#include "Windows.h"
#include "stdio.h"
#include "iphlpapi.h"

int main()
{
    IP_ADAPTER_INFO  *pAdapterInfo;
    ULONG            ulOutBufLen;
    DWORD            dwRetVal;

    pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
    ulOutBufLen = sizeof(IP_ADAPTER_INFO);

    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) != ERROR_SUCCESS)
    {
        free(pAdapterInfo);
        pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
    }

    if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) != ERROR_SUCCESS)
    {
        free(pAdapterInfo);
    }

    PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
    while (pAdapter)
    {
        printf("Adapter Name: %s %s\n", pAdapter->AdapterName, pAdapter->Description);
        printf("IP Address: %s\n", pAdapter->IpAddressList.IpAddress.String);
        pAdapter = pAdapter->Next;
    }

    if (pAdapterInfo)
        free(pAdapterInfo);

    system("pause");
    return 0;
}
В примере вроде похожее имя адаптера?
37053
 
  • Нравится
Реакции: Roger571

RTD

Нестандартное звание
Модератор
391
414
Всем привет, пытаюсь поставит хук на самповскую функцию SAMP_FUNC_SENDCMD 0x65C60

ставлю через https://blast.hk/threads/30412/

C++:
DWORD Trampoline = 0x0;
byte prologue[6];

void UserHook(void* _this, char* message)
{
    MessageBoxA(NULL, message, "sadasd", NULL);
    __asm jmp Trampoline
}

// устанавливаю
DWORD Addr = SF->getSAMP()->getSAMPAddr() + SAMP_FUNC_SENDCMD;
Trampoline = MakeJump(Addr, (DWORD)& UserHook, prologue, 6);

но при вызове команды происходит краш

вот скрины с енжина
до
Посмотреть вложение 37046
и после установки
Посмотреть вложение 37049
по моему выглядит красиво, но все же я где-то проебался

пробовал и с __stdcall функцию UserHook, и брал размер пролога 8 вместо 6 тоже не помогло, что я делаю не так?
Крашит т.к. функция __thiscall + хук будет затирать инструкцию mov
https://blast.hk/threads/781/post-359737
 
  • Нравится
Реакции: Stiopko и ШPEK

ШPEK

Известный
1,476
525
Всем привет, пытаюсь поставит хук на самповскую функцию SAMP_FUNC_SENDCMD 0x65C60

ставлю через https://blast.hk/threads/30412/

C++:
DWORD Trampoline = 0x0;
byte prologue[6];

void UserHook(void* _this, char* message)
{
    MessageBoxA(NULL, message, "sadasd", NULL);
    __asm jmp Trampoline
}

// устанавливаю
DWORD Addr = SF->getSAMP()->getSAMPAddr() + SAMP_FUNC_SENDCMD;
Trampoline = MakeJump(Addr, (DWORD)& UserHook, prologue, 6);

но при вызове команды происходит краш

вот скрины с енжина
до
Посмотреть вложение 37046
и после установки
Посмотреть вложение 37049
по моему выглядит красиво, но все же я где-то проебался

пробовал и с __stdcall функцию UserHook, и брал размер пролога 8 вместо 6 тоже не помогло, что я делаю не так?
Сделай через call (0xE8)
C++:
void _stdcall hook(const char* text)
{
  addBlueText(text)
}
void _declspec(naked) change()
{
__asm 
{
  push [esp + 8]
  call hook
  mov eax, fs:[0]
  ret
}
}
У меня так все работало
 
Последнее редактирование:
  • Нравится
Реакции: Stiopko

Roger571

Известный
58
31
В примере вроде похожее имя адаптера?
Посмотреть вложение 37053
Да, был невнимателен.
В общем, если кому вдруг пригодится, на новых системах нужно использовать GetAdaptersAddresses(), который содержит поле FriendlyName. Он то и содержит читаемое имя адаптера. Источник.
Рабочий код:
C++:
#include <WS2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    PIP_ADAPTER_ADDRESSES pAdapterAdresses = NULL;
    ULONG ulOutBufLen = 0x1000;
    DWORD dwRetVal;
    char buff[0x10], adapterName[0x20], desc[0x20];

    pAdapterAdresses = (IP_ADAPTER_ADDRESSES *)malloc(ulOutBufLen);
    ulOutBufLen = sizeof(IP_ADAPTER_INFO);

    if (GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, NULL, pAdapterAdresses, &ulOutBufLen) != ERROR_SUCCESS)
    {
        free(pAdapterAdresses);
        pAdapterAdresses = (IP_ADAPTER_ADDRESSES *)malloc(ulOutBufLen);
    }

    if ((dwRetVal = GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, NULL, pAdapterAdresses, &ulOutBufLen)) != ERROR_SUCCESS)
    {
        free(pAdapterAdresses);
    }

    PIP_ADAPTER_ADDRESSES pAdapter = pAdapterAdresses;

    while (pAdapter)
    {

        wcstombs(adapterName, pAdapter->FriendlyName, wcslen(pAdapter->FriendlyName));
        wcstombs(desc, pAdapter->Description, wcslen(pAdapter->Description));

        printf("Adapter Name: %s %s\n", adapterName, desc);

        if (pAdapter->FirstUnicastAddress->Address.lpSockaddr->sa_family == AF_INET)
        {
            sockaddr_in *sa_in = (sockaddr_in *)pAdapter->FirstUnicastAddress->Address.lpSockaddr;
            printf("IP Address: %s\n", inet_ntop(AF_INET, &(sa_in->sin_addr), buff, 0x10));
        }

        pAdapter = pAdapter->Next;
    }

    if (pAdapterAdresses)
        free(pAdapterAdresses);

    system("pause");
    return 0;
}
Это описание сетевого адаптера, указывается имя железа.
 
  • Нравится
Реакции: Stiopko, ШPEK и Cake_

ALF

Известный
Проверенный
320
537
Всем привет, пытаюсь поставит хук на самповскую функцию SAMP_FUNC_SENDCMD 0x65C60

ставлю через https://blast.hk/threads/30412/

C++:
DWORD Trampoline = 0x0;
byte prologue[6];

void UserHook(void* _this, char* message)
{
    MessageBoxA(NULL, message, "sadasd", NULL);
    __asm jmp Trampoline
}

// устанавливаю
DWORD Addr = SF->getSAMP()->getSAMPAddr() + SAMP_FUNC_SENDCMD;
Trampoline = MakeJump(Addr, (DWORD)& UserHook, prologue, 6);

но при вызове команды происходит краш

вот скрины с енжина
до
Посмотреть вложение 37046
и после установки
Посмотреть вложение 37049
по моему выглядит красиво, но все же я где-то проебался

пробовал и с __stdcall функцию UserHook, и брал размер пролога 8 вместо 6 тоже не помогло, что я делаю не так?
как то трудно всё.
в сф без этого всего можно ставить хуки

C++:
DWORD hk_address;
void __declspec(naked) hook()
{
    static DWORD jmp_address = hk_address + 6;
    __asm
    {
        mov eax, fs:[00000000]
        pushad
        pushfd
    }
    SF->getSAMP()->getChat()->AddChatMessage(-1, "hooked!");
    __asm
    {
        popfd
        popad
        jmp jmp_address
    }
}

void CALLBACK mainloop()
{
    static bool init = false;
    if (!init)
    {
        if (GAME == nullptr) return;
        if (GAME->GetSystemState() != eSystemState::GS_PLAYING_GAME) return;
        if (!SF->getSAMP()->IsInitialized()) return;

        hk_address = SF->getSAMP()->getSAMPAddr() + 0x65C60;
        SF->getGame()->createHook(reinterpret_cast<PVOID>(hk_address), hook, DETOUR_TYPE_JMP, 6);

        init = true;
    }
}
 
  • Нравится
Реакции: Ya Zaregalsya и Stiopko

Cake_

Известный
Проверенный
263
313
как то трудно всё.
в сф без этого всего можно ставить хуки

C++:
DWORD hk_address;
void __declspec(naked) hook()
{
    static DWORD jmp_address = hk_address + 6;
    __asm
    {
        mov eax, fs:[00000000]
        pushad
        pushfd
    }
    SF->getSAMP()->getChat()->AddChatMessage(-1, "hooked!");
    __asm
    {
        popfd
        popad
        jmp jmp_address
    }
}

void CALLBACK mainloop()
{
    static bool init = false;
    if (!init)
    {
        if (GAME == nullptr) return;
        if (GAME->GetSystemState() != eSystemState::GS_PLAYING_GAME) return;
        if (!SF->getSAMP()->IsInitialized()) return;

        hk_address = SF->getSAMP()->getSAMPAddr() + 0x65C60;
        SF->getGame()->createHook(reinterpret_cast<PVOID>(hk_address), hook, DETOUR_TYPE_JMP, 6);

        init = true;
    }
}
Можно пример хука без сф?