Есть тут замечательная тема с инжектом в функции от могайки: https://blast.hk/threads/2370/#post-27225
Все в ней хорошо, только не рассказывается как искать функции и параметры к ним. Сейчас покажу как перехватывать сообщения, введенные нами в чат.
Значит для начала запускаем ЖТА и логинимся на рандомный аккаунт, чтобы был доступ к чату.
В чате пишем что-нибудь на русском, в CE выбираем процесс с ЖТА, тип исхомых данных выбираем String, ставим галочку напротив UTF-16, вводим что-нибудь в чате, тоже самое в поиске и находим наш адрес.
Добавляем в выбранные адреса, жмем ПКМ по добавленному адресу -> Find out what writes to this address. Потом отправляем сообщение в сампе и смотрим что произошло:
обнаружена инструкция, взаимодействующая с нашими данными в строке ввода. В данном случае эта инструкция обнуляет буффер после отправки сообщения. Жмем Show Dissasembler и вот мы в теле какой-то функции. Перемещаемся к началу:
(Начало можно определить по куче int опкодов). Значит видим в начале две инструкции, которые занимаю 5 байт, как раз хватит для того, чтобы сделать jmp к нашей функции. Дело осталось за малым.
Пишем инжект:
Теперь надо бы определить, какие аргументы в эту функцию передаются, я делал это так: накидываю push'ей, потом смотрю какие данные передаются туда.
Здесь например 2 push'a, запускаем данный скрипт в игре и ставим Break and Trace instructions на нашей jmp:
Вводим любое сообщение в чат и смотрим, какие данные передаются в наших push'ах. В первом пуше - во втором аргументе передается какой-то непонятный DWORD
Во втором пуше - первом аргументе какой-то указатель, возможно это указатель на нашу строку.
Так и есть
Теперь осталось дописать нашу функцию, которая будет ловить эти сообщения. Второй параметр можно убрать.
В итоге получаем перехват сообщения:
Вообще не понятно, что данная функция делает, но наша цель была перехватить сообщение, выводимое в чат, цель достигнута.
Я только изучаю все это дело, поэтому способ может быть не самый лучший. Может кто знает что-нибудь по лучше?
Все в ней хорошо, только не рассказывается как искать функции и параметры к ним. Сейчас покажу как перехватывать сообщения, введенные нами в чат.
Значит для начала запускаем ЖТА и логинимся на рандомный аккаунт, чтобы был доступ к чату.
В чате пишем что-нибудь на русском, в CE выбираем процесс с ЖТА, тип исхомых данных выбираем String, ставим галочку напротив UTF-16, вводим что-нибудь в чате, тоже самое в поиске и находим наш адрес.
Добавляем в выбранные адреса, жмем ПКМ по добавленному адресу -> Find out what writes to this address. Потом отправляем сообщение в сампе и смотрим что произошло:
обнаружена инструкция, взаимодействующая с нашими данными в строке ввода. В данном случае эта инструкция обнуляет буффер после отправки сообщения. Жмем Show Dissasembler и вот мы в теле какой-то функции. Перемещаемся к началу:
(Начало можно определить по куче int опкодов). Значит видим в начале две инструкции, которые занимаю 5 байт, как раз хватит для того, чтобы сделать jmp к нашей функции. Дело осталось за малым.
Пишем инжект:
C++:
void _declspec(naked) Hook( void )
{
_asm {
pushad
push[esp + 0x28] // arg2
push[esp + 0x28] // arg1
call myfunc
popad
push edi
mov edi, [esp+0xC]
jmp ret_addr
}
}
void SetupHook(DWORD dwSamp)
{
DWORD dwAddr = dwSamp + CLEAR_CHAT_HOOK;
ret_addr = (LPVOID)(dwAddr + 5);
DWORD dwProt = PAGE_EXECUTE_READWRITE;
VirtualProtect((void *)dwAddr, 5, dwProt, &dwProt);
unsigned char* pdata = (unsigned char*)dwAddr;
pdata[0] = 0xE9; // jmp
*(unsigned int*)& pdata[1] = (unsigned int)Hook - (dwAddr + 5);
VirtualProtect((void*)dwAddr, 5, dwProt, NULL);
}
Теперь надо бы определить, какие аргументы в эту функцию передаются, я делал это так: накидываю push'ей, потом смотрю какие данные передаются туда.
Здесь например 2 push'a, запускаем данный скрипт в игре и ставим Break and Trace instructions на нашей jmp:
Вводим любое сообщение в чат и смотрим, какие данные передаются в наших push'ах. В первом пуше - во втором аргументе передается какой-то непонятный DWORD
Во втором пуше - первом аргументе какой-то указатель, возможно это указатель на нашу строку.
Так и есть
Теперь осталось дописать нашу функцию, которая будет ловить эти сообщения. Второй параметр можно убрать.
C++:
void __stdcall myfunc(wchar_t* arg1)
{
MessageBox(NULL, arg1, L"TEST", MB_OK);
}
void _declspec(naked) Hook( void )
{
_asm {
pushad
push[esp + 0x24] // arg1
call myfunc
popad
push edi
mov edi, [esp+0xC]
jmp ret_addr
}
}
В итоге получаем перехват сообщения:
C++:
#include <Windows.h>
#include <process.h>
#include <stdio.h>
#define CLEAR_CHAT_HOOK 0x7FF00
LPVOID ret_addr;
void __stdcall myfunc(wchar_t* arg1)
{
MessageBox(NULL, arg1, L"TEST", MB_OK);
}
void _declspec(naked) Hook( void )
{
_asm {
pushad
push[esp + 0x24] // arg1
call myfunc
popad
push edi
mov edi, [esp+0xC]
jmp ret_addr
}
}
void SetupHook(DWORD dwSamp)
{
DWORD dwAddr = dwSamp + CLEAR_CHAT_HOOK;
ret_addr = (LPVOID)(dwAddr + 5);
DWORD dwProt = PAGE_EXECUTE_READWRITE;
VirtualProtect((void *)dwAddr, 5, dwProt, &dwProt);
unsigned char* pdata = (unsigned char*)dwAddr;
pdata[0] = 0xE9; // jmp
*(unsigned int*)& pdata[1] = (unsigned int)Hook - (dwAddr + 5);
VirtualProtect((void*)dwAddr, 5, dwProt, NULL);
}
void attach(PVOID)
{
DWORD dwSamp = (DWORD)GetModuleHandle(L"samp.dll");
while (dwSamp == NULL)
{
Sleep(1000);
dwSamp = (DWORD)GetModuleHandle(L"samp.dll");
}
SetupHook(dwSamp);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH) _beginthread(attach, NULL, NULL);
return TRUE;
}
Вообще не понятно, что данная функция делает, но наша цель была перехватить сообщение, выводимое в чат, цель достигнута.
Я только изучаю все это дело, поэтому способ может быть не самый лучший. Может кто знает что-нибудь по лучше?
Вложения
Последнее редактирование: