.header
static bool User_UseItem(User *pUser, CItem *pItem);
.cpp
g_HookManager.WriteCall( 0x008257C0, CAntiExploit::User_UseItem, 0);
bool CAntiExploit::User_UseItem(User *pUser, CItem *pItem)
{
if (pItem->pSID->nItemID > 0)
{
pUser->pSocket->SendSystemMessage(L"You odel odejdu!!!");
}else
{
pUser->pSocket->SendSystemMessage(L"You goliy !!!");
}
typedef bool (*f)(CItem*);
return f(0x008257C0L)(pItem);
}
это неудачный пример я сюда выписал вам. оно не с двумя передаваемыми, не с одним не хочет возвращаться к реальной функции. знаю, что нужно писать ссылки в asm на мою функцию и потом обратно, это я не умею, это я сейчас начал учить. как я понял без asm частично заменить функцию. сервера на мою не получится.А почему у тебя в хуке 2 параметра а пытаясь вызвать оригинал ты передаешь 1 аргумент всего лишь?
return ((bool(__stdcall*)(User*, CItem*))(0x008257C0))(pUser, pItem);
вагантовый хукменеджер, из его проэкта.Я бы попробовал так:
return ((bool(__stdcall*)(User*, CItem*))(0x008257C0))(pUser, pItem);
соглашение о вызове подставь правильное
И что вообще делает WriteCall у тебя?
void CHookManager::WriteCall(UINT64 Address, PVOID Function, SIZE_T Nops, LPBYTE OrgBytes)
{
if(Address && Function)
{
Lock();
SIZE_T Size = 5 + Nops;
if(ValidOrgBytes(Address, OrgBytes, Size))
{
if(TryWrite(Address, Size))
{
DWORD dwOldProtect = NULL;
SIZE_T BytesWritten = NULL;
PUCHAR Buffer = new unsigned char[Size];
if(Buffer)
{
memset(Buffer, 0, Size);
Buffer[0]=CALL;
UINT functionAddr = (UINT)Function;
functionAddr-=Address+5;
memcpy(&Buffer[1], &functionAddr, 4);
if(Nops)
{
for(int n=5; n<Size; n++)
{
Buffer[n]=0x90;
}
}
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessId());
if(hProcess)
{
if(!VirtualProtect((LPVOID)Address, Size, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
ShowMessage("Hook Manager", "Failed to set new protection with VirtualProtect at address [%p]!", Address);
}
if (WriteProcessMemory(hProcess, (LPVOID)Address, Buffer, Size, &BytesWritten))
{
Write(Address, Size);
}else
{
ShowMessage("Hook Manager", "Failed to write process memory at address[%p]!", Address);
Unlock();
ExitProcess(0);
return;
}
if(!VirtualProtect((LPVOID)Address, Size, dwOldProtect, &dwOldProtect))
{
ShowMessage("Hook Manager", "Failed to set old protection with VirtualProtect at address [%p]!", Address);
}
CloseHandle(hProcess);
}else
{
ShowMessage("Hook Manager", "Failed to get process handle!");
Unlock();
ExitProcess(0);
return;
}
delete [] Buffer;
}else
{
ShowMessage("Hook Manager", "Cannot allocate memory for buffer!");
Unlock();
ExitProcess(0);
return;
}
}
}
Unlock();
}
}
Я бы попробовал так:
return ((bool(__stdcall*)(User*, CItem*))(0x008257C0))(pUser, pItem);
соглашение о вызове подставь правильное
И что вообще делает WriteCall у тебя?
Доброго времени. Такое дело, в С++ не очень давно. решил поработать с хуками, взял исход ванганта (интерлюд) решил хукнуть функцию, так для опыта.
Написал хук на адресс функции (0x008257C0, "User::EquipItem()"); cс таким вот содержимым.
При вызове функции в игре, при одевании предмета, условия, написаные мной в моей функции выполняются, мне пишет в систем чат что я одел одежду, но сервер крашится, так как продолжения нет, вот собственно и вопрос, как мне после выполнения моего хука функции, вернутся в стандартную функцию l2servera.C++:.header static bool User_UseItem(User *pUser, CItem *pItem); .cpp g_HookManager.WriteCall( 0x008257C0, CAntiExploit::User_UseItem, 0); bool CAntiExploit::User_UseItem(User *pUser, CItem *pItem) { if (pItem->pSID->nItemID > 0) { pUser->pSocket->SendSystemMessage(L"You odel odejdu!!!"); }else { pUser->pSocket->SendSystemMessage(L"You goliy !!!"); } typedef bool (*f)(CItem*); return f(0x008257C0L)(pItem); }
int ololo(int a1, int a2, int a3);
int __fastcall ololo_hook(void* _this, int EDX_stub, int a1, int a2, int a3);
Спасибо за подсказку, все верно, fastcall в моем случае будет правильным. Вашими постами, вы помогли мне дойти до сути, и сделать свой первый хук, спасибо ещё раз!!!Как уже написали выше - ты получаешь бесконечную рекурсию. При установке хука необходимо сохранять адрес трамплина в оригинальную функцию. Как ставить хуки можешь посмотреть, к примеру, тут -Вы не можете просматривать ссылку пожалуйста воспользуйтесь следующими ссылками Вход или Регистрация
Второй момент - calling conventions. Если ты хукаешь метод класса, то ты не можешь для него просто взять и объявить хук как __thiscall, компилятор такое не соберет (есть исключения, но сейчас не о них).
Для хуков методов класс применяют трюк с __fastcall, который схож с __thiscall и имеет лишь небольшие различия:
При __fastcall первые 2 аргумента передаются в регистрах ECX и EDX.
При __thiscall контекст выполнения this передается через регистр ECX, а аргументы через стек.
Допустим это сигнатура метода класса:
C++:int ololo(int a1, int a2, int a3);
Тогда хук будет выглядеть примерно так:
C++:int __fastcall ololo_hook(void* _this, int EDX_stub, int a1, int a2, int a3);
Вы забыли добавить что это верно для х86 (о чем свидетельствуют названия регистров).Для хуков методов класс применяют трюк с __fastcall, который схож с __thiscall и имеет лишь небольшие различия:
При __fastcall первые 2 аргумента передаются в регистрах ECX и EDX.
При __thiscall контекст выполнения this передается через регистр ECX, а аргументы через стек.
Дак автору и надо для x86, поэтому пример приведен для его случаяВы забыли добавить что это верно для х86 (о чем свидетельствуют названия регистров).
все верно. в моем случае быстрый вызов (fastcall подошел)Автор хукает L2server.exe из C4 PTS, который -таки 64битный
Тогда неувязочка вышла, так как думал, что автор ковыряется в клиентеАвтор хукает L2server.exe из C4 PTS, который -таки 64битный
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?