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.Создаю
В каком это смысле?В параметре приходит L2ParamStack
Я от туда извлекаю то что мне нужно т.е данные.
потом создаю чистый L2ParamStack
Засовываю туда данные,и отправляю на сервер вызовом оригинальной функции.
Вот только данные вставить нормально не могу(
...
Но блин откуда взять
1.UnetworkHandler,нужен он вобще или нет?
2.Как правильно запихнуть данные и отправить?
зачем пользоваться глючным стеком? оО
можно проще. например(с++):
перехват инита, для получения NetworkHandler - чистая магия, местами подогнанная по месту, так что приведена исключительно для осознания что и куда.
p.s.как-то пробовал сделать на делфи - могу поискать исходники, но они "портированы" с с++, так что по сути тоже самое
p.p.s. есть еще способ (если защита смотрит откуда сенд вызван)
__________________
C++Builder 6, Delphi 7, RAD Studio XE2, MS VC++...
Последний раз редактировалось Elecktron, 03.10.2013 в 16:09.
зачем пользоваться глючным стеком? оО
можно проще. например(с++):
перехват инита, для получения NetworkHandler - чистая магия, местами подогнанная по месту, так что приведена исключительно для осознания что и куда.
p.s.как-то пробовал сделать на делфи - могу поискать исходники, но они "портированы" с с++, так что по сути тоже самое
p.p.s. есть еще способ (если защита смотрит откуда сенд вызван)
Тема наверное уже мертва но всё равно попробую
Может кто-то напишет пример как на дельфях получить этот долбаный NetworkHandler