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

RTD

Потужно
Модератор
399
470
Всем привет, пытаюсь поставит хук на самповскую функцию 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,474
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
539
Всем привет, пытаюсь поставит хук на самповскую функцию 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;
    }
}
Можно пример хука без сф?
 

ALF

Известный
Проверенный
320
539
Можно пример хука без сф?
тоже самое всё, ниже функа
кстати, можно использовать для call хука если заменить 0xE9 на 0xE8
C++:
void CreateJmpHook(BYTE *pAddress, DWORD dwJumpTo, size_t size = 5)
{
    if (size < 5) return;

    DWORD prot = PAGE_EXECUTE_READWRITE;
    VirtualProtect(pAddress, size, prot, &prot);

    *pAddress = 0xE9;
    *reinterpret_cast<DWORD *>(pAddress + 0x1) = dwJumpTo - reinterpret_cast<DWORD>(pAddress) - 0x5;
    for (size_t i = 0x5; i < size; i++) *(pAddress + i) = 0x90;

    VirtualProtect(pAddress, size, prot, nullptr);
}
 
  • Нравится
Реакции: Stiopko и Cake_

Stiopko

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

И где они хранятся, в коком регистре?
 

RTD

Потужно
Модератор
399
470
Как можно взять параметры которые передавались в функцию которую хукнули?

И где они хранятся, в коком регистре?
 
  • Нравится
Реакции: ШPEK и Stiopko

ШPEK

Известный
1,474
525
Как можно взять параметры которые передавались в функцию которую хукнули?

И где они хранятся, в коком регистре?
Зависит от соглашения о вызове.
Например: _cdecl - в стеке, __thiscall - первый аргумент в регистре ecx и остальные в стеке, _stdcall - в стеке.
__thiscall обычно используется в методах класса.
Пример:
C++:
__asm
{
  push ebp // сохраняем значение регистра ebp в стеке 
  mov ebp, esp
  push [ebp + 4 + 8] // передаем второй аргумент 
  push [ebp + 4 + 4] // передаём первый аргумент 
  call hook // функция должна быть _stdcall
  pop ebp // воостанавливаем значение регистра ebp из стека 
}
 
  • Нравится
Реакции: RTD и Stiopko

Stiopko

Известный
Проверенный
307
218
Зависит от соглашения о вызове.
Например: _cdecl - в стеке, __thiscall - первый аргумент в регистре ecx и остальные в стеке, _stdcall - в стеке.
__thiscall обычно используется в методах класса.
Пример:
C++:
__asm
{
  push ebp // сохраняем значение регистра ebp в стеке
  mov ebp, esp
  push [ebp + 4 + 8] // передаем второй аргумент
  push [ebp + 4 + 4] // передаём первый аргумент
  call hook // функция должна быть _stdcall
  pop ebp // воостанавливаем значение регистра ebp из стека
}
а что хранится в регистре ebp, или обязательно сохранять все регистры через pushad, или можно только ebp?
 

0xNull_Dll

Известный
143
21
Парни, кто-нибудь знает оффсет на клавиши? Конкретно - на WASD. Типа, чтобы можно было записать в какой-то адресс 255 - нажалась кнопка, к примеру, W. 0 = "отжалась" (press / release)

P.S Не функцию. Именно оффсет
 

MuhaPW

Новичок
6
0
1 Не могу начать писать плагины SAMPFUNCS.
Установил Visual Studio, распаковал проект SFPlugin и открыл. Вот ошибка, ни как не могу понять с чем связана ошибка и как его исправить.

Код:
1>------ Перестроение всех файлов начато: проект: FirstSF, Конфигурация: Release Win32 ------
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppBuild.targets(379,5): error MSB8020: The build tools for Visual Studio 2012 - Windows XP (Platform Toolset = 'v110_xp') cannot be found. To build using the v110_xp build tools, please install Visual Studio 2012 - Windows XP build tools.  Alternatively, you may upgrade to the current Visual Studio tools by selecting the Project menu or right-click the solution, and then selecting "Retarget solution".
1>Сборка проекта "SFPlugin.vcxproj" завершена с ошибкой.
========== Перестроение всех проектов: успешно: 0, с ошибками: 1, пропущено: 0 ==========