Некие проблеммы во время хука... - Вопросы и ответы, обсуждения - Ваши вопросы по C/C++ только в данном разделе
23.04.2013, 16:46
#1
Пехотинец
Регистрация: 10.10.2011
Сообщений: 65
Популярность: 772
Сказал(а) спасибо: 58
Поблагодарили 57 раз(а) в 32 сообщениях
Некие проблеммы во время хука...
сабж что такое смутно догадываюсь
вот полный код
PHP код:
#include <Winsock2.h>
//DWORD address_one = 0x00792C72;
DWORD address_two = 0x750698FD ;
DWORD address_hook = 0 ;
DWORD address_jmp = 0x75069903 ;
void hook ()
{
MessageBoxA ( 0 , "Тест" , "Тест" , 0 );
leave
mov edi , edi
push ebp
mov ebp , esp
xor eax , eax
jmp dword ptr address_jmp
}
}
void SetHook ()
{
_asm call dword ptr address_hook
}
BOOL APIENTRY DllMain ( HMODULE hModule ,
DWORD ul_reason_for_call , LPVOID lpReserved )
{
switch ( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH :
{
address_hook = ( DWORD ) hook ;
DWORD old_prot = 0 ;
VirtualProtect (( void *) address_two , 6 , PAGE_EXECUTE_READWRITE ,& old_prot );
memcpy (( void *) address_two ,( PBYTE ) SetHook , 6 );
VirtualProtect (( void *) address_two , 6 , old_prot ,& old_prot );
}
case DLL_THREAD_ATTACH :
case DLL_THREAD_DETACH :
case DLL_PROCESS_DETACH :
break;
}
return TRUE ;
}
}
в данном примере я пытался хукнуть FindWindowW внутри функции ...
но при попытке вызова функции выдаёт ошибку
пытался восстонавливать регистры через простое копиривание их в переменные и при выполнении функции восстонавливать но там уже чуточку другая ошибка(leave я потом добавил)
27.04.2013, 15:31
#2
Сержант
Регистрация: 01.10.2011
Сообщений: 128
Популярность: 5723
Сказал(а) спасибо: 25
Поблагодарили 174 раз(а) в 105 сообщениях
Re: Некие проблеммы во время хука...
Это вы так сплайсингом хукаете?
Начнем с начала.
1. Нам нужно получить адрес оригинальной функции, где это у вас?
Код:
#include <Windows.h>
DWORD WINAPI Inject_Thread (LPVOID);
DWORD APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, NULL, Inject_Thread, NULL, NULL, NULL);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
default:
break;
}
return true;
}
DWORD WINAPI Inject_Thread (LPVOID)
{
DWORD dwFindWindow = GetProcAddress(GetModuleHandle("User32.dll"), "FindWindowW"); //получаем адрес оригинальной функции
ExitThread(0);
}
2. Трамплин и место приземления
Код:
#include <Windows.h>
DWORD WINAPI Inject_Thread (LPVOID);
DWORD APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, NULL, Inject_Thread, NULL, NULL, NULL);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
default:
break;
}
return true;
}
DWORD jmpAddr; //место приземления
HWND WINAPI jmpFindWindow(
_In_opt_ LPCTSTR lpClassName,
_In_opt_ LPCTSTR lpWindowName
) //Прототип трамплина, прямиком с MSDN
{
_asm jmp [jmpAddr]
}
DWORD WINAPI Inject_Thread (LPVOID)
{
DWORD dwFindWindow = GetProcAddress(GetModuleHandle("User32.dll"), "FindWindowW");
jmpAddr = dwFindWindow + 5; //задаем место приземления
ExitThread(0);
}
3. Установка хука
Код:
#include <Windows.h>
DWORD WINAPI Inject_Thread (LPVOID);
DWORD APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, NULL, Inject_Thread, NULL, NULL, NULL);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
default:
break;
}
return true;
}
DWORD jmpAddr;
HWND WINAPI jmpFindWindow(
_In_opt_ LPCTSTR lpClassName,
_In_opt_ LPCTSTR lpWindowName
)
{
_asm jmp [jmpAddr]
}
HWND WINAPI hookFindWindow(
_In_opt_ LPCTSTR lpClassName,
_In_opt_ LPCTSTR lpWindowName
) //Сам хук
{
//TODO: Добавить логику хука
return jmpFindWindow(lpClassName, lpWindowName);
}
char jmpBytes[5]; //5 байт, опкод + адрес
char originalBytes[5]; //5 байт, оригинальные 5 байт функции, на случай если нужно снять хук
DWORD WINAPI Inject_Thread (LPVOID)
{
DWORD dwFindWindow = GetProcAddress(GetModuleHandle("User32.dll"), "FindWindowW");
jmpAddr = dwFindWindow + 5;
DWORD addr = (DWORD)hookFindWindow - (jmpAddr + 5); // на сколько прыгнуть, смещение
jmpBytes[0] = 0xE9; //опкод jmp'а
memcpy(&jmpBytes[1], &addr, sizeof(DWORD));
memcpy(&originalBytes[0], (LPVOID)dwFindWindow, sizeof(DWORD)); //Сохранили оригинальные 5 байт
memcpy((LPVOID)dwFindWindow, jmpBytes, 5); // Поставили хук
memcpy((LPVOID)dwFindWindow, originalBytes, 5); // Сняли хук
ExitThread(0);
}
________________
Talk is cheap. Show me the code
— Linus Torvalds
Последний раз редактировалось Yukikaze; 27.04.2013 в 15:37 .
Пользователь сказал cпасибо:
29.04.2013, 11:15
#3
Пехотинец
Регистрация: 10.10.2011
Сообщений: 65
Популярность: 772
Сказал(а) спасибо: 58
Поблагодарили 57 раз(а) в 32 сообщениях
Re: Некие проблеммы во время хука...
спасибо! я использовал ваш пример посмотрел и всё улучшилось но не сильно =( всё равно краш...
попробовал провести через отладчик на се по шагам всё получилось даже хз что это =(
но потом всё равно выключается...
может я что то опять не то сделал?
снизу я выложил файл что патчить и проэкт патча
посмотрите пожалуйста
Последний раз редактировалось артём612; 29.04.2013 в 11:44 .
29.04.2013, 14:45
#4
Сержант
Регистрация: 01.10.2011
Сообщений: 128
Популярность: 5723
Сказал(а) спасибо: 25
Поблагодарили 174 раз(а) в 105 сообщениях
Re: Некие проблеммы во время хука...
Поправил исходник
Код:
#include <Windows.h>
#pragma comment(lib,"user32.lib")
DWORD WINAPI Inject_Thread (LPVOID);
extern "C"
DWORD APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, 0, Inject_Thread, NULL, 0, NULL);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
default:
break;
}
return true;
}
DWORD jmpAddr;
HWND WINAPI jmpFindWindow(LPCWSTR lpClassName, LPCWSTR lpWindowName)
{
__asm jmp jmpAddr;
}
HWND WINAPI hookFindWindow(LPCWSTR lpClassName, LPCWSTR lpWindowName) //Сам хук
{
//TODO: Добавить логику хука
MessageBoxW(0, lpWindowName, lpClassName, MB_OK);
return jmpFindWindow(lpClassName, lpWindowName);
}
char jmpBytes[5]; //5 байт, опкод + адрес
char originalBytes[5]; //5 байт, оригинальные 5 байт функции, на случай если нужно снять хук
DWORD WINAPI Inject_Thread (LPVOID)
{
DWORD dwFindWindow = (DWORD)GetProcAddress(GetModuleHandle("User32.dll"), "FindWindowW");
jmpAddr = dwFindWindow + 5;
DWORD addr = (DWORD)hookFindWindow - (dwFindWindow + 5); // на сколько прыгнуть, смещение
jmpBytes[0] = 0xE9; //опкод jmp'а
memcpy(&jmpBytes[1], &addr, sizeof(DWORD));
memcpy(&originalBytes[0], (LPVOID)dwFindWindow, 5); //Сохранили оригинальные 5 байт
DWORD old;
VirtualProtect((LPVOID)dwFindWindow, 5, PAGE_EXECUTE_READWRITE, &old);
if(memcpy((LPVOID)dwFindWindow, jmpBytes, 5) > 0)
MessageBoxA(0, "Хук установлен", "Info", MB_OK); // Поставили хук
VirtualProtect((LPVOID)dwFindWindow, 5, old, &old);
//memcpy((LPVOID)dwFindWindow, originalBytes, 5); // Сняли хук
Sleep(5000);
FindWindowW(NULL, L"Winject"); //Проверка хука
ExitThread(0);
}
Пример: [
Ссылки могут видеть только зарегистрированные пользователи. ]
Прошлый раз писал без IDE и не компилировал, поэтому допустил пару глупых ошибок, например
Код:
DWORD addr = (DWORD)hookFindWindow - (jmpAddr + 5);
а нужно было
Код:
DWORD addr = (DWORD)hookFindWindow - (dwFindWindow + 5);
В общем, работает
[
Ссылки могут видеть только зарегистрированные пользователи. ]
Добавлено через 32 минуты
Можно сделать более элегантно, так сказать по C++'ному
detour.h
Код:
#ifndef DETOUR_H
#define DETOUR_H
class Detour
{
public:
Detour(void* lpTarget, void* lpHook);
~Detour();
void Apply();
void Remove();
bool IsApplied;
private:
char* bOriginal;
char* bHook;
void* lpTarget;
};
#endif // DETOUR_H
detour.cpp
Код:
#include "detour.h"
#include <Windows.h>
Detour::Detour(void* lpTarget, void* lpHook)
{
bOriginal = new char[5];
bHook = new char[5];
this->lpTarget = lpTarget;
memcpy(this->bOriginal, lpTarget, 5);
this->bHook[0] = (char)0xe9;
DWORD addr = (DWORD)lpHook - ((DWORD)lpTarget + 5);
memcpy(&this->bHook[1], &addr, sizeof(DWORD));
}
Detour::~Detour()
{
this->Remove();
delete[] this->bHook;
delete[] this->bOriginal;
}
void Detour::Apply()
{
DWORD old;
VirtualProtect(this->lpTarget, 5, PAGE_EXECUTE_READWRITE, &old);
memcpy(this->lpTarget, this->bHook, 5);
this->IsApplied = true;
VirtualProtect(this->lpTarget, 5, old, &old);
}
void Detour::Remove()
{
DWORD old;
VirtualProtect(this->lpTarget, 5, PAGE_EXECUTE_READWRITE, &old);
memcpy(this->lpTarget, this->bOriginal, 5);
this->IsApplied = false;
VirtualProtect(this->lpTarget, 5, old, &old);
}
main.cpp
Код:
#include <Windows.h>
#include "detour.h"
#pragma comment(lib,"user32.lib")
DWORD WINAPI Inject_Thread (LPVOID);
extern "C"
DWORD APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, 0, Inject_Thread, NULL, 0, NULL);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
default:
break;
}
return true;
}
Detour* FindWindow_Detour;
HWND WINAPI hookFindWindow(LPCWSTR lpClassName, LPCWSTR lpWindowName) //Сам хук
{
MessageBoxW(0, lpWindowName, lpClassName, MB_OK);
FindWindow_Detour->Remove(); //Сняли хук
HWND retVal = FindWindowW(lpClassName, lpWindowName); //Вызвали оригинал
FindWindow_Detour->Apply(); //Вернули хук
return retVal;
}
DWORD WINAPI Inject_Thread (LPVOID)
{
void* lpFindWindow = GetProcAddress(GetModuleHandle("User32.dll"), "FindWindowW");
FindWindow_Detour = new Detour(lpFindWindow, hookFindWindow);
FindWindow_Detour->Apply();
ExitThread(0);
}
________________
Talk is cheap. Show me the code
— Linus Torvalds
Последний раз редактировалось Yukikaze; 29.04.2013 в 16:51 .
Причина: Добавлено сообщение
Пользователь сказал cпасибо:
29.04.2013, 17:10
#5
Пехотинец
Регистрация: 10.10.2011
Сообщений: 65
Популярность: 772
Сказал(а) спасибо: 58
Поблагодарили 57 раз(а) в 32 сообщениях
Re: Некие проблеммы во время хука...
Спасибо большое буду должен =_= хук работает как часы =)
Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
Заявление об ответственности / Список мошенников
Часовой пояс GMT +4, время: 08:33 .