PDA

Просмотр полной версии : [Помогите!] Некие проблеммы во время хука...


артём612
23.04.2013, 16:46
сабж что такое смутно догадываюсь :confused:

вот полный код

#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_R EADWRITE,&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 внутри функции ...
но при попытке вызова функции выдаёт ошибку:omg:

пытался восстонавливать регистры через простое копиривание их в переменные и при выполнении функции восстонавливать но там уже чуточку другая ошибка(leave я потом добавил) :nono:

Yukikaze
27.04.2013, 15:31
Это вы так сплайсингом хукаете?
Начнем с начала.
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);
}

артём612
29.04.2013, 11:15
спасибо! я использовал ваш пример посмотрел и всё улучшилось но не сильно =( всё равно краш...

попробовал провести через отладчик на се по шагам всё получилось даже хз что это =(
но потом всё равно выключается...

может я что то опять не то сделал?
снизу я выложил файл что патчить и проэкт патча
посмотрите пожалуйста

Yukikaze
29.04.2013, 14:45
Поправил исходник
#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);
}

артём612
29.04.2013, 17:10
Спасибо большое буду должен =_= хук работает как часы =)