library hook;
uses
Windows, //Для GetProcAddress
Variants, //Для перевода VarToStr(Когда выводим MessageDlg)
Dialogs, //Ну собствено для MessageDlg
advApiHook, //Для HookProc
SysUtils; //Для IntToStr и обратно.type
TL2ParamStack = array[0..16] ofbyte; //Тип L2ParamStack это массив из 16 байт.
PL2ParamStack = ^TL2ParamStack;
TL2Param = class//Делаем с Tl2param сразу классом.Для простого управления.
l2p: PL2ParamStack; //Парамет имеет тип с 16 байт.publicconstructor Create; //Конструктор.destructor Destroy; //Деструктор.procedure l2PushBack(cmd: string); // L2patamStack [00 00 00 00 00 00 00 00 xx xx xx xx xx xx xx xx] в xx- помещаем String Значение.procedure l2PushBackInt(i: integer); // L2patamStack [00 00 00 00 00 00 00 00 00 00 00 00 xx xx xx xx] в xx- помещаем Int Значение.procedure l2Clear; //Очищаем тип.procedure l2Free; //Освобождаем.end;
var//Указатель на UNetworkHandler]
NH:Pointer;
//-------------------Указатели на оригинальные процедуры------------------//
L2ParamStackCreate_Original: procedure(i: integer); stdcall; //Создать стек.
L2ParamStackClear_Original: procedure; stdcall; //Очистить стек.
L2ParamStackPushBack_Original: function(i: pointer): integer; stdcall; //Вставляем значение в стек.
L2ParamStackTop_Original: Procedure(i:Pointer); stdcall; //Достает значение с вершины стека.
L2ParamStackFree_Original: procedure; stdcall; //Очистить стек.
Init_UNetworkHandler_Original:Procedure(I:Integer;UGameEngine:Pointer);stdcall;
//----------------------Тут наши процедуры которые хукаем.------------------------//
UseItem_Original: Procedure(l2p:Pl2ParamStack); stdcall;
//--------------------------------------------------------------------------------//procedure l2stackCreate(l2p: PL2ParamStack); stdcall; //Создали стек.
asm
push ecx;
mov ecx,l2p;
push 0Ah;
call [L2ParamStackCreate_Original];
pop ecx;
end;
procedure L2StackPushBack(l2p: PL2ParamStack; cmd: string); stdcall;//Заполняем стек(последнее значение) строкой.
asm
mov ecx,cmd;
push ecx;
mov ecx,l2p;
call [L2ParamStackPushBack_Original];
end;
procedure L2StackPushBackInt(l2p: PL2ParamStack; cmd: Integer); stdcall; //Заполняем стек(последнее значение) Int числом (8 байт).
asm
mov ecx,cmd;
push ecx;
mov ecx,l2p;
call [L2ParamStackPushBack_Original];
end;
procedure L2StackClear(l2p: PL2ParamStack); stdcall; //Очищаем стек.
asm
mov ecx,l2p;
call [L2ParamStackClear_Original];
end;
procedure L2StackFree(l2p: PL2ParamStack); stdcall; //Убиваем стек.
asm
mov ecx,l2p;
call [L2ParamStackFree_Original];
end;
constructor TL2Param.create;//Создание L2ParamStack.beginNew(l2p);//Создали новый динамический класс L2ParamStack.
L2StackCreate(l2p);
end;
destructor TL2Param.Destroy;//Разрушение L2ParamStack.beginDispose(l2p);
end;
procedure TL2Param.l2Clear;//Очищение L2ParamStack.begin
L2StackClear(l2p);
end;
procedure TL2Param.l2Free;//Освобождение L2ParamStack.begin
L2StackFree(l2p);
end;
procedure TL2Param.l2PushBack(cmd: string);//Наш переходник вставки cтроки в L2ParamStackbegin
L2StackPushBack(l2p,cmd);
end;
procedure TL2Param.l2PushBackInt(i: integer);//Наш переходник вставки числа в L2ParamStackbegin
L2StackPushBackInt(l2p,i);
end;
procedure UseItem_Call(l2p: PL2ParamStack); stdcall;
asm
push l2p;
mov ecx, NH;// nh - указатель на UNetworkHandler
call [UseItem_Original];
end;
Procedure UseItem(Oid:Integer); //Тут уже формируем ParamStackvar
param: TL2Param;
begin
param:= TL2Param.Create; //Создали Класс.
param.l2Clear; //Очистили Класс.
param.l2PushBackInt(Oid); //В конец Стака вставили значение.
UseItem_call(param.l2p); //Вызвали процедуру уже с переходом на оригинальну.
param.l2Free; //Освободили Класс.
param.Destroy; //Разрушили класс,так как он у нас динамический.end;
Procedure UseItem_Hook(l2p:PL2ParamStack); //Хукнутая процедура(тут получить параметры и извлекать)var
ObjOid:Integer;
begin
asm
mov esi,[L2p] //Премещаю в esi L2ParamStack
mov ecx,esi //В ecx премещаю L2ParamStack
Call [L2ParamStackTop_Original] //Посылаю в оригинальную функцию L2ParamStackTop_Original параметр ecx т.е наш L2ParamStack
mov [ObjOid],eax //Получаю резултат от функции в eax и записываю его в ObjOidend;
MessageDlg('Функция UseItem Была перехвачена.OidПредмета:'+IntToStr(ObjOid),mtInformation, [mbOk],0);
//UseItem(Oid);//Вызываем нормальную процедуру.end;
Procedure Init_UNetworkHandler_Hook(I:Integer;UGameEngine:Pointer);
begin
asm
mov esi,[UGameEngine];
mov [NH],esi;
//call Init_UNetworkHandler_Original;end;
MessageDlg('UNetworkHandler:'+VarToStr(DWORD(NH)),mtInformation, [mbOk],0);
if UnhookCode(@Init_UNetworkHandler_Original)thenMessageDlg('Хук на UNetworkHandler успешно снят.',mtInformation, [mbOk],0)elseMessageDlg('Не смогли снять хук на UNetworkHandler',mtInformation, [mbOk],0);
end;
begin//Сначала деаем хук на стаковские процедуры.////Interlude ??0L2ParamStack@@QAE@AAV0@@Z
L2ParamStackCreate_Original:= GetProcAddress(GetModuleHandle('Core.dll'),'??0L2ParamStack@@QAE@AAV0@@Z');
//Interlude ?Clear@L2ParamStack@@QAEXXZ
L2ParamStackClear_Original:= GetProcAddress(GetModuleHandle('Core.dll'),'?Clear@L2ParamStack@@QAEXXZ');
//Interlude ?PushBack@L2ParamStack@@QAEHPAX@Z
L2ParamStackPushBack_Original:= GetProcAddress(GetModuleHandle('Core.dll'),'?PushBack@L2ParamStack@@QAEHPAX@Z');
//Interlude ??1L2ParamStack@@QAE@XZ
L2ParamStackFree_Original:= GetProcAddress(GetModuleHandle('Core.dll'),'??1L2ParamStack@@QAE@XZ');
//Interlude ??1L2ParamStack@@QAE@XZ
L2ParamStackTop_Original:=GetProcAddress(GetModuleHandle('Core.dll'),'?Top@L2ParamStack@@QAEPAXXZ');
//Ставим хук на Init_UNetworkHandler.
HookProc('Engine.dll','?Init@UNetworkHandler@@UAEXHPAVUGameEngine@@@Z', @Init_UNetworkHandler_Hook, @Init_UNetworkHandler_Original);
//Ставим хуки на свои процедуры.
HookProc('Engine.dll','?RequestUseItem@UNetworkHandler@@UAEHAAVL2ParamStack@@@Z', @UseItem_Hook, @UseItem_Original);
end.
Delphi Код:
Procedure Init_UNetworkHandler_Hook(I:Integer;UGameEngine:Pointer);
begin
asm
mov esi,[UGameEngine];
mov [NH],esi;
//call Init_UNetworkHandler_Original;end;
MessageDlg('UNetworkHandler:'+VarToStr(DWORD(NH)),mtInformation, [mbOk],0);
if UnhookCode(@Init_UNetworkHandler_Original)thenMessageDlg('Хук на UNetworkHandler успешно снят.',mtInformation, [mbOk],0)elseMessageDlg('Не смогли снять хук на UNetworkHandler',mtInformation, [mbOk],0);
end;
Как сделать возврат в оригинальную?
Получать то получаю UnetworkHandler а вот назад его запихнуть не могу(
Или как получить этот указатель другим путем.:?
library hook;
uses
Windows, //Для GetProcAddress
Variants, //Для перевода VarToStr(Когда выводим MessageDlg)
Dialogs, //Ну собствено для MessageDlg
advApiHook, //Для HookProc
SysUtils; //Для IntToStr и обратно.type
TL2ParamStack = array[0..16] ofbyte; //Тип L2ParamStack это массив из 16 байт.
PL2ParamStack = ^TL2ParamStack;
TL2Param = class//Делаем с Tl2param сразу классом.Для простого управления.
l2p: PL2ParamStack; //Парамет имеет тип с 16 байт.publicconstructor Create; //Конструктор.destructor Destroy; //Деструктор.procedure l2PushBack(cmd: string); // L2patamStack [00 00 00 00 00 00 00 00 xx xx xx xx xx xx xx xx] в xx- помещаем String Значение.procedure l2PushBackInt(i: integer); // L2patamStack [00 00 00 00 00 00 00 00 00 00 00 00 xx xx xx xx] в xx- помещаем Int Значение.procedure l2Clear; //Очищаем тип.procedure l2Free; //Освобождаем.end;
var//Указатель на UNetworkHandler
UNetworkHundler:Pointer;
//-------------------Указатели на оригинальные процедуры------------------//
L2ParamStackCreate_Original: procedure(i: integer); stdcall; //Создать стек.
L2ParamStackClear_Original: procedure; stdcall; //Очистить стек.
L2ParamStackPushBack_Original: function(i: pointer): integer; stdcall; //Вставляем значение в стек.
L2ParamStackTop_Original: Procedure(i:Pointer); stdcall; //Достает значение с вершины стека.
L2ParamStackFree_Original: procedure; stdcall; //Очистить стек.
Init_UNetworkHandler_Original:Procedure(I:Integer;UGameEngine:Pointer);stdcall;
//----------------------Тут наши процедуры которые хукаем.------------------------//
UseItem_Original: Procedure(l2p:Pl2ParamStack); stdcall;
//--------------------------------------------------------------------------------//Function L2ParamStackToString(l2p:Pl2ParamStack):String;
var
i:Integer;
S:String;
begin
S:='';
for i:=1to16dobeginif(l2p[i] in [0..9])then S:=S+'0'+IntToStr(l2p[i])+' 'else
S:=S+IntToStr(l2p[i])+' ';
end;
result:=S;
end;
procedure l2stackCreate(l2p: PL2ParamStack); stdcall; //Создали стек.
asm
push ecx;
mov ecx,l2p;
push 0Ah;
call [L2ParamStackCreate_Original];
pop ecx;
end;
procedure L2StackPushBack(l2p: PL2ParamStack; cmd: string); stdcall;//Заполняем стек(последнее значение) строкой.
asm
mov ecx,cmd;
push ecx;
mov ecx,l2p;
call [L2ParamStackPushBack_Original];
end;
procedure L2StackPushBackInt(l2p: PL2ParamStack; cmd: Integer); stdcall; //Заполняем стек(последнее значение) Int числом (8 байт).
asm
mov ecx,cmd;
push ecx;
mov ecx,l2p;
call [L2ParamStackPushBack_Original];
end;
procedure L2StackClear(l2p: PL2ParamStack); stdcall; //Очищаем стек.
asm
mov ecx,l2p;
call [L2ParamStackClear_Original];
end;
procedure L2StackFree(l2p: PL2ParamStack); stdcall; //Убиваем стек.
asm
mov ecx,l2p;
call [L2ParamStackFree_Original];
end;
constructor TL2Param.create;//Создание L2ParamStack.beginNew(l2p);//Создали новый динамический класс L2ParamStack.
L2StackCreate(l2p);
end;
destructor TL2Param.Destroy;//Разрушение L2ParamStack.beginDispose(l2p);
end;
procedure TL2Param.l2Clear;//Очищение L2ParamStack.begin
L2StackClear(l2p);
end;
procedure TL2Param.l2Free;//Освобождение L2ParamStack.begin
L2StackFree(l2p);
end;
procedure TL2Param.l2PushBack(cmd: string);//Наш переходник вставки cтроки в L2ParamStackbegin
L2StackPushBack(l2p,cmd);
end;
procedure TL2Param.l2PushBackInt(i: integer);//Наш переходник вставки числа в L2ParamStackbegin
L2StackPushBackInt(l2p,i);
end;
procedure UseItem_Call(l2p: PL2ParamStack); stdcall;
asm
push l2p;
mov ecx, UNetworkHundler;// nh - указатель на UNetworkHandler
call [UseItem_Original];
end;
Procedure UseItem(Oid:Integer); //Тут уже формируем ParamStackvar
param: TL2Param;
begin
param:= TL2Param.Create; //Создали Класс.
param.l2Clear; //Очистили Класс.
param.l2PushBackInt(Oid); //В конец Стака вставили значение.
UseItem_call(param.l2p); //Вызвали процедуру уже с переходом на оригинальну.
param.l2Free; //Освободили Класс.
param.Destroy; //Разрушили класс,так как он у нас динамический.end;
Procedure UseItem_Hook(l2p:PL2ParamStack); //Хукнутая процедура(тут получить параметры и извлекать)var
ObjOid:Integer;
begin
asm
mov esi,[L2p]; //Премещаю в esi L2ParamStack
mov [UNetworkHundler],esi;
mov ecx,esi; //В ecx премещаю L2ParamStack
Call [L2ParamStackTop_Original]; //Посылаю в оригинальную функцию L2ParamStackTop_Original параметр ecx т.е наш L2ParamStack
mov [ObjOid],eax; //Получаю резултат от функции в eax и записываю его в ObjOidend;
MessageDlg('Функция UseItem Была перехвачена.OidПредмета:'+IntToStr(ObjOid)+' L2ParamStack:'+L2ParamStackToString(l2p),mtInformation, [mbOk],0);
//UseItem(ObjOid);//Вызываем нормальную процедуру.end;
{Procedure Init_UNetworkHandler_Hook(I:Integer;UGameEngine:Pointer);
begin
asm
mov esi,[UGameEngine];
mov [NH],esi;
call Init_UNetworkHandler_Original;
end;
MessageDlg('UNetworkHandler:'+VarToStr(DWORD(NH)),mtInformation, [mbOk],0);
if UnhookCode(@Init_UNetworkHandler_Original) then MessageDlg('Хук на UNetworkHandler успешно снят.',mtInformation, [mbOk],0)
else
MessageDlg('Не смогли снять хук на UNetworkHandler',mtInformation, [mbOk],0);
end; }begin//Сначала деаем хук на стаковские процедуры.////Interlude ??0L2ParamStack@@QAE@AAV0@@Z
L2ParamStackCreate_Original:= GetProcAddress(GetModuleHandle('Core.dll'),'??0L2ParamStack@@QAE@AAV0@@Z');
//Interlude ?Clear@L2ParamStack@@QAEXXZ
L2ParamStackClear_Original:= GetProcAddress(GetModuleHandle('Core.dll'),'?Clear@L2ParamStack@@QAEXXZ');
//Interlude ?PushBack@L2ParamStack@@QAEHPAX@Z
L2ParamStackPushBack_Original:= GetProcAddress(GetModuleHandle('Core.dll'),'?PushBack@L2ParamStack@@QAEHPAX@Z');
//Interlude ??1L2ParamStack@@QAE@XZ
L2ParamStackFree_Original:= Ge[color="Red"]t[/color]ProcAddress(GetModuleHandle('Core.dll'),'??1L2ParamStack@@QAE@XZ');
//Interlude ??1L2ParamStack@@QAE@XZ
L2ParamStackTop_Original:=GetProcAddress(GetModuleHandle('Core.dll'),'?Top@L2ParamStack@@QAEPAXXZ');
//Ставим хук на Init_UNetworkHandler.//HookProc('Engine.dll','?Init@UNetworkHandler@@UAEXHPAVUGameEngine@@@Z', @Init_UNetworkHandler_Hook, @Init_UNetworkHandler_Original);//Ставим хуки на свои процедуры.
HookProc('Engine.dll','?RequestUseItem@UNetworkHandler@@UAEHAAVL2ParamStack@@@Z', @UseItem_Hook, @UseItem_Original);
end.
Что я не так делаю?
P.S Добавил функцию для отображения уже L2ParamStack.
Вот еще пока без возвратки так как еще не отловил UNetworkHandler.
Ух этот клиет,а я думаю что же будет дальше то Там же нужно будет нарыть структуру User))) и все такое
Может кто то делал это все с функциями полегче? например что то в чат ебануть?
а то да действительно гемора немного есть с L2ParamStack.)
Я прикреплю ниже свою библиотеку,протестите и скажите какие результаты пожалуйста. http://rghost.ru/48942586Вот сама библиотека хука. http://rghost.ru/48942628Вот иньектор.
ОШИБКА ТУТ
В каком это смысле?В параметре приходит L2ParamStack
Я от туда извлекаю то что мне нужно т.е данные.
потом создаю чистый L2ParamStack
Засовываю туда данные,и отправляю на сервер вызовом оригинальной функции.
Вот только данные вставить нормально не могу(
1.Создаю