Просмотр полной версии : Перехват из Engine.dll
goodvin1709
19.09.2013, 01:40
Вот уже много времени мучаюсь над тем что пытаюсь написать что то подобие перехватчика,уже и пробовал перейти на С++ но в основном сижу на делфи.
Вот проблема состоит в том что бы каким то образом перехватить любую вызывающуюся функцию из Engine.dll.
Я получил их названия под свой клиент:
Расшифрована:
int UGameEngine::OnDie(struct User *,class L2ParamStack &)
Зашифрована:
?OnDie@UGameEngine@@UAEHPAUUser@@AAVL2ParamStack@@ @Z
Но как прехватить, я вобще не понимаю, посмотрел кучу исходником.
Может найдется тот человек который разжует все, и покажет исходник как именно это осуществить.
P.S Да в принципе пофиг какая функция и какая библиотека,хоть Core.dll хоть Engine.dll
Помогите добрые люди пожалуйста.
Под Delphi есть готовая библиотека advApiHook.pas вроде есть в исходниках пакетхака.
Там есть функция
function HookProc(lpModuleName, lpProcName: PChar; NewProc: pointer; var OldProc: pointer): boolean;
var
OnDieOriginal: function (lpLibFileName: PAnsiChar): integer;
function NewFunc: integer;
begin
//код
Result:= OnDieOriginal;//вызов оригинальной функции
end;
HookProc('Engine.dll', 'OnDie', @NewFunc, @OnDieOriginal);
Но в таком виде прокатит только если перехватываемая функция идет без параметров, так как в Delphi в функции параметры передаются как stdCall, а в клиенте l2 fastcall. Нужно лепить специальный переходник. Xсor где то выкладывал на форуме.
goodvin1709
19.09.2013, 14:36
Да это уже сам перехват,а до этого что вобще нужно сделатЬ?
Каким фигом оно будет HookProc('Engine.dll', ... искать именно эту библиотеку? lpProcName: PChar; это параметр закодированого или открытого
названия функции?*
?OnDie@UGameEngine@@UAEHPAUUser@@AAVL2ParamStack@@ @Z
Вот этот параметр?
Добавлено через 7 минут
Можешь дать свой скайп что бы чуть чуть обьяснить?
Добавлено через 7 минут
Нашел сам файл advApiHook.pas
http://l2ph.coderx.ru/svn/l2phx3/3.6.x/units/advApiHook.pas
он вот тут.
Когда именно делать этот хук?
Добавлено через 24 минуты
OnDieOriginal: function (lpLibFileName: PAnsiChar): integer; Откуда ее взять?
Добавлено через 2 минуты
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,advApiHook, StdCtrls;
type
TForm1 = class(TForm)
btn1: TButton;
lbl1: TLabel;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
OnDieOriginal: function (lpLibFileName: PAnsiChar): integer;
implementation
{$R *.dfm}
function NewFunc: integer;
begin
form1.lbl1.Caption:='Перехвачена была вызвана функция.';
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
HookProc('Engine.dll', '?Say2@UNetworkHandler@@UAEXAAVL2ParamStack@@@Z', @NewFunc, @OnDieOriginal);
end;
end.
Будет ли работать так?
Да, все правильно надо передавать закодированное название функции.
Перед тем как хукать нужно подгрузить в процесс l2 свою dll, а уже в ней осуществлять перехват.
В advApiHook есть функции внедрения своей dll в чужой процесс.
goodvin1709
20.09.2013, 18:23
А так это не юнит,а library писать нужно?
Самое главное если стоит LameGuard подгружать dll нужно вручную, не добавляй ее в список автоматом загружаемых dll или у тебя дальше выбора сервера не дойдет.
Если поищешь на этом форуме есть исходники l2cc вот их могу объяснить, но там не используется хукпроцедура, там другой метод.
goodvin1709
21.09.2013, 02:46
Хотел бы с тобой пообщаться,может даш скайп или как с тобой связаться для быстрой переписки,видел l2cc
Добавлено через 4 часа 35 минут
Поковырялся,и подумал посидел, в итоге у меня что то получилось.
Взял тотал командер, через F3 вытянул названия из Engine.dll, т.е названия функций.Так как у меня Interlude клиент был под рукой,взял самую мне необходимую.
?RequestBypassToServer@UNetworkHandler@@UAEHAAVL2P aramStack@@@Z
И начал ковырять.
Написал код библиотеки:
library Project2;
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,advApiHook, StdCtrls;
{$R *.res}
var
RequestBypassToServer_Old: function (lpLibFileName: PAnsiChar): integer;
function RequestBypassToServer_New: Integer;
begin
MessageDlg('Функция RequesBypassToServer была вызвана.',mtError, [mbOk],0);
//result:=RequestBypassToServer_Old('Engine.dll');
end;
begin
HookProc('Engine.dll','?RequestBypassToServer@UNet workHandler@@UAEHAAVL2ParamStack@@@Z', @RequestBypassToServer_New, @RequestBypassToServer_Old);
end.
Взял WinInject 1.7b и прииньектил к L2.exe мою скомпилированую dll.
Все заработало.
Подхожу к NPC и нажимаю любой диалог, сразу ще выскакивает сообщение "Функция RequesBypassToServer была вызвана."
Вроде все не так уж и плохо.Но в игре действия не происходит,так как не возвращается результат.
Дальше я изменил функцию свою на :
function RequestBypassToServer_New: Integer;
begin
MessageDlg('Функция RequesBypassToServer была вызвана.',mtError, [mbOk],0);
result:=RequestBypassToServer_Old('Engine.dll');
end;
И сразу же выскакивает критом,я понял что результат не возвращается.
Теперь у меня задача,получать параметры от функций а так же их грамотно отправлять.
Помогите с этим.
Вот тут Xcor привел пример как сделать переходник для перехвата из Delphi
http://coderx.ru/showpost.php?p=50250&postcount=36
goodvin1709
21.09.2013, 03:23
Можешь сделать пример полегче,что то у меня нечего не получилось, я не понял с переходами,и откуда взять этот чертов параметр.
или даже пример как с моим перехватом Bypass,
еще очень запутался че к чему,если поподробней обьяснить.
Мне самому надо в это вникать. Вникну напишу :)
goodvin1709
24.09.2013, 09:56
Вот тут снизу мой быдлокод.
library hook;
uses
Windows, //Для GetProcAddress
Variants, //Для перевода VarToStr(Когда выводим MessageDlg)
Dialogs, //Ну собствено для MessageDlg
advApiHook, //Для HookProc
SysUtils; //Для IntToStr и обратно.
type
TL2ParamStack = array[0..16] of byte; //Тип L2ParamStack это массив из 16 байт.
PL2ParamStack = ^TL2ParamStack;
TL2Param = class //Делаем с Tl2param сразу классом.Для простого управления.
l2p: PL2ParamStack; //Парамет имеет тип с 16 байт.
public
constructor 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.
begin
New(l2p);//Создали новый динамический класс L2ParamStack.
L2StackCreate(l2p);
end;
destructor TL2Param.Destroy;//Разрушение L2ParamStack.
begin
Dispose(l2p);
end;
procedure TL2Param.l2Clear;//Очищение L2ParamStack.
begin
L2StackClear(l2p);
end;
procedure TL2Param.l2Free;//Освобождение L2ParamStack.
begin
L2StackFree(l2p);
end;
procedure TL2Param.l2PushBack(cmd: string);//Наш переходник вставки cтроки в L2ParamStack
begin
L2StackPushBack(l2p,cmd);
end;
procedure TL2Param.l2PushBackInt(i: integer);//Наш переходник вставки числа в L2ParamStack
begin
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); //Тут уже формируем ParamStack
var
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 и записываю его в ObjOid
end;
MessageDlg('Функция UseItem Была перехвачена.OidПредмета:'+IntToStr(ObjOid),mtInfor mation, [mbOk],0);
//UseItem(Oid);//Вызываем нормальную процедуру.
end;
Procedure Init_UNetworkHandler_Hook(I:Integer;UGameEngine:Po inter);
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'),'??0L2P aramStack@@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'),'?PushB ack@L2ParamStack@@QAEHPAX@Z');
//Interlude ??1L2ParamStack@@QAE@XZ
L2ParamStackFree_Original:= GetProcAddress(GetModuleHandle('Core.dll'),'??1L2P aramStack@@QAE@XZ');
//Interlude ??1L2ParamStack@@QAE@XZ
L2ParamStackTop_Original:=GetProcAddress(GetModule Handle('Core.dll'),'?Top@L2ParamStack@@QAEPAXXZ');
//Ставим хук на Init_UNetworkHandler.
HookProc('Engine.dll','?Init@UNetworkHandler@@UAEX HPAVUGameEngine@@@Z', @Init_UNetworkHandler_Hook, @Init_UNetworkHandler_Original);
//Ставим хуки на свои процедуры.
HookProc('Engine.dll','?RequestUseItem@UNetworkHan dler@@UAEHAAVL2ParamStack@@@Z', @UseItem_Hook, @UseItem_Original);
end.
Procedure Init_UNetworkHandler_Hook(I:Integer;UGameEngine:Po inter);
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;
Как сделать возврат в оригинальную?
Получать то получаю UnetworkHandler а вот назад его запихнуть не могу(
Или как получить этот указатель другим путем.:?
Добавлено через 3 часа 4 минуты
Сылка на библиотеку для хука и иньектора. (http://rghost.ru/48932514)
Добавлено через 11 часов 37 минут
UP
goodvin1709
24.09.2013, 10:19
library hook;
uses
Windows, //Для GetProcAddress
Variants, //Для перевода VarToStr(Когда выводим MessageDlg)
Dialogs, //Ну собствено для MessageDlg
advApiHook, //Для HookProc
SysUtils; //Для IntToStr и обратно.
type
TL2ParamStack = array[0..16] of byte; //Тип L2ParamStack это массив из 16 байт.
PL2ParamStack = ^TL2ParamStack;
TL2Param = class //Делаем с Tl2param сразу классом.Для простого управления.
l2p: PL2ParamStack; //Парамет имеет тип с 16 байт.
public
constructor 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:=1 to 16 do
begin
if (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.
begin
New(l2p);//Создали новый динамический класс L2ParamStack.
L2StackCreate(l2p);
end;
destructor TL2Param.Destroy;//Разрушение L2ParamStack.
begin
Dispose(l2p);
end;
procedure TL2Param.l2Clear;//Очищение L2ParamStack.
begin
L2StackClear(l2p);
end;
procedure TL2Param.l2Free;//Освобождение L2ParamStack.
begin
L2StackFree(l2p);
end;
procedure TL2Param.l2PushBack(cmd: string);//Наш переходник вставки cтроки в L2ParamStack
begin
L2StackPushBack(l2p,cmd);
end;
procedure TL2Param.l2PushBackInt(i: integer);//Наш переходник вставки числа в L2ParamStack
begin
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); //Тут уже формируем ParamStack
var
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 и записываю его в ObjOid
end;
MessageDlg('Функция UseItem Была перехвачена.OidПредмета:'+IntToStr(ObjOid)+' L2ParamStack:'+L2ParamStackToString(l2p),mtInforma tion, [mbOk],0);
//UseItem(ObjOid);//Вызываем нормальную процедуру.
end;
{Procedure Init_UNetworkHandler_Hook(I:Integer;UGameEngine:Po inter);
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'),'??0L2P aramStack@@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'),'?PushB ack@L2ParamStack@@QAEHPAX@Z');
//Interlude ??1L2ParamStack@@QAE@XZ
L2ParamStackFree_Original:= GetProcAddress(GetModuleHandle('Core.dll'),'??1L2P aramStack@@QAE@XZ');
//Interlude ??1L2ParamStack@@QAE@XZ
L2ParamStackTop_Original:=GetProcAddress(GetModule Handle('Core.dll'),'?Top@L2ParamStack@@QAEPAXXZ');
//Ставим хук на Init_UNetworkHandler.
//HookProc('Engine.dll','?Init@UNetworkHandler@@UAEX HPAVUGameEngine@@@Z', @Init_UNetworkHandler_Hook, @Init_UNetworkHandler_Original);
//Ставим хуки на свои процедуры.
HookProc('Engine.dll','?RequestUseItem@UNetworkHan dler@@UAEHAAVL2ParamStack@@@Z', @UseItem_Hook, @UseItem_Original);
end.
Что я не так делаю?
P.S Добавил функцию для отображения уже L2ParamStack.
Вот еще пока без возвратки так как еще не отловил UNetworkHandler.
Ух этот клиет,а я думаю что же будет дальше то Там же нужно будет нарыть структуру User))) и все такое
Может кто то делал это все с функциями полегче? например что то в чат ебануть?
а то да действительно гемора немного есть с L2ParamStack.)
Я прикреплю ниже свою библиотеку,протестите и скажите какие результаты пожалуйста.
http://rghost.ru/48942586Вот сама библиотека хука.
http://rghost.ru/48942628Вот иньектор.
ОШИБКА ТУТ
procedure L2StackPushBackInt(l2p: PL2ParamStack; cmd: Integer); stdcall; //Заполняем стек(последнее значение) Int числом (8 байт).
asm
mov ecx,cmd;
push ecx;
mov ecx,l2p;
call [L2ParamStackPushBack_Original];
end;
Как ее блин исправить то?
goodvin1709
26.09.2013, 10:11
UP
Добавлено через 11 часов 7 минут
UP
goodvin1709
27.09.2013, 10:29
UP
во! попробуй на cracklab.ru на форуме тему создать. там думаю подскажут :) правда регистрация галимая...
Elecktron
29.09.2013, 02:01
а какой тайный смысл перехватывать L2ParamStack?
goodvin1709
29.09.2013, 03:34
В каком это смысле?В параметре приходит L2ParamStack
Я от туда извлекаю то что мне нужно т.е данные.
потом создаю чистый L2ParamStack
Засовываю туда данные,и отправляю на сервер вызовом оригинальной функции.
Вот только данные вставить нормально не могу(
1.Создаю
procedure l2stackCreate(l2p: PL2ParamStack); stdcall;
asm
mov ecx,l2p;
push ecx;
push 0Ah;
call [L2ParamStackCreate_Original];
end;
Вот тут создали стек.Все работает хорошо.
Потом очищаю стек.
procedure L2StackClear(l2p: PL2ParamStack); stdcall;
asm
mov ecx,l2p;
call [L2ParamStackClear_Original];
end;
Тут все хорошо работает,вроде очистили.
Потом я в него вставляю что мне нужно:
procedure L2StackPushBackInt(l2p: PL2ParamStack; cmd: Integer); stdcall;
asm
mov ecx,cmd;
push ecx;
mov ecx,l2p;
call [L2ParamStackPushBack_Original];
end;
Правда тут почему то ошибка,но по плану следующий шаг отправка.
procedure UseItem_Call(l2p: PL2ParamStack); stdcall;
begin
asm
push l2p;
mov ecx, UNetworkHundler;
call [UseItem_Original];
end;
Но блин откуда взять
1.UnetworkHandler,нужен он вобще или нет?
2.Как правильно запихнуть данные и отправить?
goodvin1709
02.10.2013, 03:56
UP
goodvin1709, я тебе дал аську, авторизовал твой контакт. Почему не пишешь? Тут как то скомкано ты нагородил всего нужно разбираться постепенно.
кстати! а гугл хром таким же макаром можно будет ковырнуть? мне при вызове одной функции надо один параметр подменить.
SeregaZ, я вообще на calc.exe эксперементировал :)
а как это выглядит? небольшой патчик, типа применил к ехе целевой программы и она всегда после этого работает как надо, или эта программа висит все время в запущенном состоянии и как только целевой процесс полез за нужной функцией - делает свое черное дело.
(я к тому, что версий хрома миллион и выходят каждый раз новые - как можно предусмотреть кросплатформенность, или точнее кроссверсионность :))
Elecktron
03.10.2013, 16:06
В каком это смысле?В параметре приходит L2ParamStack
Я от туда извлекаю то что мне нужно т.е данные.
потом создаю чистый L2ParamStack
Засовываю туда данные,и отправляю на сервер вызовом оригинальной функции.
Вот только данные вставить нормально не могу(
...
Но блин откуда взять
1.UnetworkHandler,нужен он вобще или нет?
2.Как правильно запихнуть данные и отправить?
зачем пользоваться глючным стеком? оО
можно проще. например(с++):
void __cdecl ReqvMagicSkillUse(int Skill,int Ctrl,int Shift)
{
char *mask = "cddc";
asm
{
mov ECX,[UNetHandler] //UnetworkHandler
mov EDI,ECX
mov ECX,DWORD PTR DS:[EDI+0x48]
mov EDX,DWORD PTR DS:[ECX]
push Shift
push Ctrl
push Skill
push 0x39
push mask
push ECX
CALL [EDX+0x6c]
add esp,0x18
}
}
CALL [EDX+0x6c] - по сути вызов сенда в engine.dll - и его можно заменить на хардкод.
UnetworkHandler - нужен!
получить его несложно.
void __cdecl UNetworkHandlerInit_hook()
{
asm
{
mov dword [UNetHandler],ecx //он лежит в ecx, копируем
MOV EAX,DWORD PTR FS:[0] //
jmp DWORD PTR initUH_orig
}
}
HMODULE hEngine = LoadLibraryA("Engine.dll");
(FARPROC&) initUH_addr = GetProcAddress(hEngine, "?Init@UNetworkHandler@@UAEXHPAVUGameEngine@@@Z");
initUH_orig = initUH_addr + 6;
DWORD buf = (DWORD)&UNetworkHandlerInit_hook + 3;
DWORD op;
short comm =0xe9;
VirtualProtect((void*)(initUH_addr),5,PAGE_READWRI TE, &op);
DWORD offset = (DWORD) buf - (DWORD) initUH_addr - 5;
WriteProcessMemory(GetCurrentProcess(), (void*)(initUH_addr),(void*)&comm,1,NULL);
WriteProcessMemory(GetCurrentProcess(), (void*)(initUH_addr+0x01),(void*)&offset,4,NULL);
VirtualProtect((void*)(initUH_addr),5,op, &op);
перехват инита, для получения NetworkHandler - чистая магия, местами подогнанная по месту, так что приведена исключительно для осознания что и куда.
p.s.как-то пробовал сделать на делфи - могу поискать исходники, но они "портированы" с с++, так что по сути тоже самое
p.p.s. есть еще способ (если защита смотрит откуда сенд вызван)
Elecktron
10.10.2013, 00:44
как успехи?
лично у меня совсем маленький сдвиг есть :) насчет goodvin1709 не знаю :)
мне дали код, где в целевой процесс вшиваться моя дополнительная длл, и уже из нее происходит перехват целевой функции. и я испытывал на своем проекте, где использовалась та моя функция и я точно знаю что она там есть - однако процесс хука работает через раз (сразу вспомнились запуски пиратской 1С бухгалтерии почему-то :)), то нормально запустит и перехват я вижу, то сразу при запуске целевая вылетает с критом. чем в теории может быть вызвано такое нестабильное "хучение" процесса?
хром же и вовсе отказался хукаться... хотя может и не отказался, а просто не использует ту мою предполагаемую функцию, из-за которой сыр бор... нужен продвинутый апи монитор, который бы показывал крипто апи тоже! где взять такое? чтобы выяснить на 100% каким образом хром получает список названий сертификатов.
Elecktron
10.10.2013, 15:08
а я никак не могу победить обработку данных при вызове сенда
с отправкой своего и обработкой приходящего - все ок..
Частично оффтоп, частично по теме:
Задача: защитить клиентские файлы от декрипта стандартными для lineage средствами. Сделать невозможным использовать клиент lineage с серверами, Ip которых отличен от нашего.
Файлы формата: *ukx *.dat
Оплата - договоримся!
ICQ:261-900303 (Михаил)
centos, а если ты переедишь на другой хостинг и соответственно айпи поменятся - чо делать? :)
centos, а если ты переедишь на другой хостинг и соответственно айпи поменятся - чо делать? :)
В ТЗ, такие моменты описаны в тз.
goodvin1709
12.10.2013, 01:44
перехват удачно идет а вот вызов оригинальной неа(
Procedure NewMessageBeep(Type.l)
MessageRequester("APIHOOK", "Beep!")
!jmp dword[p_oldMessageBeep]
EndProcedure
***
*oldMessageBeep = sethook("crypt32.dll", "CertGetCertificateContextProperty", @NewMessageBeep())
а вот такого у тебя подобного нет?
Elecktron
16.10.2013, 15:19
Файлы формата: *ukx *.dat
Михаил, в этих файлах невозможно сделать привязку, по причине того, что в них нет исполняемого кода - это файлы текстур и текстовых данных клиента.
cvillian
27.03.2015, 13:46
зачем пользоваться глючным стеком? оО
можно проще. например(с++):
перехват инита, для получения NetworkHandler - чистая магия, местами подогнанная по месту, так что приведена исключительно для осознания что и куда.
p.s.как-то пробовал сделать на делфи - могу поискать исходники, но они "портированы" с с++, так что по сути тоже самое
p.p.s. есть еще способ (если защита смотрит откуда сенд вызван)
Тема наверное уже мертва но всё равно попробую :)
Может кто-то напишет пример как на дельфях получить этот долбаный NetworkHandler :)
Elecktron
08.04.2015, 00:55
как я уже упоминал - "портировано 1 к 1 с с++":
получение указателя на экземпляр UNetworkHandler'а
UNetworkHandler: Pointer
//UNetworkHandler_Init
procedure UNetworkHandlerInit_hook();
asm
mov UNetworkHandler, ecx //сохраняем указатель на экземпляр
MOV EAX,DWORD PTR FS:[0] //
jmp DWORD PTR initUH_orig //прыгаем в оригинальную
end;
внедрение кода (ставим свои адреса и радуемся)
function InitThread(lpParameter: pointer):dword;// stdcall;
begin
//подождать engine.dll, и начать внедрение своего кода
repeat
Sleep(100);
until (GetModuleHandleA('engine.dll')<>0);
buf := DWORD(@UNetworkHandlerInit_hook);
//тут магия, хардкод и шанс попортить регистры.
initUH_orig:=Engine+$003B2D96;
comm :=$e9;
// Обычно страницы в этой области недоступны для записи
// поэтому принудительно разрешаем запись
VirtualProtect(ptr(Engine+$003B2D90),5,PAGE_READWR ITE, @op);
//вычисляем смещение которое запишем в джамп
offset := buf - (Engine+$003B2D90 + 5);
// Пишем новый адрес
// нужно писать СМЕЩЕНИЕ!
WriteProcessMemory(GetCurrentProcess(), ptr(Engine+$003B2D90),@comm,1,written);
WriteProcessMemory(GetCurrentProcess(), ptr(Engine+$003B2D90+$01),@offset,4,written);
end;
"DLL Main"
procedure DLLEntryPoint(dwReason: DWORD); export;
var
ThreadId:dword;
begin
case dwReason of
DLL_PROCESS_ATTACH:
begin
CreateThread(nil,0,@ InitThread,nil,0,ThreadId);
end;
DLL_PROCESS_DETACH:
begin
end;
end
end;
все это "хардкод", "дурной тон" и "так нельзя" :D
и не забываем все действия десять раз перепроверить в отладчике.
Люди добрые, выручайте! Пытаюсь из engine.dll вызвать UGameEngine::OnNpcHtmlMessage.
void * html_this = NULL; // <<< где взять изначально???
typedef int (__thiscall *_OnNpcHtmlMessage) (void * This, void * user, wchar_t * html, int unk);
_OnNpcHtmlMessage true_OnNpcHtmlMessage;
int __fastcall new_OnNpcHtmlMessage(void * This, unsigned int EDX, void * user, wchar_t * html, int unk)
{
if(html_this == NULL) html_this = This; //Тут выдёргиваю пойнтер при первом вызове диалога сервером
return true_OnNpcHtmlMessage(This, 0, html, 0);
}
void NpcHtmlMessage()
{
wchar_t html[] = L"<html></html>";
if(html_this != NULL) true_OnNpcHtmlMessage(html_this, 0, html, 0);
}
P.S: Если html_this != NULL, то окно можно открыть хоть на экране ввода логина и пароля.
Хукается вроде успешно, НО где достать пойнтер This, чтобы вызывать эту функцию без предварительного получения This?
Добавлено через 7 минут
Да и вообще очень интересует как вызвать (__thiscall)OnNpcHtmlMessage, да или вообще что угодно из engine.dll !!! Дайте пример или пните в каком направлении капать))
This - это указатель в памяти на объект UNetworkHandler, чтобы его получить надо перехватить один из его методов и получить этот адрес.
Например ставим хук на
class UNetworkHandler {};
UNetworkHandler* UNH;
int __fastcall UNetworkHandler_AddNetworkQueue_hook(UNetworkHandl er* This, int /*edx*/, NetworkPacket* packet)
{
if(UNH == 0)
{
UNH = This;
}
....
Но чтобы произошел AddNetworkQueue_hook необходимо отправка хотя бы одного пакета на сервер. Например при вводе пароля.
Botter100
11.01.2016, 12:15
Посоны привет! Я тут это все читаю, чето все всё перехватывают. А я понять не могу - это все делается на клиенте с откусанной темидой и ГГ или прям со всем этим добром? Я просто пытаюсь делать хук и у меня крэшится. Причем крэшится не доходя до моего кода, но и не сразу, а только там где я залез своми грязнуми руками в енжин.длл.
Моя первая цель - вызвать MessageBox при вызове OnNpcHtmlMessage
Вот тут хукаю
bool Entry()
{
HMODULE hEngine = GetModuleHandle(L"Engine.dll");
if (hEngine == INVALID_HANDLE_VALUE)
MessageBox(HWND_DESKTOP, L"Can't get module handle.", L"Error", MB_OK | MB_ICONERROR);
char* addr = (char*)GetProcAddress(hEngine, "?OnNpcHtmlMessage@UGameEngine@@UAEHPAUUser@@PA_WHH @Z");
if (!addr)
MessageBox(HWND_DESKTOP, L"Can't get proc address.", L"Error", MB_OK | MB_ICONERROR);
DWORD protection;
DWORD ff = (DWORD)UGameEngine__OnNpcHtmlMessage;
Log::putstring(L"dump_UGameEngine__OnNpcHtmlMessage.txt", L"UGameEngine__OnNpcHtmlMessage = 0x%0X\n", ff);
Log::putstring(L"dump_UGameEngine__OnNpcHtmlMessage.txt", L"UGameEngine::OnNpcHtmlMessage = 0x%0X\n", (DWORD)addr);
//VirtualProtect(addr, 5, PAGE_EXECUTE_READWRITE, &protection);
*addr = char(0xE9); // op code
memcpy(addr + 1, &ff, 4);
//VirtualProtect(addr, 5, protection, 0);
HANDLE hDumpFile = CreateFile(L"dump.txt", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
DWORD bytesWritten = 0;
WriteFile(hDumpFile, addr, 200, &bytesWritten, NULL);
CloseHandle(hDumpFile);
MessageBox(HWND_DESKTOP, L"I am in...", L"Yop", MB_OK);
return true;
}
тут я просто инжеклю jmp на мою функцию представленую ниже
__declspec(naked) void UGameEngine__OnNpcHtmlMessage()
{
MessageBox(HWND_DESKTOP, L"Called 'UGameEngine__OnNpcHtmlMessage'", L"Yop", MB_OK);
}
Это все делается под геймгуардом и с темидой, не знаю влияет ли это как то. Просто бот л2тавер показывает что это возможно. Подсобите че не так делаю? Спасибо.
__declspec(naked) void UGameEngine__OnNpcHtmlMessage()
Твоя функция подмены должна быть по параметрам и возвращаемому значению идентична оригинальной функции. Вот так этот метод класса выглядит:
int __thiscall UGameEngine::OnNpcHtmlMessage(UGameEngine *this, struct User *, wchar_t *, int)
Botter100
11.01.2016, 13:02
Твоя функция подмены должна быть по параметрам и возвращаемому значению идентична оригинальной функции. Вот так этот метод класса выглядит:
int __thiscall UGameEngine::OnNpcHtmlMessage(UGameEngine *this, struct User *, wchar_t *, int)
Это понятно, если я хочу жить после всего этого. Но щас для меня цель отобразить мессадж бокс и гори оно синим пламенем. Ведь должно же по логике проканать. Мне не надо сохранять стэк и прочее ведь? По сути че происходит - вызывается функция из енжин длл OnNpcHtmlMessage а там вместо ее кода уже мой тупо jmp а по этому жмп тупо call MessageBox.
я не переписываю адрес функции в таблице, я хукаюсь внутрь самой функции и мне в принципе пофигу на параметры.
memcpy(addr + 1, &ff, 4); неверно, так как нужно пересчитать относительное смещение т.е.
вместо &ff UGameEngine__OnNpcHtmlMessage - addr - 5;
с GG не пробовал хукать, возможно он палит, попробуй хукнуть не на первом байте а дальше, глянь что в отладчике переписывается ли джамп
А какие хроники клиента? Если ИЛ то там не получится хукнуть в лоб заменив первые 4 байта функции.
А какие хроники клиента? Если ИЛ то там не получится хукнуть в лоб заменив первые 4 байта функции.
Почему именно первые 4? если в ИЛ то первый байт jmp следующие 4 адрес. В случае ИЛ хукается еще проще просто переписывается адрес 4 байта после джампа т.е. 2-5 байты.
Оно то не сложно но я же не вижу как вы хукаете, и там не просто адрес а смешение.
memcpy(addr + 1, &ff, 4); неверно, так как нужно пересчитать относительное смещение т.е.
вместо &ff UGameEngine__OnNpcHtmlMessage - addr - 5;
вот расчет относительного смещения
========================
в отладчике после jmp виден адрес готового перехода который на самом деле вычесляется
Предположим, что функция A расположена по адресу 0×401000, а функция B – по адресу 0×401800. Далее мы определим требуемое относительное смещение. Разница между адресами данных функций составляет 0×800 байт, и мы хотим перейти из функции A в функцию B, так что нам пока не нужно беспокоиться об отрицательных смещениях.
Дальше следует хитрый момент. Предположим, что мы уже записали нашу инструкцию перехода по адресу 0×401000 (функции A), и что данная инструкция выполняется. CPU при этом сделает следующее: сначала он добавит длину инструкции к Указателю на Инструкцию [3] (или Программному Счетчику). Длина инструкции перехода равна пяти байтам, как мы установили ранее. После этого к Указателю на Инструкцию добавляется относительное смещение. Другими словами, CPU вычисляет новое значение Указателя на Инструкцию следующим образом:
instruction_pointer = instruction_pointer + 5 + relative_offset;
Поэтому для вычисления относительного смещения нам нужно переписать формулу в следующем виде:
relative_offset = function_B - function_A - 5;
Мы вычитаем 5, поскольку это длина инструкции перехода, которую CPU добавляет при запуске данной инструкции, а function_A is вычитается из function_B, так как это относительный переход. Разница между адресами функций равна, как мы помним, 0×800 байтам. (Например, если мы забудем вычесть function_A, то CPU перейдет по адресу 0×401800 + 0×401000 + 5, что, очевидно, нежелательно).
вот кусок кода правда не мой но как пример подойдет :void* Create_Hook(BYTE *src, const BYTE *dst, const int len)
{
BYTE *jmp; DWORD dwback;
DWORD jumpto, newjump;
VirtualProtect(src,len,PAGE_READWRITE,&dwback);
if(src[0] == 0xE9)
{
jmp = (BYTE*)malloc(10);
jumpto = (*(DWORD*)(src+1))+((DWORD)src)+5;
newjump = (jumpto-(DWORD)(jmp+5));
jmp[0] = 0xE9;
*(DWORD*)(jmp+1) = newjump;
jmp += 5;
jmp[0] = 0xE9;
*(DWORD*)(jmp+1) = (DWORD)(src-jmp);
}
else
{
jmp = (BYTE*)malloc(5+len);
memcpy(jmp,src,len);
jmp += len;
jmp[0] = 0xE9;
*(DWORD*)(jmp+1) = (DWORD)(src+len-jmp)-5;
}
src[0] = 0xE9;
*(DWORD*)(src+1) = (DWORD)(dst - src) - 5;
for(int i = 5; i < len; i++)
src[i] = 0x90;
VirtualProtect(src,len,dwback,&dwback);
return (jmp-len);
}
Так у тебя на ИЛ клиенте крашится все таки?
FrankJScott
20.05.2025, 00:59
To the person talking about top ai companies to invest in, ai based stock market prediction, ai to buy and sell stocks, best stock trading bot, ai stocks to invest, ai shares to buy, ai stock futures, stock picking software, artificial intelligence for investment, best apps to predict stocks, I highly recommend this on the main page about AI stock picker analysis advice (https://whatisyoursstory.com/2025/05/14/20-pro-news-tips-to-picking-ai-stock-trading-platform-websites/) or future ai stocks, stock analysis best app, ai stocks in us, best free stock analysis tools, ai stock plays, bot stock trading, chat gpt investment, best ai trading platform, ai app for stock market, ai companies to invest in, together with this top rated AI stock picker analysis blog (https://icing-cupcakes.online/2025/05/15/20-excellent-ideas-to-choosing-ai-stock-picker-platform-websites/) not forgetting sites such as ai system for stock trading, ai chart prediction, ticker ai, chat gpt stock prediction, top ai stocks to buy now, best app to research stocks, best stock information sites, share market ai, stocks chat gpt, best way to analyze stocks, bearing in mind this more about the author for AI stock trading analysis site (https://tweetyskitchen.com/20-recommended-info-to-selecting-ai-stock-trading-platform-websites/) which is also great. Also, have a look at this updated AI stock investing platform url (https://fluidalab.com/20-new-advice-on-selecting-ai-stock-trading-analysis-websites-49273663/) and don't forget bot stock trading, about stock investment, day trading ai software, technical stock, stock market analysis website, stock openai, ai companies stock market, ai stock chart, tools to predict stock market, ai tech stock, and don't forget this high rated AI stock predictions analysis blog (https://lambodvd.com/20-great-tips-on-deciding-on-ai-stock-predictions-analysis-sites/) not to mention best app for analysing stocks, undervalued ai stocks, predict stock price, chat gpt ai stock, stock market research software, click this link about (https://josuepdln89135.blogofoto.com) and don't forget ai software for stock trading, best free stock analysis tools, ai share market, trading market analysis, cheap ai companies to invest in, for good measure. Check more @ Recommended AI Stock Predictions Analysis Tips (https://logikmemorial.ca/forum/index.php?topic=410495.new#new) c9ac285
FrankJScott
27.05.2025, 06:28
In reply to the person asking about situs togel gampang menang, situs slot pragmatic, idn live casino, game slot pragmatik, slot online 4d, cara main slot game, yang kami, situs agen slot terpercaya, judi pulsa, situs judi, I highly suggest this my response for Tajir4D info (https://gunnerhyjm81245.look4blog.com/73394873/30-new-advice-to-picking-tajir4d-websites) or slot tembak ikan, slot bersama, slot login, bo togel dan slot terpercaya, game slot online adalah, game online dari web, situs slot asli, agen slot joker, apa saja game online, permainan slot online yang mudah menang, as well as this such a good point on TAJIR4D Login forum (https://daltonnkev98765.fitnell.com/76045970/30-top-facts-to-picking-tajir4d-sites) alongside all permainan joker slot, menang casino, situs resmi slot online, slot web, slot via pulsa, situs judi casino online, gampang menang slot, agen togel live 4d, slot judi online terpercaya, slot online, and don't forget this useful TAJIR4D Login blog (https://riverwtmd21098.blogerus.com/57315892/30-good-advice-on-deciding-on-tajir4d-login-sites) which is also great. Also, have a look at this her response on TAJIR4D Login info (https://rafaeldpyg18529.bloggadores.com/34401949/30-recommended-reasons-for-selecting-tajir4d-login-websites) on top of game judi slot online, situs akun togel terpercaya, game slot adalah, slot permainan, permainan habanero, bermain slot adalah, daftar joker gaming, situs slot yang aman, judi togel, judi slot gampang menang, not forgetting sites such as this top TAJIR4D Login blog (https://franciscotjvh20863.prublogger.com/34356681/30-top-ideas-for-selecting-tajir4d-websites) not forgetting sites such as bandar togel terbesar terpercaya, bandar togel online terbesar, permainan slot yang mudah menang, situs slot via pulsa, judi slot adalah, my latest blog post about (https://chancevzac23344.loginblogin.com) bearing in mind situs yang mudah menang, resmi slot login, agen toto slot, anda togel, agen toto online, for good measure. Check more @ New AI Stock Investing Platform Website (http://www.b04.abdemo.zzart.me/forum.php?mod=viewthread&tid=3115&pid=6871&page=1&extra=#pid6871) f130c9a
Добавлено через 13 часов 33 минуты
In response to the person inquiring about angka keluar sdy sgp dan hk, keluaran togel singapore live, angka jitu sdy hari ini, daftar keluaran togel hongkong, togel keluaran sgp hari ini, angka keluaran sgp hari ini, data pengeluaran sdy, daftar angka keluar hk, bocoran togel sgp hari ini, keluar angka hk, I highly suggest this find for 7 RAJA TOGEL details (https://tools-directory.com/listings711957/keluaran-sgp-sdy-hk-dan-live-draw-togel-sdy) or keluar angka singapura hari ini, prediksi angka sgp, live result sgp hari ini tercepat dan akurat, angka togel jitu, angka jitu togel singapura hari ini, data pengeluaran sgp, kumpulan situs slot terbaru, angka togel hongkong malam ini, angka pengeluaran singapura hari ini, angka jitu togel hk hari ini, which is worth considering with this updated 7RAJATOGEL info (https://wise-social.com/story5103953/data-lengkap-togel-dan-angka-keluar-singapura-hari-ini) and don't forget prediksi togel sgp, angka keluar sgp 2022, bocoran sgp togel hari ini angka jitu, togel singapore hongkong hari ini keluaran hongkong malam ini, angka sgp yang keluar hari ini, data togel sdy sgp hk, angka angka togel, prediksi angka togel hk, data lengkap togel, data togel sdy, on top of this new 7RAJATOGEL forum (https://john9e14oub7.qodsblog.com/profile) which is also great. Also, have a look at this additional reading about 7 RAJA TOGEL blog (https://your-directory.com/listings13485956/keluar-angka-hk-dan-angka-keluaran-togel-hongkong) not forgetting sites such as angka jitu togel hk hari ini, rekap togel sgp, angka togel hongkong hari ini, live draw sgp hari ini tercepat, pengeluaran togel sidney hari ini, keluaran hk sdy sgp 2022 lengkap hari ini, angka bocoran togel singapura, data nomor togel hongkong, hasil keluaran hk, angka togel singapura hari ini, not forgetting sites such as this more tips here for 7RAJATOGEL advice (http://iawbs.com/home.php?mod=space&uid=900447) and don't forget data keluaran sgp hari ini, angka jitu togel hongkong malam ini, bocoran togel sidney hari ini, prediksi togel sgp, angka togel keluar malam ini, i was reading this for (https://finnwqim65432.webdesign96.com) together with data togel hk, data togel lengkap hari ini, keluaran sgp sdy hk, angka togel hongkong yang keluar hari ini, nomor togel singapura hari ini, for good measure. Check more @ Cool TAJIR4D Guide (https://forum.narutotrad.com/viewtopic.php?p=477908#p477908) 0c5b334
FrankJScott
06.06.2025, 18:52
In response to the man inquiring about stock trading picks, stock ai bot, ai and stocks, free ai stock picker, stock picking advice, investing in a stock, ai in the stock market, ai tools to predict stock market, openai publicly traded, best ai stock trading bot, I highly suggest this get redirected here about AI Stock Predictions Analysis info (https://casinonanets.com/top-10-suggestions-to-determine-the-integration-and-compatibility-of-ai-based-stock-predicting-analyzing-trading-platforms/) or buy chat gpt stock, danelfin reviews, best investments in ai, best application for stock analysis, best ai for stock trading, stock analysis software free, stock market analytics tools, top ai stock picks, stock market and how to invest, automated ai investing, not to mention this a replacement about AI Stock Investing Analysis link (https://prizestashbubble.de/20-top-info-for-choosing-ai-stock-picker-platform-websites/) alongside all stock market investment software, open ai company stock, ai for stock picking, stock market trading software, ai companies invest, companies investing in ai, technical stock, best share trading software, good websites for stock analysis, stock picker app, bearing in mind this website about AI Stock Picker Analysis details (https://bellaglutenfree.us/20-pro-reasons-on-picking-ai-stock-trading-platform-websites/) which is also great. Also, have a look at this best AI Stock Picker Platform forum (https://huuugesocialcasinos.com/20-great-news-on-choosing-ai-stock-investing-analysis-websites/) not to mention about stocks and investing, best stock picker, ai for stock picking, website stock market, ai trading stocks, website that tells you when to buy and sell stocks, stock analysis software, using ai for trading, most promising ai stocks, stock buying software, which is worth considering with this official source on AI Stock Predictions Platform url (https://www.southafricamusic.com/20-pro-tips-on-selecting-ai-stock-trading-platform-websites/) not to mention stock for chat gpt, ai stock ticker, us stock analysis website, ai company share price, ai startup stocks, sell on (https://finniarf10875.blogvivi.com) not forgetting sites such as learn how to analyze stocks, ai gpt stock, best trading ai, stock price ai, about stocks and investing, for good measure. Check more @ New Ad Blocker Site (http://www.881.cz/forum.php?mod=viewthread&tid=1331&extra=) 8670b35
FrankJScott
13.06.2025, 03:10
To the people asking about masuk akun dana, fortune slot online, bank bri website, macam macam judi slot online, judi slot hari ini, bank mandiri online login, rtp pandahoki, logo slot game, download kasino, link main slot online, I highly recommend this great CUAN88 url (https://addurl-directory.com/listings13223440/slot-play-dan-game-of-slot) or panda spin 88 login, cara tf di bank bca, toto casino login, link judi slot gacor, download casino online, website judi gacor, casino provider, cara transfer bank mandiri ke bri, cara transfer dari rekening bri ke bca, rtp hari ini slot, on top of this funny post about 322 Togel tips (https://nathan7y72sjx5.wikicorrespondence.com/user) on top of cara transfer dari bank mandiri ke bni, situs resmi bank bca, ovo slot online, 10 casino, main judi online, menang judi login, cara transfer mandiri ke bank bri, bandar judi slot online terbaik, cara memakai akun dana, saldo link aja, together with this sources tell me about CUAN88 url (https://cypriotdirectory.com/listings13237631/web-judi-online-dan-toto-judi-4d-login) which is also great. Also, have a look at this my sources about DVLTOTO url (https://ryan9y08jvh2.fare-blog.com/profile) not to mention download game judi, cara transfer rekening, rtp slot, aplikasi link, cara transfer e money ke e money, mandiri ke bri, judi toto slot, fortunes slot 88, jackpot judi, cara menghitung 4d singapore, bearing in mind this her response on DVL TOTO blog (https://daniel5o63lhc8.wikigdia.com/user) alongside all free link slot, bank bri ke mandiri, win casino online, jackpot game slot, transfer bank mandiri ke bni, he said for (https://cesarwtit49370.amoblog.com) together with hot slots online, download mega slot, jago login, link game judi slot online, game slot win, for good measure. Check more @ Updated Login Tajir4D Tips (http://www.kaxitixi.com/forum.php?mod=viewthread&tid=56491&pid=435371&page=1&extra=#pid435371) c5b335_
vBulletin® v3.6.11, Copyright ©2000-2025, Jelsoft Enterprises Ltd. Перевод: zCarot