PDA

Просмотр полной версии : [Руоф] Код для инжекта в память.


Страницы : [1] 2

Dinmaite
04.01.2011, 22:11
Подготовленные функции для инжекта в память клиента (руоф)

Адреса Устарели

Большей частью тема скопирована с форума elitepvpers.de ([Ссылки могут видеть только зарегистрированные и активированные пользователи])
Я добавил несколько своих инжектов, а также "тел пакетов", кроме того все инжекты, которые могут быть удобно заменены на инжект отсылки пакетов - не описаны.
Код представлен на Delphi.
Все значения в дампах приведены в шестнадцатиричной кодировке.


type
PParams = ^TParams;
TParams = packed record
Packet: array [0..100] of byte;
Param1,Param2,Param3: DWord;
Param4: array [1..100] of widechar;
end;

const
PW_BASE_ADDRESS = $009C0E6C;
PW_GAMERUN_ADDR = $009C1514;




procedure InjectFunc(ProcessID: Cardinal; Func, aParams: Pointer;
aParamsSize: DWord);
var
hThread: THandle;
lpNumberOfBytes: DWord;
ThreadAddr, ParamAddr: Pointer;
begin
if ProcessID<>0 then
begin
// ---- Выделяем место в памяти процесса, и записываем туда нашу функцию
ThreadAddr := VirtualAllocEx(ProcessID, nil, 256, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(ProcessID, ThreadAddr, Func, 256, lpNumberOfBytes);

// ---- Также запишем параметры к ней
ParamAddr := VirtualAllocEx(ProcessID, nil, aParamsSize, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(ProcessID, ParamAddr, aParams, aParamsSize, lpNumberOfBytes);

// ---- Создаем поток, в котором все это будет выполняться.
hThread := CreateRemoteThread(ProcessID, nil, 0, ThreadAddr, ParamAddr, 0, lpNumberOfBytes);

// ---- Ожидаем завершения функции
WaitForSingleObject(hThread, INFINITE);

// ---- подчищаем за собой
CloseHandle(hThread);
VirtualFreeEx(ProcessID, ParamAddr, 0, MEM_RELEASE);
VirtualFreeEx(ProcessID, ThreadAddr, 0, MEM_RELEASE);
end
end;



Инжект пакетов.


procedure PacketCall(aPParams:PParams); stdcall;
var
CallAddress,pPacket:pointer;
Len:DWord;
begin
CallAddress:=Pointer($0060E310); // Старый адрес - $005D7C30
Len:=aPParams^.Param1;
pPacket:=@aPParams^.Packet;
asm
pushad
mov ecx, dword ptr [PW_BASE_ADDRESS]
mov ecx, dword ptr [ecx+$20]
push Len
push pPacket
call CallAddress
popad
end;
end;

procedure StrToByte(Packet:string; var aParams:TParams);
var
i:integer;
begin
i:=(length(Packet) div 2)-1;
aParams.Param1:=i+1;
for i:=0 to i do
aParams.Packet[i]:=strtoint('$'+bytecode[i*2+1]+bytecode[i*2+2]);
end;

procedure Packet(Packet: string);
var
aParams: TParams
begin
StrToByte(Packet,aParams);
InjectFunc(ProcessID,@PacketCall,@aParams,sizeof(a Params));
end;



Пакеты (© Dinmaite):
Пакеты предоставлены в виде "разделенном на байты" для удобности рассмотрения.
Если вы передаете их в мою функцию, необходимо удалить все пробелы.


Цветом выделены ID состояний.
67 00 00 00 00 00 03 00 00 00 00 00 00 00 - Перевести пета в состояние охраны.
67 00 00 00 00 00 03 00 00 00 01 00 00 00 - Перевести пета в агресивное состояние.
67 00 00 00 00 00 03 00 00 00 02 00 00 00 - Перевести пета в управляемое состояние.

64 00 00 00 00 00 - Вызов пета из первой клетки (пакет вызова из второй и тд. выложу когда сделаю 2 ячейки друле)

65 00 - убрать пета.

Песочный - WID моба.
67 00 00 00 00 80 01 00 00 00 00 - атаковать петом.

Песочный - WID моба. Оранжевый - id скилла.
67 00 9C 49 10 80 04 00 00 00 AF 02 00 00 00 00 - Скилл пета.



Песочный - номер ячейки инвентаря. Оранжевый - id предмета.
28 00 00 01 1F 00 A9 21 00 00 - Использование итема.

Песочный - номер ячейки из которой требуется переместить предмет.
Оранжевый - номер целевой ячейки.
Если в целевой ячейке есть предмет - предметы поменяются местами.
0C 00 01 02 - Перемешение итема в инвентаре.

Песочный - номер ячейки инвентаря, в которой лежит предмет.
Оранжевый - номер целевой ячейки на "кукле".
11 00 01 05 - Одеть предмет.



2E 00 - Сесть в медитацию.
2F 00 - Встать из медитации.
03 00 00 - Нормальная атака.
28 00 01 01 0C 00 30 08 00 00 - взлет и посадка на флайте. Песочный - id флайта.
5A 00 01 00 00 00 - включить ускоренный полет.
5A 00 00 00 00 00 - выключить ускоренный полет
1B 00 E1 0E 56 00 - Пригласить в пати. Песочный - id персонажа.
1E 00 - Выйти из пати. (Спасибо Sirioga за помощь).
30 00 00 00 - Помахать рукой.
30 00 01 00 - Кивать головой.
30 00 02 00 - Качать головой.
30 00 03 00 - Пожать плечами.
30 00 04 00 - Рассмеяться.
30 00 05 00 - Рассердиться.
30 00 06 00 - Упасть.
30 00 07 00 - Грустить.
30 00 08 00 - Воздушный поцелуй.
30 00 09 00 - Стасняться.
30 00 0a 00 - Благодарить.
45 00 0B - Сесть.
30 00 0C 00 - Заоядка.
30 00 0D 00 - Думать.
30 00 0E 00 - Насмехаться.
30 00 0F 00 - Победа.
30 00 10 00 - Потянуться.
30 00 11 00 - Бой.
30 00 12 00 - Атака1.
30 00 13 00 - Атака2.
30 00 14 00 - Атака3.
30 00 15 00 - Атака4.
30 00 16 00 - Защита.
30 00 17 00 - Упасть.
30 00 18 00 - Притворная смерть.
30 00 19 00 - Оглядеться.
30 00 1A 00 - Танец.


04 00 - Респаун в город.
02 00 EC 3D 10 80 - Выделить моба/НПС/Игрока. Песочный - WID моба/НПС или ID игрока.
08 00 - Сбросить таргет.
Песочный - WID НПС.
23 00 D1 3C 10 80 - открыть диалог с NPC.


25 00 07 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 - взять квест, песочный ID квеста
25 00 06 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 - сдать квест, песочный ID квеста; желтый награда, 00 дефолт или нет выбора, дальше по возрастанию.


Инжекты.

Дамп

0044ED5C |. 8B86 F80A0000 MOV EAX,DWORD PTR DS:[ESI+AF8]
0044ED62 |. 50 PUSH EAX
0044ED63 |. E8 487D1A00 CALL elementc.005F6AB0
0044ED68 |. 83C4 04 ADD ESP,4



procedure AssistCall(aPParams:PParams);Stdcall;
var P1:DWORD;
begin
P1:=aPParams^.Param1;
asm
pushad
mov eax, P1
push eax
mov eax, $5F6AB0
call eax
add esp, $4
popad
end;
end;

procedure Assist(PlayerMemberID:dword);
var aParams:TParams;
begin
aParams.Param1:=PlayerMemberID; //ID игрока в пати.
InjectFunc(aHandle,@AssistCall,@aParams,SizeOf(aPa rams));
end;





procedure Mine_Drop(aPParams:PParams); stdcall;
var
addr,addr2:pointer;
x,y:dword;
begin
x:=aPParams^.param1;
y:=aPParams^.param2;
addr := Pointer($00463990);
if y=2 then
asm
pushad
mov ecx, dword ptr[$9C0E6C];
mov ecx, dword ptr[ecx+$1C];
mov ecx, dword ptr[ecx+$20];
push 1
push x
CALL addr
popad
end
else
asm
pushad
mov ecx, dword ptr[$9C0E6C];
mov ecx, dword ptr[ecx+$1C];
mov ecx, dword ptr[ecx+$20];
push 0
push x
CALL addr
popad
end;
end;

Procedure TInjects.AutoDrop_Mining(hProcess,WID,_type:DWord) ;
var
aParams:TParams;
begin
aParams.Param1:=WID;
aParams.Param2:=_type;
InjectFunc(hProcess, @MineDrop, @aParams, sizeof(aParams));
end;





procedure TalkToNPCCall(aPParams:PParams);Stdcall;
var NPCID:DWORD;
BaseAddress,CallAddress:Pointer;
begin
BaseAddress:=ptr(PW_GAMERUN_ADDR-$1C);
NPCID:=aPParams^.Param1;
CallAddress:=ptr($005D1D70);
asm
pushad
mov edx, dword ptr [BaseAddress]
mov ecx, dword ptr [edx+$20]
push NPCID
add ecx, $EC
call CallAddress
popad
end;
end;

procedure TalkToNPC(NPCID:Cardinal);
var aParams:TParams;
begin
aParams.Param1:=NPCID;
InjectFunc(aHandle,@TalkToNPCCall,@aParams,SizeOf( aParams));
end;





procedure WalkCall(aPParams:PParams);Stdcall;
var CallAddress1,CallAddress2,CallAddress3:Pointer;
x,y,z:single;
flying:DWORD;
begin
CallAddress1:=Pointer($00468070);
CallAddress2:=Pointer($0046BCB0);
CallAddress3:=Pointer($00468470);
x:=aPParams^.Param4;
y:=aPParams^.Param5;
z:=aPParams^.Param6;
flying:=aPParams^.Param1;
asm
pushad
mov eax, dword ptr [PW_GAMERUN_ADDR]
mov esi, dword ptr [eax+$20]
mov ecx, dword ptr [esi+$FE0]
push 1
call CallAddress1
mov edi, eax
lea eax, dword ptr [esp+$0C]
push eax
push flying
mov ecx, edi
call CallAddress2
mov ecx, dword ptr [esi+$FE0]
push 0
push 1
push edi
push 1
call CallAddress3
mov eax, dword ptr [PW_GAMERUN_ADDR]
mov eax, dword ptr [eax+$20]
mov eax, dword ptr [eax+$FE0]
mov eax, dword ptr [eax+$30]
mov ecx, dword ptr [eax+$4]
mov eax, x
mov dword ptr[ecx+$20], eax
mov eax, z
mov dword ptr[ecx+$24], eax
mov eax, y
mov dword ptr[ecx+$28], eax
popad
end;
end;

procedure Walk(x,y,z:single);
var aParams: TParams;
begin
ReadProcessMemory(aHandle,ptr(BaseWalkMode),@WalkM ode,1,readwrite); //BaseWalkMode = GA +20 +61C
if WalkMode = 0 then aParams.Param1:=0 else aParams.Param1:=1;
aParams.Param3:=x;
aParams.Param4:=y;
aParams.Param5:=z;
InjectFunc(aHandle,@WalkCall,@aParams,SizeOf(aPara ms));
end;





procedure SkillCall(aPParams:PParams); stdcall;
var CallAddress:pointer;
P1:DWord;
begin
CallAddress:=Pointer($0045DCD0);
P1:=aPParams^.Param1;
asm
pushad
mov ecx, dword ptr [$009C0E6C]
mov ecx, dword ptr [ecx+$1C]
mov ecx, dword ptr [ecx+$20]
push $FFFFFFFF
push $00
push $00
mov edx, P1
push edx
call CallAddress
popad
end;
end;

procedure Skill(SkillID:DWord);
begin
aParam.Param1:=SkillID;
InjectFunc(ProcessID,@SkillCall,@aParam,SizeOf(aPa ram));
end;





procedure UseSkillGenieCall(aPParams:PParams);Stdcall;
var CallAddress: pointer;
SkillNum:DWORD;
begin
CallAddress:=Pointer($004B0CE0);
SkillNum:=aPParams^.Param1; // порядковый номер скилла [0-7]
asm
pushad
mov ecx, dword ptr [PW_GAMERUN_ADDR]
mov ecx, dword ptr [ecx + $20]
mov edi, dword ptr [ecx + $3A8]
push $FFFFFF00
push $00
mov ecx, SkillNum
push ecx
mov ecx, edi
call CallAddress
popad
end;
end;

procedure UseSkillGenie(SkillNum:cardinal);
var aParams:TParams;
begin
aParams.Param1:=SkillNum;
Injectfunc(aHandle,@UseSkillGenieCall,@aParams,Siz eOf(aParams));
end;





procedure BuyCall(buf:Pointer);Stdcall;
var CallAddress:pointer;
begin
CallAddress:=Pointer($005F72C0);
asm
pushad
push buf
push 1
call CallAddress
add esp, $8
popad
end;
end;

procedure Buy(ItemId,ItemCount,CellNum:integer);
var buf:array [0..2] of DWORD;
begin
buf[0]:=ItemId; //Id предмета
buf[1]:=CellNum; //Номер ячейки у продавца
buf[2]:=ItemCount; //Количество покупаемых предметов
InjectFunc(aHandle,@BuyCall,@buf,SizeOf(buf));
end;





procedure SellCall(buf:Pointer);Stdcall;
var CallAddress:pointer;
begin
CallAddress:=Pointer($005F7340);
asm
pushad
push buf
push 1
call CallAddress
add esp, $8
popad
end;
end;

procedure Sell(ItemId,ItemCount,CellNum:integer);
var buf:array [0..2] of DWORD;
begin
buf[0]:=ItemId; // ID предмета
buf[1]:=CellNum; //Номер ячейки инвентаря
buf[2]:=ItemCount; //Количество предметов для продажи.
InjectFunc(aHandle,@SellCall,@buf,SizeOf(buf));
end;





procedure ReparAllCall(aPParams:PParams);Stdcall;
var CallAddress:pointer;
begin
CallAddress:=pointer($005F73C0);
asm
pushad
push $0FFFFFFFF
push 0
push 0
call CallAddress
add esp, $0C
popad
end;
end;

procedure RepairAll;
var aParams:TParams;
begin
InjectFunc(aHandle,@ReparAllCall,@aParams,SizeOf(a Params));
end;





procedure JumpCall(aPParams:PParams);Stdcall;
var CallAddress:pointer;
begin
CallAddress:=pointer($00476970);
asm
pushad
push $0
push $C8
push $1
push $3F800000
push $4
mov ecx, dword ptr [PW_GAMERUN_ADDR]
mov ecx, dword ptr [ecx+$20]
mov eax, $41200000
mov dword ptr[ecx+$B80], $0
mov dword ptr[ecx+$B94], $0
mov dword ptr[ecx+$B98], $0
mov dword ptr[ecx+$B9C], $0
mov dword ptr[ecx+$BA4], eax
mov dword ptr[ecx+$BF4], $1
mov dword ptr[ecx+$BFC], eax
call CallAddress
popad
end;
end;

procedure Jump;
var aParams:TParams;
begin
InjectFunc(aHandle@JumpCall,@aParams,SizeOf(aParam s));
end;





procedure AutoPathCall(aPParams:PParams); stdcall;
var
addr:pointer;
x,y:dword;
begin
x:=aPParams^.param1;
y:=aPParams^.Param2;
z:=aPParams^.Param3;
addr := Pointer($00438770);
asm
pushad
MOV EDI,y
MOV ESI,x
MOV EAX,DWORD PTR DS:[$9C0E6C] // base_addr
PUSH 0 // ; /Arg7 = 00000000
PUSH EDI // ; |Arg6
MOV ECX,DWORD PTR DS:[EAX+$1C] // ; |
PUSH ESI // ; |Arg5
PUSH 0 // ; |Arg4 = 00000000
PUSH 0 // ; |Arg3 = 00000000
PUSH 0 // ; |Arg2 = 00000000
PUSH $14A // ; |Arg1 = 0000014A
call addr // ; \elementc.00438770


MOV EDX,DWORD PTR DS:[$9C0E6C] //; elementc.009C14F8
XOR EAX,EAX
MOV AL,0
PUSH 0 //; /Arg7 = 00000000
MOV ECX,DWORD PTR DS:[EDX+$1C] //; |
MOV EDX,z //; |
PUSH EAX //; |Arg6 = 00000000
PUSH EDX //; |Arg5 = Высота полета
PUSH 1 //; |Arg4 = 00000001
PUSH 0 //; |Arg3 = 00000000
PUSH 0 //; |Arg2 = 00000000
PUSH $14A //; |Arg1 = 0000014A
CALL addr //; \elementc.00438770
popad
end;
end;


procedure AutoPath(realcoord_X,realcoord_Y,realcoord_Z:singl e);
begin
aParams.Param1:=round(realcoord_X);
aParams.Param2:=round(realcoord_Y);
aParams.Param3:=round(realcoord_Z); // высота полета
InjectFunc(aHandle,@AutoPathCall,@aParams,SizeOf(a Params));
end;

Greeeds
04.01.2011, 23:01
Почитал, оч интересно, но возник вопрос про пакеты: они статичны? думаю нет, как тогда их выловить?

Dinmaite
04.01.2011, 23:33
Это "тела" пакетов, инжектим мы их до шифровки.
Они статичны, за исключением секций, которые я выделял цветом, обычно это ID моба или действия.

Greeeds
06.01.2011, 20:47
procedure AssistCall(aPParams:PParams);Stdcall;
var P1:DWORD;
begin
P1:=aPParams^.Param1;
asm
pushad
mov eax, P1
push eax
mov eax, $5F6AB0
call eax
add esp, $4
popad
end;
end;

procedure Assist(PlayerMemberID:dword);
var aParams:TParams;
begin
aParams.Param1:=PlayerMemberID; //ID игрока в пати.
InjectFunc(aHandle,@AssistCall,@aParams,SizeOf(aPa rams));
end;
оч заинтерисовало вот это, как правильно определить ID? или оно по порядку сверху вниз 1,2,3,4... ?

Dinmaite
06.01.2011, 21:21
оч заинтерисовало вот это, как правильно определить ID? или оно по порядку сверху вниз 1,2,3,4... ?

Нет, это ID персонажа, его можно найти в массиве (структуре) членов группы, в соседней теме "Адреса и оффсеты".

Allein
23.01.2011, 14:39
Procedure TInjects.AutoDrop_Mining(hProcess,WID,_type:DWord) ;
WID - как я понимаю это место кирки в инвентаре. Последняя ячейка в нерасширенном инвентаре это 31 или 32?

_type - Совсем не понимаю что это.. Тип ресурса? В каком виде он должен быть?

Вызывал функцию такими способами:

AutoDrop_Mining(hProcess,31,0);
AutoDrop_Mining(hProcess,31,1);
AutoDrop_Mining(hProcess,31,2);
AutoDrop_Mining(hProcess,31,3);
AutoDrop_Mining(hProcess,31,4);
AutoDrop_Mining(hProcess,32,0) и тп.
даже: AutoDrop_Mining(hProcess,31,3075);
Не копает =\ В чём может быть проблема?

semoder
23.01.2011, 14:58
WID-это уникальный ид ресурса/Моба/NPC на карте, но не место кирки, ни в коем случае =)

Allein
23.01.2011, 15:26
WID-это уникальный ид ресурса/Моба/NPC на карте, но не место кирки, ни в коем случае =)

Хорошо. А как узнать этот уникальный ID? И что такое _type(по сути либо 2 либо не 2 :forward:)?

И очень интересен принцип работы PWAuto в этом плане, он же собирает ближайший ресурс. Как он узнаёт ID ближайшего ресурса? Или сканирует карту на ID? :sceptic:

Совсем запутался хD

semoder
23.01.2011, 15:59
Сканирует карту, отбрасывает дальние ресурсы, оставляя только самый ближайший

Структура / Список лута:
GA +8 +28 +18 +[I*4] + (+0)^J +4: (I in [0..300])

GA +8 +28 +14: - Items count
+3C ItemLocX (float)
+40 ItemLocZ (float)
+44 ItemLocY (float)
+10C ItemWID (Sn - Serial Number)
+110 ItemID
+14C ItemType (1 - Money; 2 - Mine; Other - Item)
+164 +0 ItemName (UText / Unicode String)
+154 Дистанция

Allein
23.01.2011, 16:02
semoder, спасибо, не совсем тривиальная задачка (по крайней мере для меня), сейчас покопаюсь

Njkzy80
31.01.2011, 18:58
Уважаемый Dinmaite прошу вас помогите найти ошибку.
Я перепробовал все инжекты но почемуто работает только джамп, остальные выбивают клиент. Вот мой код
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;



type
PParams = ^TParams;
TParams = packed record
Param1: DWORD;
Param2: DWORD;
Param3: single;
Param4: single;
Param5: single;
Param6: byte;
end;

type
TForm1 = class(TForm)
btnAttach: TButton;
btnToggleFly: TButton;
mInfo: TMemo;
btnTownPortal: TButton;
procedure btnAttachClick(Sender: TObject);
procedure btnTownPortalClick(Sender: TObject);
procedure btnToggleFlyClick(Sender: TObject);
private
public
end;

var
Form1: TForm1;
hWindow: HWND;
gamePID, hProcess: cardinal;

implementation

{$R *.dfm}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
//~~~ Инжектор
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
procedure InjectFunc(hProcess: Cardinal; Func: Pointer; aParams: Pointer; aParamsSize: DWORD);
var
hThread: THandle;
lpNumberOfBytes: DWORD;
ThreadAddr, ParamAddr: Pointer;
begin
if hProcess<>0 then
begin
// ---- Выделим место в памяти процесса и запишем туда нашу функцию
ThreadAddr := VirtualAllocEx(hProcess, nil, 256, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, ThreadAddr, Func, 256, lpNumberOfBytes);
// ---- Также запишем параметры к ней
ParamAddr := VirtualAllocEx(hProcess, nil, aParamsSize, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, ParamAddr, aParams, aParamsSize, lpNumberOfBytes);
// ---- Создадим поток, в котором это всё будет выполняться
hThread := CreateRemoteThread(hProcess, nil, 0, ThreadAddr, ParamAddr, 0, lpNumberOfBytes);
// ---- Ожидаем, пока функция отработает
WaitForSingleObject(hThread, INFINITE);
// ---- Подчищаем за собой
CloseHandle(hThread);
VirtualFreeEx(hProcess, ParamAddr, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, ThreadAddr, 0, MEM_RELEASE);
end
end;


procedure TForm1.btnAttachClick(Sender: TObject);
begin
hWindow := FindWindow('ElementClient Window',nil);
if hWindow <> 0 then begin
GetWindowThreadProcessId(hWindow, @gamePID);
hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, gamePID);
mInfo.Lines.Add('Нашёл клиента PW. PID='+IntToStr(gamePID)+' hProcess='+IntToStr(hProcess));
btnTownPortal.Enabled := true;
btnToggleFly.Enabled := true;
end else begin
mInfo.Lines.Add('Клиент PW не найден');
end;
end;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
// Команда использования скилла
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
procedure UseSkillCall(aPParams:PParams); Stdcall;
var
Address: pointer;
begin
Address := Pointer($004B0CE0);
asm
pushad
mov ecx, dword ptr [$009C1514]
mov ecx, dword ptr [ecx + $20]
mov ecx, dword ptr [ecx + $3A8]
push $FFFFFF00
push $00
mov ecx, [$1]
push ecx
mov ecx, edi
call Address
popad
end;
end;
procedure TForm1.btnTownPortalClick(Sender: TObject);
var
aParams : TParams;
begin
InjectFunc(hProcess, @UseSkillCall, @aParams, SizeOf(aParams));
end;

procedure JumpCall(aPParams:PParams);Stdcall;
var CallAddress:pointer;
begin
CallAddress:=pointer($00476970);
asm
pushad
push $0
push $C8
push $1
push $3F800000
push $4
mov ecx, dword ptr [$009C1514]
mov ecx, dword ptr [ecx+$20]
mov eax, $41200000
mov dword ptr[ecx+$B80], $0
mov dword ptr[ecx+$B94], $0
mov dword ptr[ecx+$B98], $0
mov dword ptr[ecx+$B9C], $0
mov dword ptr[ecx+$BA4], eax
mov dword ptr[ecx+$BF4], $1
mov dword ptr[ecx+$BFC], eax
call CallAddress
popad
end;
end;

procedure TForm1.btnToggleFlyClick(Sender: TObject);
var aParams:TParams;
begin
InjectFunc(hProcess,@JumpCall,@aParams,SizeOf(aPar ams));
end;

end.
Помогите разобраться

Добавлено через 2 минуты
Почему-то инжект на использование скила 1 выбивает клиент, и я немогу понять почему.

Dinmaite
31.01.2011, 19:14
Я вроде отвечал на ПВлабе

BotDruLife
12.02.2011, 12:46
Инжектим-инжектим....
А вот вопрос, а вдруг в игре есть защита от инжекта? То что она не срабатывает, это не значит что ее нет или она "не видит"...

Kitsune
12.02.2011, 13:05
BotDruLife, не городите ерунды.

j091
17.02.2011, 16:59
Уважаемый Dinmaite, подскажите, как реализовать функцию запроса на аукцион?

Заранее благодарен.

BotDruLife
26.02.2011, 18:33
Не пашет что-то инжект Walk Injection (© AlexGD, muzhig; Addresses by asdxz).

Правильно ходит только в координаты (+-1; +-1; +-1). Если задать точку, например (100, 200, 300), то либо идет в точку (0, 0, 0), либо далеко по одному направлению...

У кого-нибудь он работает нормально?

Dinmaite
26.02.2011, 19:47
Координаты надо указывать в том виде, в котором они хранятся в памяти клиента.

BotDruLife
06.03.2011, 22:03
Бывалые люди, посоветуйте как лучше... Если одно и то же можно сделать через пакеты и через вызовы функций - какой способ выбирать?

Путь через пакеты мне представляется намного проще... Все завязано на вызове одной функции, которая вызывается из 171 места (интерес, наверное, представляют только 30-40 мест...). Легко отследить содержимое, размер и назначение полей пакета. Но не ждет ли в конце, по закону подлости, какая-нибудь расплата за простоту?

Dinmaite[Work]
07.03.2011, 18:17
Не ждет нас никакой расплаты, но некоторые действия удобнее совершать инжектами действий, а не пакетов.
Я большую часть функций завязываю на пакетах, так удобнее, вместо десятка различных кодов достаточно держать всего несколько байтовых массивов.
Да и при "перепрошивке" под другой клиент куда меньше проблем, так как нужно исать меньшее количество адресов, а это зачастую забирает много времени.

pwgamer
16.04.2011, 23:30
CallAddress1:=Pointer($00468070);
CallAddress2:=Pointer($0046BCB0);
CallAddress3:=Pointer($00468470);

Кто подскажет что это за адреса, используются для полета. Не могу новые теперь найти, так как не пойму что искать

zaparca
18.04.2011, 14:33
движение:
WALK_CALL1 =$00469F00; // 00468070
WALK_CALL2 =$0046E090; // 0046BCB0
WALK_CALL3 =$0046A340; // 00468470


Откуда pwlab.ru ([Ссылки могут видеть только зарегистрированные и активированные пользователи])

pwgamer
18.04.2011, 20:20
zaparca, Класс, большее спасибо.

Sanych89
26.04.2011, 10:53
пытаюсь разобраться с инжектором пакетов, а именно с тем, как искать, какой пакет нужно посылать при совершении того или иного действия. пытался при помощи CE смотреть, что стучится на адрес $60E310, но результата это не возымело. в какую сторону гуглить?)

Sirioga
26.04.2011, 15:41
пытаюсь разобраться с инжектором пакетов, а именно с тем, как искать, какой пакет нужно посылать при совершении того или иного действия.
Dinmaite в этой теме ([Ссылки могут видеть только зарегистрированные и активированные пользователи]) упоминает об этом, ознакомься)

gurin
07.05.2011, 02:29
Никто не знает нового адреса для инжекта сбора лута? Раньше он был picklut_inject_addr = 00463990

zaparca
08.05.2011, 14:31
продажа/покупка:
SELL_ITEM_CALL = $006316D0;//005F7340
BAY_ITEM_CALL = $00631650;//005F72C0
использование скилов:
MAGIC_CALL = $0045F550;//0045DCD0
сбор лута и ресурсов:
PICK_ITEM_CALL = $004656F0;//00463990<=


Откуда pwlab.ru ([Ссылки могут видеть только зарегистрированные и активированные пользователи]) :wtf:

krysun
09.05.2011, 05:08
delete

Python
09.05.2011, 10:17
Медитация тут: 0044FE20

Lexxy85
10.05.2011, 01:56
...И все-таки кому не лень подскажите с инжектом пакета на "хождение". В каком виде посылаются координаты?? порыл пвлаб, да и другие источники - не попалось чего-то конкретного примера. Видел формулы: X = (400+X/10); Y = (550+Y/10); Z = (Z/10). По всякому пробовал - убегаю далеко-далеко не по адресу.. Как же правильно передать данные этой функции, зная только необходимые игровые координаты???

Python
10.05.2011, 02:46
X1 = (400+X2/10)

Х1 - координаты удобные для чтения человеку
Х2 - координаты с которыми работает клиент.

Логично, что и передавать ему нужно координаты с которыми он работает - Х2.

texnicoffe
08.07.2011, 11:50
А как узнать код кнопки приглашения в клан ?

Player_First_L3
31.07.2011, 20:38
Каким образом можно найти данный адрес для клиента фришки?
CallAddress:=Pointer($005D7C30);

Dinmaite[Work]
01.08.2011, 10:59
Каким образом можно найти данный адрес для клиента фришки?
CallAddress:=Pointer($005D7C30);

В этом же разделе, тема от моего основного акка (Dinmaite): Ищем базовый адрес Perfect World при помощи Cheat Engine ([Ссылки могут видеть только зарегистрированные и активированные пользователи]).
CallAddres там назван BaseAddres.

Player_First_L3
01.08.2011, 14:37
Спасибо, что откликнулись, Dinmaite!

;1562701']
CallAddres там назван BaseAddres.

Базовый адрес успешно найден (00926FD4), по цепочке [[[[00926FD4]+$1c]+$20]+1104] успешно читается ХП, но инжекты не работают..
Если обратиться к коду на первой странице, то там используется два адреса: const PW_BASE_ADDRESS = $009C0E6C; и CallAddress:=Pointer($005D7C30); это два разных адреса, и если CallAddress принять 00926FD4, то как найти PW_BASE_ADDRESS?

Dinmaite[Work]
01.08.2011, 14:43
CallAddress принять 00926FD4, то как найти PW_BASE_ADDRESS?
Дело в том, что тот адрес, который Вы называете CallAddress на самом деле является базовым адресом (Base Addres, тоесть так как указано в моей теме).
А тот адрес, который Вы называете PW_BASE_ADDRESS на самом деле адрес структуры данных о игре (во многих источниках GA - GameAddres). В моей теме, указанной мною выше этот адрес назван BP - BasePointer.
Мне больше нравится такое название, поскольку адрес может являться указателем на многие структуры данных.

PS Если Вы используете инжекты приведенные в одной из тем данного раздела - то они и не будут работать. Все адреса в них даны под предидущую версию клиента.

Player_First_L3
01.08.2011, 15:42
Вот теперь с адресами понятно в том коде, получается базовый адрес BA "CallAddress:=Pointer($00926FD4)", BP, называемый "PW_BASE_ADDRESS= 0092764C" ([Base+$1C], его также находит ntkid-mhs-retriever.

;1563741'] PS Если Вы используете инжекты приведенные в одной из тем данного раздела - то они и не будут работать. Все адреса в них даны под предидущую версию клиента.

Я использую только инжектор пакетов, там всего 4 функции - InjectFunc, PacketCall, StrToByte и Packet, и в них используются только эти два адреса, разве там нужно поменять что-то ещё?

Dinmaite[Work]
01.08.2011, 15:56
Да, в процедуре PacketCall указан адрес для инжекта, его и нужно поменять.

Player_First_L3
01.08.2011, 17:02
А я уж было подумал, что накосячил где-то :sceptic:

Наверное, вы имели в виду строчку, где задаётся смещение -
mov ecx, dword ptr [ecx+$20] ?
Сразу возникает вопрос, как это смещение найти )

Dinmaite
01.08.2011, 18:53
Дело не в смещении, а в красном адресе.
procedure PacketCall(aPParams:PParams); stdcall;
var
CallAddress,pPacket:pointer;
Len:DWord;
begin
CallAddress:=Pointer($005D7C30);
Len:=aPParams^.Param1;
pPacket:=@aPParams^.Packet;
asm
pushad
mov ecx, dword ptr [PW_BASE_ADDRESS]
mov ecx, dword ptr [ecx+$20]
push Len
push pPacket
call CallAddress
popad
end;
end;

Player_First_L3
01.08.2011, 19:01
Дело не в смещении, а в красном адресе.


Так я про этот адрес и спрашивал изначально (решил указать только одну строчку из кода с первого сообщения, чтобы не перегружать пост)
Это и есть базовый адрес?

Dinmaite
01.08.2011, 19:22
Нет, это адрес функции, которую мы вызываем со своими параметрами.

Player_First_L3
01.08.2011, 19:30
Его я и ищу, и по поводу него изначально был вопрос.
Каким образом этот адрес проще всего найти?

Dinmaite
01.08.2011, 19:52
А блин :) Прости я сам себя запутал.
Забудь все о чем я говорил :)

Этот адрес ищется способом аналогичным описанному в статье "Поиск инжектов" или "Наш код в чужом процессе" ([Ссылки могут видеть только зарегистрированные и активированные пользователи])
Я искал его покупая что-то из шопа (по моему так удобнее всего).
Но можно найти пройдя чуть дальше по вызовам функций от любого (почти) действия. К примеру от стандартной атаки тоже с успехом ищется.

Главное помнить о том, что для того чтобы найти этот адрес надо пройти вперед по вызовам функций.
Вообще если тебе срочно могу просто его дать :)

Обновленный адрес в первом посте.

Player_First_L3
02.08.2011, 00:09
Спасибо, что обновил адрес в первом посте, но я давно уже не играю на руофе, а адрес ищу для фришки :forward:

Главное помнить о том, что для того чтобы найти этот адрес надо пройти вперед по вызовам функций.

Похоже, я неправильно понял, что значит "пройти вперёд по вызовам функций". Я в СЕ ввожу базовый, жму "кто получает доступ к адресу", бегаю, затем покупаю вещи в шопе - нашёл 3 адреса, которые обращаются к базовому при каждой покупке из шопа; далее на каждом адресе "показать в дизассемблере", и чуть ниже в коде для трёх адресов - call по статическому адресу, для одного - по динамическому; далее загружаю процесс в OllyDbg, на каждом из статических адресов перехода, в свою очередь, выписываю переходы по статическим адресам, но ни с одним из статических адресов инжект не работает...

Dinmaite[Work]
02.08.2011, 09:26
Это вполне вероятно. Для поиска инжектов сложно дать конкретный алгоритм.
Там многое зависит от "наработанной интуиции", тоесть привычки к коду клиента.

Под "пройти вперед по вызовам функций" понимается следующее.
Ты нашел эти 3 вероятных адреса. Далее переходишь вперед по Call'ам и смотришь нет ли функции, в которую передаются 2 параметра, адрес пакета и длина пакета.

jekans
19.09.2011, 10:07
1B 00 E1 0E 56 00 - Пригласить в пати. Песочный - id персонажа.
1E 00 - Выйти из пати. (Спасибо Sirioga за помощь).

Ммм а принять приглашение пати не подскажите кодик случайно =)))) позязя:forward:

Player_First_L3
30.09.2011, 19:22
принять приглашение в пати:
1C00 XXXXXXXX YYYYYYYY
где XX - ID персонажа, c которого посылается приглашение в пати (4 байта)
YY - счётчик приглашений в пати (4 байта)
взято из темы "Sending Packets" на elitepvpers.com

Добавлено через 3 минуты
В свою очередь, спрошу, находил ли кто пакеты: на вытягивание из шопа (был раньше на пвлабе) и пакет на телепорт руной переноса?

dark_avenger
30.09.2011, 22:37
YY - счётчик приглашений в пати (4 байта)
уж больно этот счетчик на TimeStamp смахивает ))

руна-юз итем 0x6D
пример для руны:
00 01 33 00 0F 38 00 00 DB 0E 00 00
00 01 - ункноун (предполагаю что количество, или флаг использования, пока не разбирал)
3300 - слот
0F 38 00 00 - id руны
DB 0E 00 00 - место назначения

Player_First_L3
02.10.2011, 21:12
Значит, это и есть TimeStamp - инфу я взял с форума elitepvpers, сам не разбирался )
А пакет для руны для какого сервера приведён? Пробовал на extremepw - не работает, и смущает то, что для слота инвентаря отводится два байта (обычно один байт).

И, пакет на крафт итема и на отправку по почте не знаешь случаем?

N00bSa1b0t
14.10.2011, 12:51
пакет на крафт итема
Крафтил яшмы и янтарку 4 уровня у алхимика на згд, вот что вышло:

25 00 0C 00 00 00 0C 00 00 00 00 00 00 00 9F 02 00 00 01 00 00 00
25 00 0C 00 00 00 0C 00 00 00 00 00 00 00 A6 02 00 00 02 00 00 00
25 00 0C 00 00 00 0C 00 00 00 00 00 00 00 94 02 00 00 01 00 00 00

Красный цвет - номер рецепта (например [Ссылки могут видеть только зарегистрированные и активированные пользователи] , 671 = 0x029F), по которому крафтится нужная вещь
Желтый цвет - количество вещей.

Возможно у других нпц, а не у алхимика на згд начальная часть пакета будет другая, не проверял.

Sirioga
16.10.2011, 09:37
Что-то мне не понятно, как массив Packet (см type), вот так вот просто берётся и push pPacket? Делфя что ли возвращает значение каждой "забитой" части массива? Если нет и я вообще не в те дебри полез, то что вообще происходит с этим массивом от начала до конца? Да понимаю, весьма странный вопрос, но я реально никак понять не могу, что и куда там "пушает".

BritishColonist
16.10.2011, 21:18
присоединяюсь к вопросу. неужто пакет это просто строка?
в смысле, передаётся в виде строки что ли?

Sirioga
16.10.2011, 23:50
присоединяюсь к вопросу. неужто пакет это просто строка?
в смысле, передаётся в виде строки что ли?
Если имелся ввиду тип данных String то нет :D
А вообще вот, что мне Dinmaite в асе ответил по этому поводу.



ЧИТАТЬ СНИЗУ ВВЕРХ

Dinmaite (16.10.2011 11:50)
а дальше с ним разбирается сам клиент

Dinmaite (16.10.2011 11:50)
ты передаешь байтики пакета в виде массива в память клиента, находишь указатель на массив и передаешь его в вызов функции

Sirioga (16.10.2011 11:49)
массив, массив, что с ним происходит?

Dinmaite (16.10.2011 11:49)
сами по себе пакеты не хранятся в клиенте

Dinmaite (16.10.2011 11:49)
потому что тебе пакет нужно передавать в память клиента

Sirioga (16.10.2011 11:48)
тогда для чего выложены тобой пакеты а не адреса на них?)

Dinmaite (16.10.2011 11:48)
не можно, а нужно)

Sirioga (16.10.2011 11:48)
ну можно и так

Dinmaite (16.10.2011 11:48)
ну смотри, тебе ведь сам пакет нужен в теле клиента ПВ?

Sirioga (16.10.2011 11:47)
да я хрен проссу, зачем нужен массив

Dinmaite (16.10.2011 11:47)
что там у тебя с пакетом?

N00bSa1b0t
17.10.2011, 00:54
присоединяюсь к вопросу. неужто пакет это просто строка?
в смысле, передаётся в виде строки что ли?
Набор (массив) байт.

Хотя, любое значение в компьютере можно представить в виде наборе байт /problem

pw.lancer
18.10.2011, 02:24
принять приглашение в пати:
1C00 XXXXXXXX YYYYYYYY
где XX - ID персонажа, c которого посылается приглашение в пати (4 байта)
YY - счётчик приглашений в пати (4 байта)
взято из темы "Sending Packets" на elitepvpers.com


Вот по поводу счетчика приглашений, пока не совсем понятно, откуда его прочитать. Как я понимаю, в момент приграшения он хранится где-то в памяти клиента, но не могу найти адреса.
Уважаемые ботоводы, если кто-то уже решал эту проблему - подскажите, пожалуйста. На elitepvpers.com нашел следующие рекомендации:

// The following regular expression should get you the base address for the partyInvCounter
$search = StringRegExp($data,
'8B87(.{8})' & _ ;//mov eax, dword_A62C28[edi]
'8B.{6}' & _ ;//mov ecx, [esp+60h+var_40]
'03C6' & _ ;//add eax, esi
'8B50.{2}' & _ ;//mov edx, [eax+0Ch]
'2BCA' & _ ;//sub ecx, edx
'8B50.{2}' & _ ;//mov edx, [eax+8]
'3BCA',2) ;//call dword ptr [edx+1Ch]
ConsoleWrite('invCounterBase=0x'&hex(dec(rev($search[1]))+0x20)&@CRLF)
// The value you are looking for in the accept party invite is then:
$partyInviteCounter = readMemory(invCounterBase+0x14)

Однако, для меня поиск оффсетов через регулярные выражения - пока филькина грамота.. Прошу хотя бы подтолкнуть в нужном направлении.

Нашел информацию про оффсет счетчика, если кому-то понадобится: [Ссылки могут видеть только зарегистрированные и активированные пользователи]

Правда, про поиск оффсетов через регэкспы так и не вижу за деревьями леса.. :)

loa
21.10.2011, 07:48
Walk inject для генезиса:

procedure WalkCall(aPParams:PParams1);Stdcall;
var CallAddress1,CallAddress2,CallAddress3:Pointer;
x,y,z:single;
flying:DWORD;
begin
CallAddress1:=Pointer($0046E410);
CallAddress2:=Pointer($004728E0);
CallAddress3:=Pointer($0046E880);
x:=aPParams^.Param4;
y:=aPParams^.Param5;
z:=aPParams^.Param6;
flying:=aPParams^.Param1;
asm
pushad
mov eax, dword ptr [PW_GAME_ADDR]
mov esi, dword ptr [eax+$34]
mov ecx, dword ptr [esi+$1050]
push 1
call CallAddress1
mov edi, eax
lea eax, dword ptr [esp+$18]
push eax
push flying
mov ecx, edi
call CallAddress2
mov ecx, dword ptr [esi+$1050]
push 0
push 1
push edi
push 1
call CallAddress3
mov eax, dword ptr [PW_GAME_ADDR]
mov eax, dword ptr [eax+$34]
mov eax, dword ptr [eax+$1050]
mov eax, dword ptr [eax+$30]
mov ecx, dword ptr [eax+$4]
mov eax, x
mov dword ptr[ecx+$20], eax
mov eax, z
mov dword ptr[ecx+$24], eax
mov eax, y
mov dword ptr[ecx+$28], eax
popad
end;
end;

Allein
22.10.2011, 05:59
PickWalk inject новый исправленный:
// ================================================== =========
// Движение к луту + сбор лута (PickWalk): © gen-ostr
// ================================================== =========
procedure PickWalkCall(aPParams: PParams); Stdcall;
var
WID, Typ: DWord;
CallAddress: DWord;
begin
CallAddress := $00469B40; //sumikot Cтарый:$004656F0
WID := aPParams^.Param1;
Typ := aPParams^.Param2;
asm
pushad
mov ecx, dword ptr [PW_GAMERUN_ADDR]
mov ecx, dword ptr [ecx+$34] //старый 20
push Typ // 0 - Сбор лута, 1 - Сбор шахт
push WID // SN ресурса
call CallAddress
popad
end;
end;
// --------
procedure PickWalk(WID, Typ: DWord);
var
aParams: TParams;
begin
aParams.Param1 := WID;
aParams.Param2 := Typ;
InjectFunc(hProcess, @PickWalkCall, @aParams, sizeof(aParams));
end;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~

Не могу найти новый адрес в замен выделенному красному :sad:

Upd: Исправил всё, теперь работает.

_DVD_
24.10.2011, 13:40
Подскажите пожалуйста новый инжект на выбор таргета по ID.

AlexM81
26.10.2011, 10:43
Подскажите пожалуйста новый инжект на выбор таргета по ID.
procedure TargetCall(aPParams:PParams);Stdcall;
var MobWID: DWORD;
begin
MobWID := aPParams^.Param1;
asm
pushad
mov ecx, dword ptr [$00B27A04]
mov ecx, dword ptr [ecx+$20]
add ecx, $EC
mov edx, MobWID
push edx
mov eax, $006686E0
call eax
popad
end;
end;

HellD
27.10.2011, 01:23
// Движение к луту + сбор лута (PickWalk): © gen-ostr

CallAddress := $004656F0; //sumikot Cтарый:$004656F0

ошибочка вродь как.... если не ошибаюсь, 00469B40... эх... раз 10 клиент вылетел, пока понял ))

Allein
27.10.2011, 03:30
HellD, угу, опечаточка :D
Исправил

Sanych89
30.10.2011, 23:20
то ли лыжи не едут, то ли со мной что-то не так.


PParams = ^TParams;
TParams = packed record
Packet: array [0..100] of byte;
Param1,Param2,Param3: DWord;
Param4: array [1..100] of widechar;
Param5: word;
end;
Base_Addr = $B27A04;
host_player = $34;

procedure InjectFunc(WH: THandle; Func: Pointer; aParams: Pointer; aParamsSize: DWORD);
var
hThread: THandle;
lpNumberOfBytes: DWORD;
ThreadAddr, ParamAddr: Pointer;
hProcess, PID : dword;
begin
if WH<>0 then
begin
GetWindowThreadProcessId(WH, @PID);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, PID);
ThreadAddr:=VirtualAllocEx(hProcess,nil,256,MEM_CO MMIT,PAGE_READWRITE);
WriteProcessMemory(hProcess, ThreadAddr, Func, 256, lpNumberOfBytes);
ParamAddr := VirtualAllocEx(hProcess, 0, aParamsSize, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, ParamAddr, aParams, aParamsSize, lpNumberOfBytes);
hThread := CreateRemoteThread(hProcess, 0, 0, ThreadAddr, ParamAddr, 0, lpNumberOfBytes);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
end;
end;

procedure PacketCall(aPParams:PParams); stdcall;
var
CallAddress,pPacket:pointer;
Len:DWord;
begin
CallAddress:=Pointer($006737B0);
Len:=aPParams^.Param1;
pPacket:=@aPParams^.Packet;
asm
pushad
mov ecx, dword ptr [base_addr]
mov ecx, dword ptr [ecx+host_player]
push Len
push pPacket
call CallAddress
popad
end;
end;
procedure StrToByte(bytecode:string; var aParams:TParams);
var
i:integer;
begin
i:=(length(bytecode) div 2)-1;
aParams.Param1:=i+1;
for i:=0 to i do
aParams.Packet[i]:=strtoint('$'+bytecode[i*2+1]+bytecode[i*2+2]);
end;

procedure Packet(Packet: string;wh:THandle);
var
aParams: TParams;
begin
StrToByte(Packet,aParams);
InjectFunc(wh,@PacketCall,@aParams,sizeof(aParams) );
end;


в общем, копипаста из начала топика. пакеты, вроде, отправляются. клиент не валится с ошибкой.
и даже PacketListener думает, что я их посылаю. но эффекта (в конкретном случае - поедания банки) не наблюдается.
где я удак?)

Krio K.Th
31.10.2011, 18:35
mov ecx, dword ptr [base_addr]
mov ecx, dword ptr [ecx+$20] <-- вот так, а не $34

AEBus
31.10.2011, 19:14
Krio K.Th, к твоему сведению уже $34 хост плеер структ а не $20

Sanych89
31.10.2011, 23:32
нет, там к host_player не имеет отношения. спасибо)

imeninnik
04.11.2011, 20:37
подскажите на какой изменился адрес инжекта SkillCall
procedure SkillCall(aPParams:PParams); stdcall;
var CallAddress: pointer;
P1: DWord;
begin
CallAddress:=Pointer($00463630);
P1: =aPParams^.Param1;
asm
pushad
mov ecx, dword ptr [PW_BASE_ADDRESS]
mov ecx, dword ptr [ecx+$1C]
mov ecx, dword ptr [ecx+ $34 ]
push $FFFFFFFF
push $00
push $00
mov edx, P1
push edx
call CallAddress
popad
end;
end;
спс нашел в соседней теме [Ссылки могут видеть только зарегистрированные и активированные пользователи] , но не успел проверить =) ну и спс VeTaL_UA за оперативный ответ. отметил сразу зеленым что изменилось

VeTaL_UA
04.11.2011, 20:46
подскажите на какой изменился адрес инжекта SkillCall
$00463630

sin(alpha)
06.11.2011, 04:14
Люди будте добры, дайте подсказку. Пытаюсь подружить с инжектами C# столкнулся с одной проблемой - язык плохо понимает ссылки на функции, или я не понимаю как передать в качестве параметра ссылку на функцию в инжектор. Пытался передать через dll выдает ошибки записи в память. С помощью IDA извлек тело функции в виде опкодов оформил как массив байт, что-то запускается и клиент ПВ падает со светофором.
В то же время пакетная передача работает нормально, но пакетами не реализовать алгоритм "поди сюда".

VeTaL_UA
06.11.2011, 09:39
но пакетами не реализовать алгоритм "поди сюда".
Кто тебе это сказал?

sin(alpha)
06.11.2011, 11:41
Прослушка пакетов сказала. Поскольку при повторной пересылке пакета пришедшего на действие "иду вперед" никаких действий персонаж не совершает, то предполагаю любым видом перемещений заведует клиент, и серверу отсылается только информативный пакет типо "персонаж двигался и теперь находится тут". Или у тебя есть инфа как выглядит пакет "идти в (X, Y, Z)" за одно может еще и подскажешь "следовать за кем-либо" на это действие вообще никакого отклика от прослушки не поступает, приходят только стандартные пакеты информации о местоположении если оно менялось.

trixicus
06.11.2011, 12:21
персонаж двигался и теперь находится тут

Так это можно хороший телепорт написать =) Нажал, и ты уже "тут".
PS: Пакет на перемещение посмотри внимательней

sin(alpha)
06.11.2011, 14:24
07 00 C2 3A 1B C5 F1 48 07 43 00 36 39 C5 7B 04 21 21 32 00 E5 00

Коричневый желтый оранжевый - X Z Y координаты конечной точки
07 00 - опкод
а белым не понятно что, может вектор ориентации персонажа ну типо данные о повороте модели
и этот пакет единственный появляющийся при перемещении в конце перемещения.

при дальних переходах еще добавляются промежуточные данные ХЗ может сигнализируют о проходе по координатам сетки:
00 00 44 16 1B C5 64 74 07 43 D1 47 39 C5 44 16 1B C5 64 74 07 43 D1 47 39 C5 14 02 C8 04 21 33 00

но вот пакета отвечающего за начало движения не нахожу.

Если вы знаете будьте добры уж подскажите пакеты на движение по координатам и следования за другим игроком.

imeninnik
13.11.2011, 09:52
07 00 C2 3A 1B C5 F1 48 07 43 00 36 39 C5 7B 04 21 21 32 00 E5 00

Коричневый желтый оранжевый - X Z Y координаты конечной точки
07 00 - опкод
а белым не понятно что, может вектор ориентации персонажа ну типо данные о повороте модели
и этот пакет единственный появляющийся при перемещении в конце перемещения.

при дальних переходах еще добавляются промежуточные данные ХЗ может сигнализируют о проходе по координатам сетки:
00 00 44 16 1B C5 64 74 07 43 D1 47 39 C5 44 16 1B C5 64 74 07 43 D1 47 39 C5 14 02 C8 04 21 33 00

но вот пакета отвечающего за начало движения не нахожу.

Если вы знаете будьте добры уж подскажите пакеты на движение по координатам и следования за другим игроком.
как было замечено в других темах много чего можно узнать из кода FlyWQ.
Исходники FlyWQ выложены автором тут ([Ссылки могут видеть только зарегистрированные и активированные пользователи]), включаемый файл тут ([Ссылки могут видеть только зарегистрированные и активированные пользователи])
там же найдеш такой кусок в коде flyUp(client, times)
{

global

local loopn := times - 1
local time := 0.5 ;s
local baseAddress := ReadMemory(realBaseAddress,client) ;00986c00
local pointer1 := ReadMemory(baseAddress+baseOffset,client) ;04c88408
local player := ReadMemory(pointer1+playerOffset,client)

SetFormat, IntegerFast, hex

local yCoord := readmemory(player+playerYposOffset, client, 4)
local yCoordFloat := hextofloat(yCoord)

if(yCoordFloat < 700)
{

loop %times%
{
sleep 500
local packet := "0700"
local counter := readmemory(player+playerCounterOffset, client, 2)
local interval := readmemory(player+playerIntervalOffset, client, 2) ;0x01F4
local xCoord := readmemory(player+playerXposOffset, client, 4)
local zCoord := readmemory(player+playerZposOffset, client, 4)
local speed := readmemory(player+playerFlySpdOffset, client, 4)
local moveType := 0x61

local speedFloat := hextofloat(speed)

local yCoordFloat := yCoordFloat + speedFloat * time
local sendSpeedFloat := speedFloat * 256 + 0.5
local sendSpeedHex := floor(sendSpeedFloat)
local sendYcoordHex := floattohex(yCoordFloat)
revHex(value, xCoord)
packet := packet . value
revHex(value, sendYcoordHex)
packet := packet . value
revHex(value, zCoord)
packet := packet . value
revHex(value, sendSpeedHex, 4)
packet := packet . value
packet := packet . "00" ;direction
revHex(value, moveType, 2)
packet := packet . value
revHex(value, counter, 4)
packet := packet . value
packet := packet . "F401" ;unknown value

writeMemory(counter + 1,player+playerCounterOffset, client, 2)
writeMemory(sendYcoordHex,player+playerYposOffset, client)
sendPacket(packet, "16", 0x16, client)

}
;Send an invalid packet so the server updates your location properly :P:P

local packet := "0700"
local counter := readmemory(player+playerCounterOffset, client, 2)
local speedFloat := hextofloat(speed)

local yCoordFloat := yCoordFloat + speedFloat * time
local sendSpeedFloat := speedFloat * 256 + 0.5
local sendSpeedHex := floor(sendSpeedFloat)
local sendYcoordHex := floattohex(yCoordFloat)
revHex(value, xCoord)
packet := packet . value
revHex(value, sendYcoordHex)
packet := packet . value
revHex(value, zCoord)
packet := packet . value
revHex(value, sendSpeedHex, 4)
packet := packet . value
packet := packet . "00" ;direction
revHex(value, moveType, 2)
packet := packet . value
revHex(value, counter, 4)
packet := packet . value
packet := packet . "0000" ;unknown value

writeMemory(counter + 1,player+playerCounterOffset, client, 2)
writeMemory(sendYcoordHex,player+playerYposOffset, client)
sendPacket(packet, "16", 0x16, client)


sleep 2000
}
SetFormat, IntegerFast, d
}

В данном куске кода реализован взлет без использования инжектов,а так же нужное тебе формирование пакета. Но не запутайся, обрати внимание на выделение красным цветом (в коде идет формирование так сказать не правильного пакета в начале) Все константы всегда выносятся в файл WQing.ini, прилагаемый к программе. Свежий гео бот найдешь тут ([Ссылки могут видеть только зарегистрированные и активированные пользователи])

sin(alpha)
19.11.2011, 10:09
Заморочился попробовать инжекты. Клиент вылетает со светофором, по описанию проблема в стеке код кривой тестовый Visual C++, консоль, не допераю как передать аргументы в функцию в потоке:

#include "stdafx.h"

const DWORD BaseAddress = 0x000b27a04;
const DWORD PW_GAMERUN_ADDR = 0x00B280C4;
DWORD PlayerStruct = 0;
void Walk(float x, float y, float z, Client c);
locale rus("rus_rus.866");
struct Param
{
DWORD Param1,Param2,Param3;
DWORD Param4;
};

int wmain(int argc, _TCHAR* argv[])
{
wcout.imbue(rus);
wcin.imbue(rus);
wchar_t *name = L"ElementClient Window";
Client c(name);
DWORD b = c.ReadInt32(BaseAddress);
printf("%8.0X",b); cout<<"\n\r";
b = c.ReadInt32(b+0x1C);
printf("%8.0X",b); cout<<"\n\r";
b = c.ReadInt32(b+0x34);
PlayerStruct = b;
printf("%8.0X",b); cout<<"\n\r";
b = c.ReadInt32(b+0x638);
printf("%8.0X",b); cout<<"\n\r";
BYTE buffer[66];
WCHAR *persName;
for(int i=0; i<33;i++)
{
buffer[i] = c.ReadByte(b+i);
}
persName = (WCHAR*)buffer;
wcout<<persName;
int i;
cin>>i;
Sleep(2000);
Walk(10,0,0,c);
cin>>i;
return 0;
}
bool CallRemoteFunction(HANDLE pProcess, LPVOID func, LPVOID param)
{
//Remote Thread Handle
HANDLE hProcess=pProcess;
//Inject Thread handle
HANDLE hThread=NULL;
//Inject Fuction Address after allocate
LPVOID ThreadCodeAddr=NULL;
//Inject Function
LPVOID ThreadDataAddr=NULL;
//Inject Fuction Stack Data
LPCVOID lpParam = NULL;
DWORD Value = 0;
lpParam = &Value;


ThreadCodeAddr=VirtualAllocEx(hProcess, NULL, 4096, MEM_COMMIT, PAGE_READWRITE);
ThreadDataAddr=VirtualAllocEx(hProcess, NULL, 256, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory (hProcess, ThreadCodeAddr, func, 4096, NULL);
WriteProcessMemory (hProcess, ThreadDataAddr, param, 256, NULL);
hThread = CreateRemoteThread(hProcess, NULL, NULL,(LPTHREAD_START_ROUTINE)ThreadCodeAddr, ThreadDataAddr, NULL, NULL);
if (!hThread)
{
//Do your Error message (CreateRemoteThread);
}
else
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
VirtualFreeEx(hProcess, ThreadCodeAddr, 4096, MEM_RELEASE);
VirtualFreeEx(hProcess, ThreadDataAddr, 256, MEM_RELEASE);
CloseHandle(hProcess);
return false;
}

void _stdcall WalkCall(Param* params)
{
LPVOID CallAddress1,CallAddress2,CallAddress3;
float x,y,z;
DWORD flying;
CallAddress1 = reinterpret_cast<LPVOID>(0x0046E410);
CallAddress2 = reinterpret_cast<LPVOID>(0x004728E0);
CallAddress3 = reinterpret_cast<LPVOID>(0x0046E880);
x = *((float*)(byte*)params->Param1);
y = *((float*)(byte*)params->Param2);
z = *((float*)(byte*)params->Param3);
flying = params->Param4;
_asm
{
pushad
mov eax, dword ptr [PW_GAMERUN_ADDR]
mov esi, dword ptr [eax+34h]
mov ecx, dword ptr [esi+1050h]
push 1
call CallAddress1
mov edi, eax
lea eax, dword ptr [esp+0Ch]
push eax
push flying
mov ecx, edi
call CallAddress2
mov ecx, dword ptr [esi+1050h]
push 0
push 1
push edi
push 1
call CallAddress3
mov eax, dword ptr [PW_GAMERUN_ADDR]
mov eax, dword ptr [eax+34h]
mov eax, dword ptr [eax+1050h]
mov eax, dword ptr [eax+30h]
mov ecx, dword ptr [eax+4h]
mov eax, x
mov dword ptr[ecx+20h], eax
mov eax, z
mov dword ptr[ecx+24h], eax
mov eax, y
mov dword ptr[ecx+28h], eax
popad
}
}

void Walk(float x, float y, float z, Client c)
{
byte WalkMode;
Param params;
ReadProcessMemory(c.Process(),reinterpret_cast<DWORD*>(PlayerStruct+0x64c),&WalkMode,1,NULL); //BaseWalkMode = GA +34 +64C
if (WalkMode == 0) params.Param4 = 0; else params.Param4 =1;
params.Param1=*((DWORD*)(byte*)&x)+c.ReadInt32(PlayerStruct+0x3c);
params.Param2=*((DWORD*)(byte*)&y)+c.ReadInt32(PlayerStruct+0x44);
params.Param3=*((DWORD*)(byte*)&z)+c.ReadInt32(PlayerStruct+0x40);
CallRemoteFunction(c.Process(),WalkCall,&params);
}

stdafx.h:

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <locale>
#include <string.h>
#include <strsafe.h>
#include <iostream>


using namespace std;

class Client
{
HWND hwnd;
DWORD pID;
HANDLE process;
DWORD pointer;
public:

Client(wchar_t *name)
{
hwnd = NULL;
wprintf_s(L"Window searching...");
wprintf_s(L"\n\r");
hwnd = FindWindowExW(NULL,hwnd,name,NULL);
if (hwnd != NULL)
{
wprintf (L"Window founded. Handler HWND: "); cout<<hwnd<<'\n'<<'\r';
wprintf_s(L"Taking process ID...");wprintf_s(L"\n\r");
GetWindowThreadProcessId(hwnd,&pID);
if (pID != 0)
{
wprintf (L"Process ID is are DWORD: "); cout<<pID<<'\n'<<'\r';
wprintf_s(L"Opening process...");
wprintf_s(L"\n\r");
IAmaDebugger(false);
process = OpenProcess(PROCESS_ALL_ACCESS,0,pID);
wprintf (L"ERR CODE: "); cout<<GetLastError()<<'\n'<<'\r';
if (process == NULL) {wprintf (L"Cannot open process");Sleep(2000);exit(-1);}
wprintf (L"Full access process opened. HANDLE: "); cout<<process<<'\n'<<'\r';
}
else wprintf (L"ID not taken");
}
else {wprintf_s(L"Window not found.");wprintf_s(L"\n\r");}
wprintf(L"************************************************** ****************");cout<<'\n'<<'\r';
cout<<'\n'<<'\r';
cout<<'\n'<<'\r';
pointer = 0;
}

~Client(void)
{
}

HWND HWnd() {return hwnd;}
DWORD PID() {return pID;}
HANDLE Process() {return process;}
LPVOID Pointer() {return reinterpret_cast<LPVOID>(pointer);}
BYTE ReadByte (DWORD addr)
{
SIZE_T readed;
BYTE buf = 0;
ReadProcessMemory(process,reinterpret_cast<DWORD*>(addr),&buf,1,&readed);
return buf;
}
DWORD ReadInt32 (DWORD addr)
{
SIZE_T readed;
BYTE buf[4] = {0,0,0,0};
ReadProcessMemory(process,reinterpret_cast<DWORD*>(addr),buf,4,&readed);
pointer = *((DWORD*)buf);
return *((DWORD*)buf);
}

void IAmaDebugger(bool debug)
{
HANDLE hCp;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hCp))
{
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
LookupPrivilegeValue(0, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
tp.Privileges[0].Attributes = debug ? SE_PRIVILEGE_ENABLED : 0;
AdjustTokenPrivileges(hCp, 0, &tp, sizeof(tp), 0, 0);
CloseHandle(hCp);
}

}
};
class MemPtr
{
DWORD adr;
DWORD pointer;
public:
LPVOID Value;
MemPtr(DWORD address)
{
adr = address;
Value = reinterpret_cast<LPVOID>(adr);
}
~MemPtr()
{

}

LPVOID operator + (DWORD offset)
{
LPVOID out;
adr += offset;
out = reinterpret_cast<LPVOID>(adr);
return out;
}

};

CreateRemoteThread выдает ошибку 998 "Неправильный доступ к памяти" почему ХЗ.

heh
05.12.2011, 21:51
простите за наглость но случайно ни у кого нет кусочка кода(в идеале делфи) который творит инжект - тагрет ID поломал мозг совсем

gurin
14.12.2011, 23:43
Не подскажете пакет для поднятия лута? (аналог кнопки - Поднимать предметы)

aktivizion15
15.12.2011, 00:01
gurin, подсказать то легко, но он будет работать только в близи лута, лучше использовать инжект

gurin
15.12.2011, 01:06
да-да, мне так и надо

krukovis
13.01.2012, 21:28
Подскажите пожалуйста как сейчас выглядит функция отправки клавиш в клиент.
Раньше было так (код VB.NET)
Public Sub ButtonPressCall(ByVal intButtonCommand As Integer)
Dim intProcID As Integer = PW_PROCESS_ID
Dim CallAddress As Integer = &H804A80 '&H73E250
Dim asm As New ASM()
asm.Pushad()
asm.Mov_EAX(intButtonCommand)
asm.Push_EAX()
asm.Mov_ECX(BaseAddress)
asm.Mov_ECX_DWORD_Ptr_ECX()
asm.Mov_ECX_DWORD_Ptr_ECX_Add(&H1C)
asm.Mov_ECX_DWORD_Ptr_ECX_Add(&H4)
asm.Mov_ECX_DWORD_Ptr_ECX_Add(&H8)
asm.Mov_ECX_DWORD_Ptr_ECX_Add(&H18)
asm.Mov_ESI_ECX()
asm.Mov_EBP(CallAddress)
asm.Call_EBP()
asm.Popad()
asm.Ret()
asm.RunAsm(intProcID, 0)
End Sub

И что нужно передать в параметре intButtonCommand ?

Я для себя открыл, что при нажатии клавиши Tab клиент сам(!) автоматически выбирает ближайшего моба. Т.е. функцию нахождения ближайшего моба можно сильно упросить :).

Помогите, пожалуйста.

pw.lancer
28.01.2012, 13:51
Уважаемые знатоки, не могли бы вы выложить исправленный инжект прыжка?
Код от Dunmate не работает, я там пофиксил под Genesis 3 места:
собственно, CallAddress из РУОФФ Адреса и оффсеты ([Ссылки могут видеть только зарегистрированные и активированные пользователи]") (Jump=0047E890*)
mov ecx, dword ptr [PW_GAMERUN_ADDR] // тут текущий GA
mov ecx, dword ptr [ecx+$34] // было $20
Подозреваю, что проблема как минимум в CallAddress, но может и сам вызов поменялся.
В принципе, боты прыгают нормально и нажатием пробела (SendMessage(VK_SPACE)), но есть одна проблема. В ХХ, когда перс портуется к Эмиссару, диалоговое окно не закрывается через VK_ESCAPE, какое-то оно там особенное. А при открытом окне прист не может запрыгнуть на уступ, ну и вообще не прыгает и не бегает пробелом и мышкой, соответственно.

krukovis
28.01.2012, 14:27
инжект прыжка

procedure JumpCall(); stdcall;
var CallAddress:pointer;
begin
CallAddress:=Pointer($459В60);
asm
pushad
mov ecx, dword ptr [GameAddress]
mov ecx, dword ptr [ecx+$34]
push $FFFFFFFF
call CallAddress
popad
end;
end;

pw.lancer
28.01.2012, 15:01
krukovis, к сожалению, не работает - игра вылетает. Инжектами пользуюсь, в частности, отправка пакетов и WalkInject, так что архитектура отлажена, в том числе и InjectFunc.
В CE 6.1 открываю memory view, по адресу 00459B60 находится строка
E8 CB2B0100 - call 0046C730
Ставлю бряк, прыгаю в игре персонажем, бряк не срабатывает.

krukovis
28.01.2012, 17:07
по адресу 00459B60 находится строка

Сори, CallAddress:=Pointer($459D60);

=Оленька=
30.01.2012, 17:19
gurin, подсказать то легко, но он будет работать только в близи лута, лучше использовать инжект
А подскажите пожалуйсто сам инжект

HellD
31.01.2012, 07:08
=Оленька=,
[Ссылки могут видеть только зарегистрированные и активированные пользователи]

gurin
31.01.2012, 13:27
пакет для продажи

25 00 02 00 00 00 10 00 00 00 01 00 00 00 [00 00 00 00] (00 00 00 00) {00 00 00 00}

в квадратных скобках [WID вещи]
в круглых скобках (номер ячейки в инвентаре, нумерация слева-направо, сверху-вниз, начиная с 0)
в фигурных скобках {количество вещей, которые надо продать}

пакет для покупки

25 00 01 00 00 00 1C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 [00 00 00 00](00 00 00 00){00 00 00 00}

в квадратных скобках [WID вещи]
в круглых скобках (номер ячейки у НИПа, нумерация слева-направо, сверху-вниз, начиная с номер_закладки_у_нипа * 32 десятичное)
в фигурных скобках {количество вещей, которые надо купить}

правда проверено только на аптекаре

yeyebvz
31.01.2012, 13:50
Ребят, а помогите пожалуйста - как закрыть диалоговое окно нипа после разговора с ним. Я пробовал на телепортах - выбирался телепортёр, тпшился (пакетами), но диалоговое окно остаётся открытое (( Пробовал слушать что передётся после тп - добавлять такие же пакетики - не помогло.
Посоветовали закрывать инжектом, но пока не понял как его ловить можно((

gurin
31.01.2012, 14:22
Ребят, а помогите пожалуйста - как закрыть диалоговое окно нипа после разговора с ним. Я пробовал на телепортах - выбирался телепортёр, тпшился (пакетами), но диалоговое окно остаётся открытое (( Пробовал слушать что передётся после тп - добавлять такие же пакетики - не помогло.
Посоветовали закрывать инжектом, но пока не понял как его ловить можно((

отправь ESC в клиента несколько раз

=Оленька=
31.01.2012, 17:11
HellD, Спасибо) ОГРОМНОЕ и ЧЕЛОВЕЧЕСКОЕ)))
Ткнуть спасибку немогу сообщений мало((((

procedure CallResurs(aPParams:PParams); stdcall;
var
MiningCall : pointer;
ItemSN : DWord;
begin
ItemSN :=aPParams^.Param1;
MiningCall := Pointer ($00469b40);
asm
pushad
mov ecx, dword ptr[$B280C4]
mov ecx, dword ptr[ecx+$34]
push $1;
push WIDres
call MiningCall
popad
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var aParams:TParams;
begin
aParams.Param1:=WIDres;
InjectFunc(hProcess,@CallResurs,@aParams,SizeOf(aP arams));
end;


отправь ESC в клиента несколько раз

подскажите пожалуйсто как :nono::nono::nono:

krukovis
31.01.2012, 17:20
Ткнуть спасибку немогу сообщений мало((((
Всегда можно ткнуть + (чуть выше и правее аватарки).

Цитата:

Сообщение от gurinПосмотреть сообщение



отправь ESC в клиента несколько раз


подскажите пожалуйсто как

Я полагаю имеется ввиду API- функция keybd_event
На VB.NET она выглядит так: Public Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
'bVk - Виртуальный код клавиши для имитации нажатия и отпускания клавиши.
'bScan - Зарезервировано -- установлено в 0.
'dwFlags - Комбинация следующих флагов определяет различные способы имитации:
'KEYEVENTF_EXTENDEDKEY - Префикс скэн-кода с префиксным байтом, имеющим значение &HE0.
'KEYEVENTF_KEYUP - Клавиша, указанная в bVk будет отпущена. Если этот флажок не определен, клавиша будет нажата.
'dwExtraInfo - Дополнительное 32-разрядное значение, связанное с событием клавиатуры.
Public Const KEYEVENTF_KEYUP = &H2 'событие отпускания клавиши
Public Const VK_ADD = &H6B 'клавиша +
Public Const VK_CONTROL = &H11 'клавиша Ctrl
Public Const VK_TAB = &H9 'клавиша Tab
Public Const VK_MENU = &H12 'клавиша Alt
Public Const VK_ESCAPE = &H1B 'клавиша Escape
Public Const VK_LWIN = &H5B 'левая клавиша, эмулирующая нажатие кнопки ПУСК
Public Const VK_RETURN = &HD 'Enter

На твоем не знаю как, думаю нагуглишь :).
Но чтобы ее использовать должно быть активно окно клиента - что не очень удобно.

=Оленька=
31.01.2012, 17:31
Всегда можно ткнуть + (чуть выше и правее аватарки).
Уже разобралась)))) Сделала)

Я полагаю имеется ввиду API- функция keybd_event
На VB.NET она выглядит так:
На твоем не знаю как, думаю нагуглишь .


Мне на Дельфине((
Пытаюсь сама неполучается(((

Ребят, а помогите пожалуйста - как закрыть диалоговое окно нипа после разговора с ним. Я пробовал на телепортах - выбирался телепортёр, тпшился (пакетами), но диалоговое окно остаётся открытое (( Пробовал слушать что передётся после тп - добавлять такие же пакетики - не помогло.
Посоветовали закрывать инжектом, но пока не понял как его ловить можно((

Раньше было так и было здорово

procedure BtnPressAs(Btn: PParams); stdcall;
var
PW_Call: Pointer;
PW_BASE_ADDR: dword;
BT_ADDR: dword;
begin
PW_Call := Pointer($809A1F);
PW_BASE_ADDR :=$B27A04;
BT_ADDR := Btn^.Param1;
asm
pushad
mov eax, BT_ADDR
push eax
mov esi, PW_BASE_ADDR
mov esi, dword ptr [esi]
mov esi, dword ptr [esi+$4]
mov esi, dword ptr [esi+$8]
mov esi, dword ptr [esi+$70]
mov ecx, esi
call PW_Call
popad
end;
end;

procedure TForm1.Button10Click(Sender: TObject);
var
aParams: TParams;
aParamsSize: dword;
begin
aParams.Param1 := $ACB998; //00967E24
aParamsSize := SizeOf(aParams);
InjectFunc(hProcess, @BtnPressAs, @aParams, aParamsSize);
end;
только адреса устарели а я новые немогу найти нигде(((

Добавлено через 2 минуты
Но чтобы ее использовать должно быть активно окно клиента - что не очень удобно.
антифриз должен помочь

gurin
01.02.2012, 14:15
procedure SendKey(hWindow: dword; key: Word; const shift: TShiftState);
var
lparam:dword;
Begin
lParam := MakeLong(0, MapVirtualKey(key, 0)) or $20000000;
if ssAlt in Shift then
PostMessage(hWindow, WM_KEYDOWN, VK_MENU, MakeLong(0, MapVirtualKey(VK_MENU, 0)));
if ssCtrl in Shift then
PostMessage(hWindow, WM_KEYDOWN, VK_CONTROL, MakeLong(0, MapVirtualKey(VK_CONTROL, 0)));
if ssShift in Shift then
PostMessage(hWindow, WM_KEYDOWN, VK_SHIFT, MakeLong(0, MapVirtualKey(VK_SHIFT, 0)));
PostMessage(hWindow, WM_KEYDOWN, key, lParam);
Sleep(100);
PostMessage(hWindow, WM_KEYUP, key, Longint(lParam or $C0000000));
if ssShift in Shift then
PostMessage(hWindow, WM_KEYUP, VK_SHIFT, MakeLong(0, MapVirtualKey(VK_SHIFT, 0)));
if ssCtrl in Shift then
PostMessage(hWindow, WM_KEYUP, VK_CONTROL, MakeLong(0, MapVirtualKey(VK_CONTROL, 0)));
if ssAlt in Shift then
PostMessage(hWindow, WM_KEYUP, VK_MENU, MakeLong(0, MapVirtualKey(VK_MENU, 0)));
end;


использовать


SendKey(hWindow, VK_ESCAPE, []);

=Оленька=
01.02.2012, 15:40
gurin, Спасибо ОГРОМНОЕ
Плюсик нажала ;) ;)

krukovis
01.02.2012, 21:10
Написал функцию закрытия любого окна:
Функция на VB.Net с использованием ASM'а. Ниже на Delphi.

''' <summary> Закрытие окна </summary> актуально на 01.02.2012
Public Sub CloseWindow(ByVal windowOffset As Integer)
Dim intProcID As Integer = PW_WINDOW.ProcessId
Dim CallAddress As Integer = &H616EA0
Dim asm As New ASM()

asm.Pushad()

asm.Mov_EAX(BaseAddress)
asm.Mov_EAX_DWORD_Ptr_EAX()
asm.Mov_EAX_DWORD_Ptr_EAX_Add(&H1C)
asm.Mov_EAX_DWORD_Ptr_EAX_Add(&H18)
asm.Mov_EAX_DWORD_Ptr_EAX_Add(&H8)
asm.Mov_EAX_DWORD_Ptr_EAX_Add(windowOffset)
asm.Push_EAX()

asm.Push68(&HACC3BC) 'Btn_Close

asm.Mov_EBP(CallAddress)
asm.Call_EBP()

asm.Popad()
asm.Ret()
asm.RunAsm(intProcID, 0)

End Sub
Принимает в качестве параметра смещение окна
0x2B8 Действия
0x2C0 Игроки и группы
0x2C4 Служба поддержки
0x314 Характеристики персонажа
0x32C Ремонт
0x36C Призыв духа
0x3E8 Помощь
0x40C Инвентарь и Окно Торговли и Ремонта
0x428 Диалог с NPC
0x438 Домашние животные
0x458 Окно алхимика
0x468 Панель 1-9
0x470 Горячие клавиши
0x4B0 Настройки
0x4C4 Умения
0x50C Системная панель
0x51C Задания

Добавлено через 25 минут
Вот на Delphi - если найдете синтаксические ошибки - скажите - поправлю. Delphi не установлен, писал в блокноте.

procedure WinClose(WinOffset: PParams); stdcall;
var
PW_Call: Pointer;
const
PW_BASE_ADDR=$B27A04;
PW_BTN_CLOSE=$ACC3BC;

begin
PW_Call := Pointer($616EA0);
WIN_OFFSET := WinOffset^.Param1;

asm
pushad

mov eax, PW_BASE_ADDR
mov eax, dword ptr [eax]
mov eax, dword ptr [eax+$1C]
mov eax, dword ptr [eax+$18]
mov eax, dword ptr [eax+$8]
mov eax, dword ptr [eax+WIN_OFFSET]
push eax

push PW_BTN_CLOSE

call PW_Call

popad
end;
end;

procedure CloseWindow(windowOffset:dword);
begin
aParams.Param1 := windowOffset;
InjectFunc(aHandle,@WinClose,@aParams,SizeOf(aPara ms));
end;

VeTaL_UA
01.02.2012, 21:52
PW_BASE_ADDR :=$B27A04;
PW_BTN_CLOSE :=&ACC3BC;
Щито за странный знак? /horror

VeTaL_UA
01.02.2012, 22:34
Еще есть что поправить?
Я не вижу больше ничего :)

yeyebvz
02.02.2012, 17:31
krukovis, спасибо большое. Приду с работы - буду тестить. Кнопочный вариант очень не айс, т.к. и сами скилы можно было по f1-8 вызывать, париться с разморозкой окна...

=Оленька=
03.02.2012, 19:20
Написал функцию закрытия любого окна:
Функция на VB.Net с использованием ASM'а. Ниже на Delphi.
На Delphi несработал ;( вылетел клиент
если найдете синтаксические ошибки - скажите - поправлю
PW_BTN_CLOSE - ??? на ето ругнулся

var
PW_Call: Pointer;
PW_BASE_ADDR: dword;
BT_ADDR: dword;
PW_BTN_CLOSE: dword; так наверно правильнее?
begin
PW_Call := Pointer($616EA0);
PW_BASE_ADDR :=$B27A04;
PW_BTN_CLOSE :=$ACC3BC;
WIN_OFFSET := WinOffset^.Param1;
asm......
ток всеравно несработал(((

VeTaL_UA
03.02.2012, 19:36
ток всеравно несработал(((
Я бы так написал:
procedure WinClose(WinOffset: PParams); stdcall;
var
PW_Call: Pointer;
BT_ADDR: dword;
const
PW_BASE_ADDR=$B27A04;
PW_BTN_CLOSE=$ACC3BC;
begin
PW_Call := Pointer($616EA0);
WIN_OFFSET := WinOffset^.Param1;
asm
pushad

mov eax, PW_BASE_ADDR
mov eax, dword ptr [eax]
mov eax, dword ptr [eax+$1C]
mov eax, dword ptr [eax+$18]
mov eax, dword ptr [eax+$8]
mov eax, dword ptr [eax+WIN_OFFSET]
push eax

push PW_BTN_CLOSE

call PW_Call

popad
end;
end;

=Оленька=
03.02.2012, 21:16
:nono::nono::nono::nono:
Все равно неработает :nono:
Подскажите ПОЖАЛУЙСТО что здесь нетак????
procedure WinClose(WinOffset: PParams); stdcall;
var
PW_Call: Pointer;
WIN_OFFSET: dword;
const
PW_BASE_ADDR=$B27A04;
PW_BTN_CLOSE=$ACC3BC;
begin
PW_Call := Pointer($616EA0);
WIN_OFFSET := WinOffset^.Param1;
asm
pushad
mov eax, PW_BASE_ADDR
mov eax, dword ptr [eax]
mov eax, dword ptr [eax+$1C]
mov eax, dword ptr [eax+$18]
mov eax, dword ptr [eax+$8]
mov eax, dword ptr [eax+WIN_OFFSET]
push eax
push PW_BTN_CLOSE
call PW_Call
popad
end;
end;

procedure TForm1.Button10Click(Sender: TObject);
var
aParams: TParams;
begin
aParams.Param1 := $314;
InjectFunc(hProcess,@WinClose,@aParams,SizeOf(aPar ams));
end;

krukovis
03.02.2012, 21:43
В своем посте выше все замечания учел. Должно заработать. Но я честно признаться делфи вообще не знаю - адаптировал под Делфи по аналогии. У меня на VB.NET все работает :).

Добавлено через 3 минуты
Все равно неработает

А "не работает" - это клиент вылетает с ошибкой или окно не закрывается?
А то я смотрю ты пытаешься окно 0x314 - Характеристики персонажа закрыть. А может у тебя другое окно открыто?
Если так, то попробуй сначала окно диалога с НПС или Инвентарь закрыть - эти точно работают. А остальные я не проверял. Вдруг там смещения поменялись.

=Оленька=
04.02.2012, 21:07
А "не работает" - это клиент вылетает с ошибкой или окно не закрывается?
Клиент с ошибкой вылетает ;(
Если так, то попробуй сначала окно диалога с НПС или Инвентарь закрыть - эти точно работают. А остальные я не проверял. Вдруг там смещения поменялись.
Пробовала все смещения Клиент с ошибкой вылетает : памят неможет быть read...... ну и тадалее
ПОМОГИТЕ ПЛИЗЗ
а то уже истерика с этим инжектом

samosi
11.02.2012, 17:34
хМ можете кто то дать программу инжект пакетов на делпше буду очень признателен.
P.S. соурс а то я уже не понимаю в чем проблема с ошибками.

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

type
PParams = ^TParams;
TParams = packed record
Packet: array [0..100] of byte;
Param1,Param2,Param3: DWord;
Param4: array [1..100] of widechar;
end;

const
PW_BASE_ADDRESS = $00B27A04;
PW_GAMERUN_ADDR = $00B280C4;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure InjectFunc(ProcessID: Cardinal; Func, aParams: Pointer;
aParamsSize: DWord);
var
hThread: THandle;
lpNumberOfBytes: DWord;
ThreadAddr, ParamAddr: Pointer;
begin
if ProcessID<>0 then
begin
// ---- Âûäåëÿåì ìåñòî â ïàìÿòè ïðîöåññà, è çàïèñûâàåì òóäà íàøó ôóíêöèþ
ThreadAddr := VirtualAllocEx(ProcessID, nil, 256, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(ProcessID, ThreadAddr, Func, 256, lpNumberOfBytes);

// ---- Òàêæå çàïèøåì ïàðàìåòðû ê íåé
ParamAddr := VirtualAllocEx(ProcessID, nil, aParamsSize, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(ProcessID, ParamAddr, aParams, aParamsSize, lpNumberOfBytes);

// ---- Ñîçäàåì ïîòîê, â êîòîðîì âñå ýòî áóäåò âûïîëíÿòüñÿ.
hThread := CreateRemoteThread(ProcessID, nil, 0, ThreadAddr, ParamAddr, 0, lpNumberOfBytes);

// ---- Îæèäàåì çàâåðøåíèÿ ôóíêöèè
WaitForSingleObject(hThread, INFINITE);

// ---- ïîä÷èùàåì çà ñîáîé
CloseHandle(hThread);
VirtualFreeEx(ProcessID, ParamAddr, 0, MEM_RELEASE);
VirtualFreeEx(ProcessID, ThreadAddr, 0, MEM_RELEASE);
end
end;

procedure PacketCall(aPParams:PParams); stdcall;
var
CallAddress,pPacket:pointer;
Len:DWord;
begin
CallAddress:=Pointer($006737B0);
Len:=aPParams^.Param1;
pPacket:=@aPParams^.Packet;
asm
pushad
mov ecx, dword ptr [PW_BASE_ADDRESS]
mov ecx, dword ptr [ecx+$34]
push Len
push pPacket
call CallAddress
popad
end;
end;

procedure StrToByte(Packet:string; var aParams:TParams);
var
i:integer;
begin
i:=(length(Packet) div 2)-1;
aParams.Param1:=i+1;
for i:=0 to i do
aParams.Packet[i]:=strtoint('$'+bytecode[i*2+1]+bytecode[i*2+2]);//тут ощыбка
end;

procedure Packet(Packet: string);
var
aParams: TParams;
begin
StrToByte(Packet,aParams);
InjectFunc(ProcessID,@PacketCall,@aParams,sizeof(a Params));//тут ощыбка
end;

end.

VeTaL_UA
11.02.2012, 17:59
соурс а то я уже не понимаю в чем проблема с ошибками.
Можно узнать, а где ты в своём исхонике пакеты посылаешь? Объясню: в твоём исходнике пакет посылает процедура Packet, если ты заметил.
procedure Packet(Packet: string);
Я не вижу, где ты эту процедуру вызываешь.

samosi
11.02.2012, 18:46
Весь геморой то что у меня даже без нее компилить нехочет....

VeTaL_UA
11.02.2012, 19:12
Весь геморой то что у меня даже без нее компилить нехочет....
Может быть, ты нам поведаешь текст ошибки?

samosi
11.02.2012, 19:28
Вот
[Error] Unit1.pas(92): Undeclared identifier: 'bytecode'
[Error] Unit1.pas(92): Incompatible types: 'String' and 'Integer'
[Error] Unit1.pas(100): Undeclared identifier: 'ProcessID'

VeTaL_UA
11.02.2012, 19:55
Вот
А теперь прогуляйся в соседнюю ([Ссылки могут видеть только зарегистрированные и активированные пользователи]) тему.

samosi
11.02.2012, 21:05
Смотри пакет листер все выдает что я отправил пакет но у меня оно не отображаеца что я его отправил в чем соль?

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
ComboBox1: TComboBox;
Button1: TButton;
Button2: TButton;
procedure Buton1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

type
PParams = ^TParams;
TParams = packed record
Packet: array [0..100] of byte;
Param1,Param2,Param3: DWord;
Param4: array [1..100] of widechar;
end;

const
PW_BASE_ADDRESS = $00B27A04;
PW_GAMERUN_ADDR = $00B280C4;

var
Form1: TForm1;
FID: array[0..10] of THandle;

implementation

{$R *.dfm}

procedure InjectFunc(ProcessID: Cardinal; Func, aParams: Pointer;
aParamsSize: DWord);
var
hThread: THandle;
lpNumberOfBytes: DWord;
ThreadAddr, ParamAddr: Pointer;
begin
if ProcessID<>0 then
begin
// ---- Âûäåëÿåì ìåñòî â ïàìÿòè ïðîöåññà, è çàïèñûâàåì òóäà íàøó ôóíêöèþ
ThreadAddr := VirtualAllocEx(ProcessID, nil, 256, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(ProcessID, ThreadAddr, Func, 256, lpNumberOfBytes);

// ---- Òàêæå çàïèøåì ïàðàìåòðû ê íåé
ParamAddr := VirtualAllocEx(ProcessID, nil, aParamsSize, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(ProcessID, ParamAddr, aParams, aParamsSize, lpNumberOfBytes);

// ---- Ñîçäàåì ïîòîê, â êîòîðîì âñå ýòî áóäåò âûïîëíÿòüñÿ.
hThread := CreateRemoteThread(ProcessID, nil, 0, ThreadAddr, ParamAddr, 0, lpNumberOfBytes);

// ---- Îæèäàåì çàâåðøåíèÿ ôóíêöèè
WaitForSingleObject(hThread, INFINITE);

// ---- ïîä÷èùàåì çà ñîáîé
CloseHandle(hThread);
VirtualFreeEx(ProcessID, ParamAddr, 0, MEM_RELEASE);
VirtualFreeEx(ProcessID, ThreadAddr, 0, MEM_RELEASE);
end
end;

procedure PacketCall(aPParams:PParams); stdcall;
var
CallAddress,pPacket:Pointer;
Len:DWord;
begin
CallAddress:=Pointer($006737B0); //àäðåñ áûë óñòàðåâøèé
Len:=aPParams^.Param1;
pPacket:=@aPParams^.Packet;
asm
pushad
mov ecx, dword ptr [PW_BASE_ADDRESS]
mov ecx, dword ptr [ecx+$34] //20
push Len
push pPacket
call CallAddress
popad
end;
end;

procedure StrToByte(Packet:string; var aParams:TParams);
var
i:integer;
begin
i:=(length(Packet) div 2)-1;
aParams.Param1:=i+1;
for i:=0 to i do
aParams.Packet[i]:=strtoint('$'+Packet[i*2+1]+Packet[i*2+2]);
end;

procedure Packet(Packet: string);
var
aParams: TParams;
Wnd: Thandle;
PID,hProcess: DWord;
begin
Wnd:=FID[Form1.ComboBox1.ItemIndex];
GetWindowThreadProcessId(Wnd,@PID);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS,False,PID );
StrToByte(Packet,aParams);
InjectFunc(hProcess,@PacketCall,@aParams,sizeof(aP arams));
CloseHandle(hProcess);
end;

procedure TForm1.Buton1Click(Sender: TObject);
var
aParams : TParams;
begin
Packet('5500'); //îòñûëàåì ïàêåò 5500
end;

function ReadPlayerName(hProcess,data:DWord): string;
var
i,rw:DWord;
ch:WideChar;
wch:array[0..255] of WideChar;
str:string;
begin
i:=0;
repeat
ReadProcessMemory(hProcess,ptr(data),@ch,2,rw);
data:=data+2;
wch[i]:=ch;
inc(i);
until
(ord(ch)=0) or (i>=255);
i:=0;
str:='';
repeat
str:=str+wch[i];
inc(i);
until
wch[i]='';
result:=str;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
Wnd:THandle;
Nick,Res:String;
Hndl:array[0..255] of Char;
buf,ibuf,BC:DWord;
hProcess,PID,PID1:DWord;
i:Integer;
begin
for i:=0 to ComponentCount-1 do
if Components[i].ClassName = 'TComboBox' then
(Components[i] as TComboBox).Items.Clear;
begin
Wnd:=FindWindow('ElementClient Window',nil);
GetWindowThreadProcessId(Wnd,@PID);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS,False,PID );
i:=0;
while (hProcess<>0) and (PID<>PID1) do
begin
GetWindowText(Wnd,Hndl,SizeOf(Hndl));
ReadProcessMemory(hProcess,ptr(PW_BASE_ADDRESS),@i buf,sizeof(ibuf),BC);
ReadProcessMemory(hProcess,ptr(ibuf+$1C),@ibuf,siz eof(ibuf),BC);
ReadProcessMemory(hProcess,ptr(ibuf+$34),@ibuf,siz eof(ibuf),BC);
ReadProcessMemory(hProcess,ptr(ibuf+$638),@buf,siz eof(buf),BC);
Nick:=ReadPlayerName(hProcess,buf);
Res:='Handle: '+Hndl+' '+'Nickname: '+Nick;
SetWindowText(Wnd,PChar(Nick));
ComboBox1.Items.Add(Nick);
FID[i]:=Wnd;
PID:=PID1;
inc(i);
end;
CloseHandle(hProcess);
end;
end;

end.

VeTaL_UA
12.02.2012, 10:33
но у меня оно не отображаеца что я его отправил в чем соль?
А как оно должно отображаться? В твоём коде я не вижу ничего, что отображало бы удачно отправленный пакет.

BritishColonist
13.02.2012, 18:56
Нашёл один юзабельный инжектик:

//---------------------------------------------------------------------------
void Print(DWORD dwColor, wchar_t* Text)
{
DWORD Function = 0x417E00;
__asm {
mov ecx,dword ptr [BA]
mov ecx,dword ptr [ecx+0x24] // указатель на интерфейс что ли..
push Text // собственно текст
push dwColor // цвет, включая непрозрачность
call Function
}
}
//---------------------------------------------------------------------------

Применение (из DLL):
Print(0xFFCEABEF,L"Hello, Perfect World!");
Цвет это обычный DWORD. Жёлтым цветом я выделил байт непрозрачности (0 - полностью прозрачный текст, т.е. невидимый; FF - абсолютно непрозрачный).
Остальные три байта - соответствующие цвета RGB.

Второй параметр - юникод-строка.

Результат (функция вызвана много-много раз):
[Ссылки могут видеть только зарегистрированные и активированные пользователи]

Пригодится разработчикам для выведения на экран полезной информации (особенно при создании DLL).
Естественно, это на любителя - можно выводить такую полезную инфу в файл.

zaparca
21.02.2012, 10:00
Нашёл один юзабельный инжектик:
//---------------------------------------------------------------------------
void Print(DWORD dwColor, wchar_t* Text)
{
DWORD Function = 0x417E00;
__asm {
mov ecx,dword ptr [BA]
mov ecx,dword ptr [ecx+0x24] // указатель на интерфейс что ли..
push Text // собственно текст
push dwColor // цвет, включая непрозрачность
call Function
}
}
//---------------------------------------------------------------------------

Применение (из DLL):
Print(0xFFCEABEF,L"Hello, Perfect World!");

Цвет это обычный DWORD. Жёлтым цветом я выделил байт непрозрачности (0 - полностью прозрачный текст, т.е. невидимый; FF - абсолютно непрозрачный).
Остальные три байта - соответствующие цвета RGB.
Второй параметр - юникод-строка.
Пригодится разработчикам для выведения на экран полезной информации (особенно при создании DLL).
Естественно, это на любителя - можно выводить такую полезную инфу в файл.

кто нибудь может переделать на DELPHI /md очень надо )

BritishColonist
21.02.2012, 16:50
zaparca, в чём сложность? В большинстве статей zhyk.ru используется Delphi. Неужели сложно глянуть, как описываются инжекты в соседних темах?

lcd1232
21.02.2012, 17:41
Код не проверял
Function Print(dwColor: dword, Text: string);
var
DwordFunction:pointer;
begin
DwordFunction:=Pointer($417E00);
asm
mov ecx,dword ptr [BA]
mov ecx,dword ptr [ecx+0x24] // указатель на интерфейс что ли..
push Text // собственно текст
push dwColor // цвет, включая непрозрачность
call DwordFunction
end;
end;

zaparca
21.02.2012, 18:37
BritishColonist, еще вопрос по коду его надо инжектить ! или нет ?

lcd1232, после первой строки Еггог (
mov ecx,dword ptr [BA]

ошибок нет но не работает пробовал через инжект

Dinmaite
21.02.2012, 19:03
cd1232, после первой строки Еггог (
mov ecx,dword ptr [BA]
Вот алгоритм для Вас:
1. Выучить язык.
2. Писать программы.
Ни в коем случае не пропускайте первый пункт.

lcd1232
21.02.2012, 20:17
, после первой строки Еггог (
mov ecx,dword ptr [BA]
Наверно не указана константа BA

zaparca
21.02.2012, 20:18
Наверно не указана константа BA
указана

Procedure PrintPWCall(dwColor: dword;Text:string);Stdcall;
var
CallAddress:pointer;
begin
CallAddress:=pointer($417E00);
asm
pushad
mov ecx,dword ptr [base_addr]
mov ecx,dword ptr [ecx + $24]
push Text
push dwColor
call CallAddress
popad
end;
end;

procedure PrintPW(dwColor: dword;Text:string);
var aParams:TParams;
begin
aParams.Text:=Text;
aParams.dwColor:=dwColor;
InjectFunc(aHandle,@PrintPWCall,@aParams,SizeOf(aP arams));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
PrintPW($FFCEABEF,'Perfect World!');
end;

так делал и так тоже

BritishColonist
21.02.2012, 20:29
Function Print(dwColor: dword, Text: string);
var
DwordFunction:pointer;
begin
DwordFunction:=Pointer($417E00);
asm
mov ecx,dword ptr [BA]
mov ecx,dword ptr [ecx+0x24] // указатель на интерфейс что ли..
push Text // собственно текст
push dwColor // цвет, включая непрозрачность
call DwordFunction
end;
end;

Что неправильного с моей точки зрения:
1) возможно, параметры в объявлении функции следует записывать через точку с запятой, а не через запятую;
2) в дельфи шестнадцатеричные числа записываются с префиксом $, а не 0x;
3) возможно, нельзя push'ить переменные Text и dwColor (но это вряд ли).

Кстати, если хотите пилить инжект, то ещё следует добавить операции pushad и popad после ключевого слова asm и перед end соответственно.

zaparca
21.02.2012, 20:33
1) возможно, параметры в объявлении функции следует записывать через точку с запятой, а не через запятую; именно запятую
2) в дельфи шестнадцатеричные числа записываются с префиксом $, а не 0x; так и записано $FFCEABEF

Кстати, если хотите пилить инжект, то ещё следует добавить операции pushad и popad после ключевого слова asm и перед end соответственно. что то не подумал )

но так точно не работает
Procedure PrintPW(dwColor:dword;Text:string);
var
CallAddress:pointer;
begin
CallAddress:=pointer($417E00);
asm
mov ecx,dword ptr [base_addr]
mov ecx,dword ptr [ecx + $24]
push Text
push dwColor
call CallAddress
end;
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
PrintPW($FFCEABEF,'Perfect World!');
end;

krukovis
21.02.2012, 21:39
Вот алгоритм для Вас:
1. Выучить язык.
2. Писать программы.
Ни в коем случае не пропускайте первый пункт.

о_О Может мне тоже начать блистать подобными алгоритмами, это я так 100500 спасибо за пару дней набью... :D

lcd1232, после первой строки Еггог (
mov ecx,dword ptr [BA]

Для разнообразия BA что ли объявите... А то вызываете неведомую фуйню.

zaparca
21.02.2012, 21:44
Для разнообразия BA что ли объявите... А то вызываете неведомую фуйню.

const
base_addr = $B27A04;

я уже где-то писал

krukovis
21.02.2012, 21:47
Цитата:

Сообщение от lcd1232Посмотреть сообщение



Наверно не указана константа BA


указана

А ты не обманщик?

Добавлено через 2 минуты
const
base_addr = $B27A04;

я уже где-то писал

В том, что ты выкладывал не увидел.

ADD:
А функции делфи точно хавают переменные и константы объявленные вне функции?

VeTaL_UA
21.02.2012, 21:51
Скорее всего так:
procedure Print(dwColor:DWord;Text:string);stdcall;
const
BA=$B27A04;
DwordFunction:Pointer=Pointer($417E00);
begin
asm
mov ecx,dword ptr[BA]
mov ecx,dword ptr[ecx+$24]
push Text
push dwColor
call DwordFunction
end;
end;
Вызывать так:
Print($FFCEABEF,'Perfect World');

zaparca
21.02.2012, 21:59
VeTaL_UA, Invalid combination of opcode and operands
после правки

mov ecx,dword ptr [BA]
окно
access violation at address 0045A966 in module 'Prog.exe'.Read of address 00B27A04.

VeTaL_UA
21.02.2012, 22:10
Поправил код.

BritishColonist
21.02.2012, 22:53
in module 'Prog.exe'.Read of address 00B27A04.
Этот код не внедрён в адресное пространство игры. А ведь должен быть.

krukovis
22.02.2012, 07:56
Я полагаю, что функция должна выглядеть так:
================================================== =============================================
Функция для отображения текста на экране
================================================== =============================================
Удалено, как нерабочая. Рабочей на Delphi у меня нет.
================================================== ===========================
Функция Закрытия окна на Delphi.
================================================== ===========================
Удалено как нерабочая. Рабочая выложена ТУТ ([Ссылки могут видеть только зарегистрированные и активированные пользователи])

lcd1232
23.02.2012, 21:00
krukovis, щас голова не соображает, чтобы додумать.
WinOffset^.Param1
Выдает на данную строку т.к. не описан параметр.
procedure WinClose(WIN_OFFSET:DWord;);лишняя

krukovis
23.02.2012, 21:37
Выдает на данную строку т.к. не описан параметр.
Поправил. Пробуйте и отпишитесь по результатам теста.

zaparca
24.02.2012, 10:54
dwColor := aPParams^.Param1; Text := aPParams^.Param2;
Зачем присваивать то что уже есть ?

код в принципе ничем не отличается от написаного мною

Вопрос в другом тут
InjectFunc(??????,@PrintPWCall,@aParams,SizeOf(aPa rams));
что должно быть ?
aHandle := FindWindow('ElementClient Window', nil);
//при этом ничего не происходит



или
GetWindowThreadProcessId(aHandle, @PId);
hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, PId);
//при этом вылетает клиент (работает при PickWalk, Jump, Walk)


просьба к BritishColonist, может сделаете программу на С с одной кнопкой просто проверить работает ли инжект /dgs, может он работает только после ижекта DLL (и только DLL).

krukovis
24.02.2012, 11:13
Зачем присваивать то что уже есть ?
Чтобы передать в функцию.

код в принципе ничем не отличается от написаного мною
Глаза раззуй.

Вопрос в другом тут
Код:
InjectFunc(??????,@PrintPWCall,@aParams,SizeOf(aPa rams));
что должно быть ?
А что у тебя InjectFunc принимает в виде первого параметра? Вот это и надо передавать. Обычно это ProcessID: Cardinal;

zaparca
26.02.2012, 10:14
krukovis, все = не работает подождем BritishColonist

krukovis
26.02.2012, 11:38
krukovis, все = не работает
Не знаю как у вас на Delphi, у меня на VB.NET все работает. У вас другие инжекты (прыжок тот же) тоже не работают?

zaparca
26.02.2012, 13:18
у меня на VB.NET все работает
ну кинь свою программу с одной функцией вывод текста 'Zhyk.Ru' проверить

HellD
29.02.2012, 12:10
Что закрытие окна(диалоги,торги, окно перса, все остальное), что вывод текста... не работает ни одно ни другое... выбивает клиент, что и как не менял... не знаю как там у Вас на VB.Net, но у нас на delphi ничерта не робит)

krukovis
29.02.2012, 12:14
но у нас на delphi ничерта не робит)
Ни один человек на форуме так и не сказал, а работают ли у него другие инжекты? Прыжок например, или еще что то?

HellD
29.02.2012, 12:15
Ни один человек на форуме так и не сказал, а работают ли у него другие инжекты? Прыжок например, или еще что то?
да, все остальные инжекты работают на ура...

krukovis
29.02.2012, 12:29
да, все остальные инжекты работают на ура...

Ну значит нужно взять готовый инжект и изменить его под выложенный мною асм.
Я не знаю как должны выглядеть точно функции на Delphi, потому что Delphi не знаю. Но знаю какой должен быть код на ассемблере. Его я выложил и выложил свое видение функции на Делфи (по аналогии с другими инжектами на делфи), ошибки в синтаксисе Делфи я просил помочь найти участников форума (особо никто не откликнулся). Если функции - не правильные - исправьте их в соответствии с синтаксисом Делфи, взяв мой асм.
Функция "Принт" на делфи может и не работать, потому что, например для отображения текста на ВБ.Нет, текст нужно сначала помещать куда то в память, а в функцию передавать уже указатель на эту строку в памяти. Но закрытие окна - должно работать не зависимо ни от чего, если ее правильно вызвать.

Если не сложно - пришли в личку или выложи тут код, как у тебя вызывается инжект прыжка, только полностью(делфи я ж не знаю и не смогу дописать ничего или смогу, но с ошибками), чтобы я смог запустить этот код у себя.

HellD
29.02.2012, 13:02
Сори не стал особо наводить красоту в коде, быстренько настрочил...

Button1 - коннектит к окну с хэндлом указанным в edit1

Button2 - отправляет перса в координаты 0,0,0 = все работает.. .ну по крайне мере бежать начинает ))
Button3 - закрывает окно характеристик персонажа(ну вернее должно было бы) = вылет клиента
Button4 - Должно выводить текст Perfect World = вылет клиента
Button5 - инжект прыжка = работает

Инжекты в том виде что и тут.. я прост не помню уже что менял и как ток не пробовал... поэтому свои перековерканные и все равно не рабочие кидать не стал, взял от сюда... во вложении zip c исходником проекта на делфе и скомпилированной исполняшкой...


И что б его... как тут спойлер всунуть? )) а то так исходник кинуть слишком громоздко ((

krukovis
29.02.2012, 13:10
Инжекты в том виде что и тут.. я прост не помню уже что менял и как ток не пробовал... поэтому свои перековерканные и все равно не рабочие кидать не стал, взял от сюда... во вложении zip c исходником проекта на делфе и скомпилированной исполняшкой...
Спасибо. Дома проверю и, если получится исправить, выложу тут.

Добавлено через 10 часов 1 минуту
Итак, 100500 спасибо Dinmaite, за пояснения как работать с asm на Delphi.
И наконец то рабочий вариант:
================================================== ===========================
Функция Закрытия окна на Delphi.
================================================== ===========================
Функция для внедрения:
procedure WinCloseCall(aPParams: PParams); stdcall;
var
WIN_OFFSET: DWord;
PW_Call: Pointer;
const
PW_BASE_ADDR=$B27A04;
PW_BTN_CLOSE=$ACC3BC;

begin
WIN_OFFSET := aPParams^.Param1;
PW_Call := Pointer($616EA0);
asm
pushad

mov eax, PW_BASE_ADDR
mov eax, dword ptr [eax]
mov eax, dword ptr [eax+$1C]
mov eax, dword ptr [eax+$18]
mov eax, dword ptr [eax+$8]

mov ebx, WIN_OFFSET
mov eax, dword ptr [eax+ebx]
push eax

push PW_BTN_CLOSE

call PW_Call

popad
end;
end;

Внедряющая функция:
procedure WinClose(WIN_OFFSET:DWord);
var aParams:TParams;
begin
aParams.Param1:=WIN_OFFSET; //Смещение окна из списка
InjectFunc(hProcess,@WinCloseCall,@aParams,SizeOf( aParams));
end;

Вызов:
WinClose($40C); //Закрыть окно Торговли и Ремоната.

Список смещений для передачи в функцию:
0x2B8 Действия
0x2C0 Игроки и группы
0x2C4 Служба поддержки
0x314 Характеристики персонажа
0x32C Ремонт
0x36C Призыв духа
0x3E8 Помощь
0x40C Инвентарь и Окно Торговли и Ремонта
0x428 Диалог с NPC
0x438 Домашние животные
0x458 Окно алхимика
0x468 Панель 1-9
0x470 Горячие клавиши
0x4B0 Настройки
0x4C4 Умения
0x50C Системная панель
0x51C Задания

Исходники на Delphi можно скачать тут [Ссылки могут видеть только зарегистрированные и активированные пользователи]

Функцию Print ремонтировать не буду, т.к. не знаю как это делать на Delphi и не считаю ее существенной, чтобы узнавать.

Anzorias
23.03.2012, 20:46
А как реализовать поиск предмета в инвентаре?
Ну на примере "Кораллов". Если они лежат в инвентаре, то будут открываться.
Если нет, то ... дальше сам.

BritishColonist
23.03.2012, 22:38
Anzorias, каких ещё кораллов? Ладно-ладно, я-то ещё играл на этой фришке и знаю, что это такое, но мне кажется, что мало кому понятно, в чём соль.

Короче, бежишь по инвентарю и проверяешь TypeId предметов.
Адреса и смещения:

BA = B27A04
PlayerStruct = BA +1C +34 // начало структуры игрока
Inventory = PlayerStruct +CAC // структура инвентаря
SlotCount = Inventory +10 // количество ячеек инвентаря
ItemsStart = Inventory +C // начало структуры самих предметов
ItemX_Start = ItemsStart +X*4 (X in [0..SlotCount]) // начало структуры предмета, лежащего в ячейке X
Если в ItemX_Start лежит 0, то в ячейке нет предмета. В противном случае можно посмотреть его TypeId:
ItemX_TypeId = ItemX_Start +8
Этот TypeId соответствует типу, взятому из базы pwdatabase.com, поэтому не составит труда получить их из этой базы. А если составит, то проверить можно через Cheat Engine, составив цепочку оффсетов по описанным выше данным.

Если ItemX_TypeId совпадёт с Id кораллов, то формируешь пакет на использование этого предмета и отсылаешь его серверу.

rufat2005
30.03.2012, 09:29
а как можно пользоваться с пакетами полученными packetlistener
точнее вот 2 пакета
280000010000276F0000 -
280000010100896F0000
пакеты для открытия коробок
куда нуна прописать пакеты в вышеуказанных примерах (инжектах) чтоб пользоваться в delphi
заранее спасибо!

krukovis
30.03.2012, 09:36
а как можно пользоваться с пакетами полученными packetlistener
точнее вот 2 пакета
280000010000276F0000 -
280000010100896F0000
пакеты для открытия коробок
куда нуна прописать пакеты в вышеуказанных примерах (инжектах) чтоб пользоваться в delphi
заранее спасибо!
В функцию отправки пакетов.

dwa83
30.03.2012, 10:34
Может кто-нибудь поделиться инжектами для пета? В частности, атака, использование скилла, перевод режима или хотябы адреса инжектов. А дальше сам допилю.

Или может кто-нибудь поможет разобраться со следующим кодом?


CPU Disasm
Address Hex dump Command Comments
00698BA0 /$ PUSH EBX
00698BA1 |. PUSH EBP
00698BA2 |. PUSH ESI
00698BA3 |. MOV ESI,DWORD PTR SS:[ARG.4]
00698BA7 |. LEA EBP,[ESI+0A]
00698BAA |. PUSH EBP ; /Arg1
00698BAB |. CALL 00879990 ; \elementclient.008798E0
00698BB0 |. MOV EBX,EAX
00698BB2 |. ADD ESP,4
00698BB5 |. TEST EBX,EBX
00698BB7 JE SHORT 00698C01
00698BB9 |. MOV EAX,DWORD PTR SS:[ARG.1]
00698BBD |. MOV ECX,DWORD PTR SS:[ARG.2]
00698BC1 |. MOV WORD PTR DS:[EBX],67
00698BC6 |. MOV DWORD PTR DS:[EBX+2],EAX
00698BC9 |. TEST ESI,ESI
00698BCB |. MOV DWORD PTR DS:[EBX+6],ECX
00698BCE JE SHORT 00698BE9
00698BD0 |. MOV ECX,ESI
00698BD2 |. MOV ESI,DWORD PTR SS:[ARG.3]
00698BD6 |. MOV EDX,ECX
00698BD8 |. PUSH EDI
00698BD9 |. LEA EDI,[EBX+0A]
00698BDC |. SHR ECX,2
00698BDF |. REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
00698BE1 |. MOV ECX,EDX
00698BE3 |. AND ECX,00000003
00698BE6 |. REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
00698BE8 |. POP EDI
00698BE9 |> A1 047AB200 MOV EAX,DWORD PTR DS:[0B27A04]
00698BEE |. PUSH EBP ; /Arg2
00698BEF |. PUSH EBX ; |Arg1
00698BF0 |. MOV ECX,DWORD PTR DS:[EAX+20] ; |
00698BF3 |. CALL 006737B0 ; \elementclient.006737B0
00698BF8 |. PUSH EBX ; /Arg1
00698BF9 |. CALL 008799A0 ; \elementclient.008798F0
00698BFE |. ADD ESP,4
00698C01 |> POP ESI
00698C02 |. POP EBP
00698C03 |. POP EBX
00698C04 \. RETN





Если кусок кода после жёлтого перехода проигнорировать с помощью замены на JMP, в клиенте происходит замораживание кнопок "пет, к ноге" и "пет, стой где стоишь" Следовательно в этом куске происходит смена данных режимов. Там происходит только запись в память каких то значений по адресу, находящемуся в EDI, я так понимаю это указатель на какую-то структуру.

В среднем вызове функции параметр Arg2 - какое-то значение ( E - при нажатии "следовать", "на месте" или перевода режима агрессивности, B - при нажатии атаки, F - при нажатии на любой скилл пета,) Arg1 - тут наверное указатель на какую-то структуру.
Структуру пета, или хз на что ещё. Может кто-нибудь помочь разобраться с этим если не лень? В идеале хотелось бы добиться полного управления поведением петом через инжекты, но буду рад, если получится хотябы простая атака.

rufat2005
30.03.2012, 11:32
тоесть

procedure PacketCall(aPParams:PParams); stdcall;
var
CallAddress,pPacket:pointer;
Len:DWord;
begin
CallAddress:=Pointer($0060E310); // Старый адрес - $005D7C30
Len:=aPParams^.Param1;
pPacket:=@aPParams^.Packet;
asm
pushad
mov ecx, dword ptr [PW_BASE_ADDRESS]
mov ecx, dword ptr [ecx+$20]
push Len
push pPacket
call CallAddress
popad
end;
end;

procedure StrToByte(Packet:string; var aParams:TParams);
var
i:integer;
begin
i:=(length(Packet) div 2)-1;
aParams.Param1:=i+1;
for i:=0 to i do
aParams.Packet[i]:=strtoint('$'+bytecode[i*2+1]+bytecode[i*2+2]);
end;

procedure Packet(Packet: string);
var
aParams: TParams
begin
aParams := $280000010000276F0000;
StrToByte(Packet,aParams);
InjectFunc(ProcessID,@PacketCall,@aParams,sizeof(a Params));

или как?) плизз помогите
end;

Добавлено через 2 минуты
у меня почему та при прочтении памяти с помощью OLLYDBG не выходит /Arg1 и \elementclient.008798F0

когда делаю по гайду... у меня последная версия OLLYDBG 1.10
но таргет к мобу прошел....

Skuka.95
30.03.2012, 13:18
aParams := $280000010000276F0000;
если не ошибаюсь там надо а не aParams, а Packet

rufat2005
30.03.2012, 13:20
всё разобрался уже)) где что прописать))

Добавлено через 7 часов 25 минут
а как можно узнать ид квеста у персонажа?
нужно узнать какой ид квеста у персонажа

gurin
31.03.2012, 18:52
Добрый день, не подскажете, как при установке кота программно нажать на кнопку OK?

вот это не сработало почему-то (вылетел клиент)


const
base_addr = $B27A04;

procedure BtnPressAs(Btn: PParams); stdcall;
var
PW_Call: Pointer;
PW_BASE_ADDR: dword;
BT_ADDR: dword;
begin
PW_Call := Pointer($00788380);//0073E250
PW_BASE_ADDR := base_addr;
BT_ADDR := Btn^.Param1;
asm
pushad
mov eax, BT_ADDR
push eax
mov esi, PW_BASE_ADDR
mov esi, dword ptr [esi]
mov esi, dword ptr [esi+$4]
mov esi, dword ptr [esi+$8]
mov esi, dword ptr [esi+$70]//18 set текущее окно
mov ecx, esi
call PW_Call
popad
end;
end;

procedure PushBtnOK(hProc: THandle);
var
aParams: TParams;
aParamsSize: dword;
begin
aParams.Param1 := $00A0DB94; //00976730
aParamsSize := SizeOf(aParams);
InjectFunc(hProc, @BtnPressAs, @aParams, aParamsSize);
end;


Добавлено через 8 часов 27 минут

Список смещений для передачи в функцию:
0x2B8 Действия
0x2C0 Игроки и группы
0x2C4 Служба поддержки
0x314 Характеристики персонажа
0x32C Ремонт
0x36C Призыв духа
0x3E8 Помощь
0x40C Инвентарь и Окно Торговли и Ремонта
0x428 Диалог с NPC
0x438 Домашние животные
0x458 Окно алхимика
0x468 Панель 1-9
0x470 Горячие клавиши
0x4B0 Настройки
0x4C4 Умения
0x50C Системная панель
0x51C Задания

как получить смещения других окон? В частности окна, которое появляется при установке кота.

PW_BTN_CLOSE=$ACC3BC;

как получить адрес других кнопок?

dwa83
02.04.2012, 00:36
Доброй ночи. Хотел спросить насчёт инжекта использования предмета из инвентаря. Адрес в шапке 00668490 судя по всему работает (хотя помечен звёздочкой). Вобщем, нашёл я кусок кода, который вызывается при использовании предметов в инвентаре. Если проследовать по коду, то после нескольких проверок и джампов в зависимости от того, используемый предмет или нет, откат у предмета или нет мы попадаем к вызову функции как раз по этому адресу. Но там есть один параметр, значение которого я не знаю. Там какой-то адрес, который не меняется, пока не перезапустишь клиент. Судя по всему указывает на какую то структуру. Если в этом параметре прямо числовым значением указать то что показывает Olly в этом регистре перед вызовом функции, то инжект работает. Может кто выложить asm код инжекта, или подсказать на какую структуру указывает этот адрес?

Вот ниже код
// Использование предмета
void __stdcall UseItem_THREAD(CELL_ITEM* itm)
{
DWORD id = itm->id;
DWORD num = itm->CellNum;
DWORD Function = 0x00668490;
DWORD HZadress = 0x07C3E3C4; // если подставить напрямую значение которое показывает Olly
__asm
{
PUSH 1 // ; /Arg4 = 1
PUSH id // ; |Arg3 // ид предмета (проверил по базе)
PUSH num // ; |Arg2 //номер ячейки, отсчёт от 0
PUSH 0 // ; |Arg1 = 0
MOV ECX,HZadress // ; | // ХЗ что такое(
CALL Function // ; \elementclient.00668490
}
}

void GAME_PROC::UseItem(DWORD id, int cell)
{
CELL_ITEM itm;
itm.id=id;
itm.CellNum=cell;
InjectAndExecute(&UseItem_THREAD, &itm);
}

Добавлено через 4 часа 41 минуту
Всё, допёр что за цепочка была. Вот что получилось
void __stdcall UseItem_THREAD(CELL_ITEM* itm)
{
DWORD id = itm->id;
DWORD num = itm->CellNum;
DWORD Function = 0x00668490;
__asm
{
PUSH 1 // ; /Arg4 = 1
PUSH id // ; |Arg3
PUSH num // ; |Arg2
PUSH 0 // ; |Arg1 = 0
MOV ECX,[BA]
MOV ECX,[ECX+0x20]
ADD ECX,0x0EC
CALL Function // ; \elementclient.00668490
}
}

Сейчас инжект использования предмета рабочий.
Если кто-нибудь без пакетов делает, пригодится)

.AsTex.
05.04.2012, 08:27
Пакет на инфо о персонаже(шмот и т.д.) подскажите

TBXin
05.04.2012, 08:37
anderwhat, на общие статы один пакет, на расширенные статы другой пакет, а так же на каждый тип инвентаря свой пакет.
Клиент свои статы не запрашивает, все приходит при подключении к серверу, а так же при любом изменении оных.

З.Ы. На сколько я помню :)

.AsTex.
05.04.2012, 08:42
мне нужно вызвать окно шмота персонважа в таргете, еще хотелось бы узнать, возможно ли получить названия того, что на нем надето

TBXin
05.04.2012, 08:52
Используйте packet listener. Запускаете, делаете пкм - показать игрока и смотрите какой пакет поймали. Там более чем тривиально все. Потом будете подменять ID игрока на нужного и получать окошко, но таймаут вам не обойти.

По поводу названий предметов, которые надеты на цели, вам придется найти структуру, схожую с вашим эквипом и распарсить её.

.AsTex.
05.04.2012, 09:02
саму структуру не подскажете, как получить?

TBXin
05.04.2012, 09:16
Если её еще никто не нашел и не выложил, то возможный алгоритм поиска таков:
1. Открываем информацию о персонаже Х
2. Видим в слоте "Броня" находится предмет с ID N.
3. Ищем все значения в памяти клиента соответствующие этому ID
4. Открываем другое окна с информацией о персонаже
5. Отсеиваем значения, которые уже равны ID брони второго игрока
6. Делаем так пока не найдем точный адрес
7. Ставим "бряк" на этом адресе (what writes on this address) или как-то так...
8. Снова открываем игрока и в окошке дебагера видим адреса, по которым производится запись в нашу ячейку памяти.
9. Пытаемся найти нужные оффсеты. (есть гайды, например поиск базового адреса)

В целом как-то так.

.AsTex.
05.04.2012, 21:15
TBXin, что-то не получается...

Smertig
19.04.2012, 15:53
Подскажите пакет на крафт, в котором на рецепт перетаскивать нужно части. Например, нирвана.
Крафтил много раз, пакеты отличаются только двумя байтами, в котором указана ячейка, откуда берется пуха и восприятия соответственно. При отправке пакета - клиент вылетает со светофором.
Помогите, пожалуйста :(

rufat2005
19.04.2012, 16:33
когда посмотрел на пакеты крафта трактов то получил очь длинный пакет... который не мог отправить...
как ети пакеты можно отправлять?
заранее спасибо

ktulx
19.04.2012, 22:41
Не мог бы кто-нибудь кратко объяснить (можно просто пару ссылок) мне разницу между "использованием пакетов" и инжектом кода, скажем, для реализации функции прыжка? Я нуб, читаю, пытаюсь понять, но пока именно этот момент взрывает мне мозг.

спасибо.

BritishColonist
19.04.2012, 22:54
ktulx, инжект это такая функция, которая имитирует действие игрового клиента, используя при этом копию оригинальной функции клиента либо вызывая её, ничего не копируя.
"Пакеты" - это инжект функции отправки пакета. Как правило большинство инжектов, используемых для бота, в конечном итоге формируют и отправляют пакет.
Когда пишут "инжект", имеют в виду инжект действия, если говорят "пакет", то подразумевается отправка пакета этого действия через стандартную функцию клиента.
Некоторые вещи проще делать отправкой пакета, а некоторые - инжектами действий.
Но, как правило, эти варианты взаимоисключающие. Если используешь инжект действия, то клиент дальше сам сформирует пакет. Происходит это посредством "вложенных" вызовов функции-инжекта. Если используешь пакет, то отпадает смысл составлять код инжекта.
Плюс пакетов в том, что внедряемый код весит меньше и в том, что при обновлении версии клиента функцию отправки пакета гораздо проще обновить (т.к. сами пакеты, как правило, остаются одинаковыми всегда).

Короче, пакет - это тоже инжект, поэтому в плане кода и его внедрения в процесс игры здесь разницы нет.

gurin
26.04.2012, 02:06
Поменялся пакет на покупку 0_О. теперь он такой:


procedure Buy(ItemId, ItemCount, shopIndex: dword);
begin
Packet('25 00 01 00 00 00 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 ' +
dwValueToString(ItemId)+' '+
dwValueToString(shopIndex)+' '+
dwValueToString(ItemCount));
end;

krukovis
15.05.2012, 21:50
================================================== ===========================
Функция Закрытия окна на Delphi для клиента ver 1.4.5 build 2305
================================================== ===========================
Функция для внедрения:

procedure WinCloseCall(aPParams: PParams); stdcall;
var
WIN_OFFSET: DWord;
PW_Call: Pointer;
const
PW_BASE_ADDR=$00A571E0;
PW_BTN_CLOSE=$00950C18; //IDCANCEL

begin
WIN_OFFSET := aPParams^.Param1;
PW_Call := Pointer($004F0150);
asm
pushad

mov eax, PW_BASE_ADDR
mov eax, dword ptr [eax]
mov eax, dword ptr [eax+$1C]
mov eax, dword ptr [eax+$18]
mov eax, dword ptr [eax+$8]

mov ebx, WIN_OFFSET
mov eax, dword ptr [eax+ebx]
push eax

push PW_BTN_CLOSE

call PW_Call

popad
end;
end;


Внедряющая функция:

procedure WinClose(WIN_OFFSET:DWord);
var aParams:TParams;
begin
aParams.Param1:=WIN_OFFSET; //Ñìåùåíèå îêíà èç ñïèñêà
InjectFunc(Form1.hProcess,@WinCloseCall,@aParams,S izeOf(aParams));
end;


Вызов:

procedure TForm1.Button3Click(Sender: TObject);
begin
WinClose($41C); //Закрыть окно Торговли и Ремоната.
end;


Список смещений для передачи в функцию:

0x2C8 Действия
0x2D0 Игроки и группы
0x2D4 Служба поддержки
0x324 Характеристики персонажа
0x33C Ремонт
0x37C Призыв духа
0x3F8 Помощь
0x41C Инвентарь и Окно Торговли и Ремонта
0x438 Диалог с NPC
0x448 Домашние животные
0x468 Окно алхимика
0x478 Панель 1-9
0x480 Горячие клавиши
0x4C0 Настройки
0x4D4 Умения
0x51C Системная панель
0x52C Задания


Исходники на Delphi можно скачать тут [Ссылки могут видеть только зарегистрированные и активированные пользователи]

Meg(0)
23.05.2012, 01:51
чем gamerun адрес отличается от базового? и как его найти?
и что за call адрес,его как найти?

dwa83
23.05.2012, 17:57
чем gamerun адрес отличается от базового? и как его найти?
и что за call адрес,его как найти?
gamerun, если не ошибаюсь, это GameAdress или GA, как и BA тоже статический и находится как [[BA] + 1C] по текущей версии руофа. Можно не считывать значение по оффсету BA + 1С а указывать сразу GA. А call adress - это адрес точки входа в какую-либо клиентскую функцию, то-есть адрес, который мы используем в команде call ассемблера.

Meg(0)
23.05.2012, 18:21
а как найти этот самый call адрес?

dwa83
23.05.2012, 19:02
а как найти этот самый call адрес?
Посмотрите темку "Поиск инжектов" или "Наш код в чужом процессе" ([Ссылки могут видеть только зарегистрированные и активированные пользователи]). Там на примере функции выделения в таргет показано как найти кусок кода для инжекта, в котором и присутствует адрес конкретно этой функции.

004619CD |. A1 0CB9A500 MOV EAX,DWORD PTR DS:[A5B90C]
004619D2 |. 57 PUSH EDI ; /Arg1
004619D3 |. 8B48 20 MOV ECX,DWORD PTR DS:[EAX+20] ; |
004619D6 |. 81C1 EC000000 ADD ECX,0EC ; |
004619DC |. E8 8F501A00 CALL elementc.00606A70 ; \elementc.00606A70

Добавлено через 5 минут
Действительно ли так важно самому найти? В теме РУОФФ Адреса и оффсеты ([Ссылки могут видеть только зарегистрированные и активированные пользователи]) есть же многие выложенные адреса

Meg(0)
23.05.2012, 23:43
Посмотрите темку "Поиск инжектов" или "Наш код в чужом процессе" ([Ссылки могут видеть только зарегистрированные и активированные пользователи]). Там на примере функции выделения в таргет показано как найти кусок кода для инжекта, в котором и присутствует адрес конкретно этой функции.

004619CD |. A1 0CB9A500 MOV EAX,DWORD PTR DS:[A5B90C]
004619D2 |. 57 PUSH EDI ; /Arg1
004619D3 |. 8B48 20 MOV ECX,DWORD PTR DS:[EAX+20] ; |
004619D6 |. 81C1 EC000000 ADD ECX,0EC ; |
004619DC |. E8 8F501A00 CALL elementc.00606A70 ; \elementc.00606A70

Добавлено через 5 минут
Действительно ли так важно самому найти? В теме РУОФФ Адреса и оффсеты ([Ссылки могут видеть только зарегистрированные и активированные пользователи]) есть же многие выложенные адреса


просто я не знаю,какие именно надо call искать... а то,что там есть,я использовал,но вылетает клиент..(

BritishColonist
24.05.2012, 00:17
Meg(0), брать адреса для CALL из шапки - это как лотерея. Все называют эти адреса так, как сами того захотят. Я о том, что адрес - не панацея. От него по сути вообще нет никакого толку. Ведь инжекты у разных разработчиков разные (если они сами их ищут), следовательно, велика вероятность того, что разные инжекты, приспособленные для одного действия, используют разные адреса для вызовов. Например, можно открыть инвентарь кнопкой <B>, а можно просто кликнуть мышью на его иконку. Если искать инжект для этого, получатся две разные функции с двумя разными адресами. Предположим, один разработчик использует первый вариант, а другой - второй вариант. Оба выложили свои инжекты в паблик, но после обновы адрес функции соизволил обновить только один из тех двоих разработчиков. И этот адрес попадает в шапку этой темы под названием типа "OpenInventoryCall". В какой инжект пихать - хороший вопрос. А что самое забавное - иногда в паблике нельзя вообще найти инжект для нужного адреса.

Короче, я не рекомендую использовать готовые адреса функций, если Вы не знаете, для какого конкретно кода эти адреса приспособлены. Лучше всего самостоятельно искать инжекты.

Meg(0)
24.05.2012, 00:28
ух...тяжело будет в слепую их искать...ведь я их пробовал найти пару раз и то не знаю,как проверить,что я нашёл..((

krukovis
24.05.2012, 12:24
ух...тяжело будет в слепую их искать...ведь я их пробовал найти пару раз и то не знаю,как проверить,что я нашёл..((
Без труда, не найдешь и функцию для инжекта. Если хотите серьезно подойти к ботостроению, то нужно начинать учиться. Начинайте с этого:
Посмотрите темку "Поиск инжектов" или "Наш код в чужом процессе" ([Ссылки могут видеть только зарегистрированные и активированные пользователи]). Там на примере функции выделения в таргет показано как найти кусок кода для инжекта, в котором и присутствует адрес конкретно этой функции.

Meg(0)
24.05.2012, 17:29
разобраться б как правильно вписывать asm с ollydbg ...
вот к примеру разговор с нпс...
с помощью CE делаем проверку(бегаем,прыгаем),потом открываем диалог с нпс,закрывем,снова открываем
затем в CE ищем те,где 2 клика использовано в конце самом..
эти адреса использовать в ollydbg
а с ollydbg просто в свою программу выписывать в той же последовательности.. правильно?

krukovis
24.05.2012, 17:39
эти адреса использовать в ollydbg
а с ollydbg просто в свою программу выписывать в той же последовательности.. правильно?
Мне кажется ты не понимаешь что видишь с ольке. Ты ассемблер знаешь? В ольке есть замечательная функция Help по асм-команде. Правой кнопкой по команде и выбирай хелп. Там будет описание что конкретная функция делает.

Meg(0)
25.05.2012, 00:19
а как проверить,работу инжекта?
вот к примеру,как его запустить?
procedure TalkToNPCCall(aPParams:PParams);Stdcall;
var NPCID:DWORD;
BaseAddress,CallAddress:Pointer;
begin
BaseAddress:=ptr($00A571E0);
NPCID:=aPParams^.Param1;
CallAddress:=ptr($0062FD80);
asm
pushad
mov edx, dword ptr [BaseAddress]
mov ecx, dword ptr [edx+$34]
push NPCID
add ecx, $EC
call CallAddress
popad
end;

krukovis
25.05.2012, 10:53
а как проверить,работу инжекта?
вот к примеру,как его запустить?
Тут есть пример рабочего инжекта и исходники: [Ссылки могут видеть только зарегистрированные и активированные пользователи]
Попробуй найти ответы на свои вопросы.

Meg(0)
26.05.2012, 01:16
у кого есть исправленный? :noemotion::nono:
procedure PacketCall(aPParams:PParams); stdcall;
var
CallAddress,pPacket:pointer;
Len:DWord;
begin
CallAddress:=Pointer($0060E310);
Len:=aPParams^.Param1;
pPacket:=@aPParams^.Packet;
asm
pushad
mov ecx, dword ptr [PW_BASE_ADDRESS]
mov ecx, dword ptr [ecx+$34]
push Len
push pPacket
call CallAddress
popad
end;
end;

procedure TalkToNPCCall(aPParams:PParams);Stdcall;
var NPCID:DWORD;
BaseAddress,CallAddress:Pointer;
begin
BaseAddress:=ptr($00A571E0);
NPCID:=aPParams^.Param1;
CallAddress:=ptr($0062FD80);
asm
pushad
mov edx, dword ptr [BaseAddress]
mov ecx, dword ptr [edx+$34]
push NPCID
add ecx, $EC
call CallAddress
popad
end;
end;

procedure TalkToNPC(NPCID:Cardinal);
var aParams:TParams;
v:HWND;
begin
aParams.Param1:=NPCID:;
InjectFunc(v,@TalkToNPCCall,@aParams,SizeOf(aParam s));
end;

и где должно находится значение NPCID?
к примеру вот это:
$801045ff

ktulx
28.05.2012, 01:08
Приветствую )

Если вызывать скиллы пакетами, то нужно учитывать таргет, откат и прочее. При использовании инжекта функции, достаточно указать ID скилла.
Существует подобная альтернатива использованию итема из инвентаря? То есть, без привязки к номеру ячейки.

Спасибо.

krukovis
28.05.2012, 11:09
Существует подобная альтернатива использованию итема из инвентаря? То есть, без привязки к номеру ячейки.
Есть альтернатива использования предметов/скиллов вынесенных на панель быстрого доступа c помощью горячих клавишь 1-9 и F1-F12.

BritishColonist
28.05.2012, 15:24
krukovis, слишком толсто же ;D
Лучше имитировать нажатие на предмет (инжектом, а не отправкой клавиш).
Если вопрос в том, существует ли альтернатива, то ответ я только что дал выше, а если требуется конкретная реализация, то лично мне в данный момент лень. : D

krukovis
28.05.2012, 15:52
krukovis, слишком толсто же ;D
Лучше имитировать нажатие на предмет (инжектом, а не отправкой клавиш).
Если вопрос в том, существует ли альтернатива, то ответ я только что дал выше, а если требуется конкретная реализация, то лично мне в данный момент лень. : D

Так я и говорю про инжект нажатия горячей клавиши. Можно кстати инжект клика мышки в нужных координатах сделать. Но искать для нового клиента мне так же лень. Но если знаешь что это есть - то есть смысл искать.

dwa83
28.05.2012, 17:46
...

procedure TalkToNPCCall(aPParams:PParams);Stdcall;
var NPCID:DWORD;
BaseAddress,CallAddress:Pointer;
begin
BaseAddress:=ptr($00A571E0);
NPCID:=aPParams^.Param1;
CallAddress:=ptr($00630B60);
asm
pushad
mov edx, dword ptr [BaseAddress]
mov ecx, dword ptr [edx+$20] // тут не 34, а 20, это не PersStruct
push NPCID
add ecx, $EC //тут так и есть EC
call CallAddress
popad
end;
end;


procedure PacketCall(aPParams:PParams); stdcall;
var
CallAddress,pPacket:pointer;
Len:DWord;
begin
CallAddress:=Pointer($0063DB70);
Len:=aPParams^.Param1;
pPacket:=@aPParams^.Packet;
asm
pushad
mov ecx, dword ptr [PW_BASE_ADDRESS]
mov ecx, dword ptr [ecx+$20] // тут не 34, а 20, это не PersStruct
push Len
push pPacket
call CallAddress
popad
end;
end;

и где должно находится значение NPCID?

procedure TalkToNPC(NPCID:Cardinal); // <-сюда передаётся как параметр
var aParams:TParams;
v:HWND;
begin
aParams.Param1:=NPCID:;
InjectFunc(v,@TalkToNPCCall,@aParams,SizeOf(aParam s));
end;

Добавлено через 7 минут
Существует подобная альтернатива использованию итема из инвентаря? То есть, без привязки к номеру ячейки.
Создать функцию, которая получает в качестве параметра только ID, сканирует инвентарь на наличие этого ID берёт номр ячейки, в которой нашёлся данный предмет и вызывает инжект уже с указанием ID и найденным номером ячейки. У меня бот так банки пьёт, из любой ячейки, лишь бы они были в инвентаре.

krukovis
29.05.2012, 11:17
dwa83, дорогой, оформи топик по человечески, пожалуйста. Основное - теги code

Meg(0)
29.05.2012, 13:18
procedure TalkToNPC(NPCID:Cardinal); // <-сюда передаётся как
параметр

а от кудого передаётся?

или сюда ввести айди вместо параметра?
NPCID:=aPParams^.Param1;

dwa83
29.05.2012, 16:12
dwa83, дорогой, оформи топик по человечески, пожалуйста. Основное -
Извиняюсь..

Добавлено через 8 минут
а от кудого передаётся?
Ну как откудого? Либог Из переменной, в которой хранится ID нужного NPC либо напрямик писать ID. Вот пожую ещё немного:
Допустим нам нужно открыть диалоговое окно с ближайшим от нас НПС, мы проверяем массив окружающих мобов/нпс, находим среди них ближайшего НПС(по расстоянию до него) и считываем его ID. Далее вызываем функцию, параметром которой и является найденный нами ID, и при условии, что мы стоим на расстоянии, позволяющем открыть диалог, диалог откроется.
Либо если мы уже посмотрели по базе ID конкретного нужного нам NPC, то подводим бота к нему на положенное расстояние и вызываем функцию с уже заранее известным ID, например:
TalkToNPC(1234); // здесь 1234 - это ид конкретного NPC (не путать ID с WID)

ktulx
29.05.2012, 17:14
Возможно меня не вполне правильно поняли, или я недопонял ответы ) Внесу больше конкретики:

Читаю инвентарь в массив записей с двумя полями: ID и ИМЯ. Как мне лучше/удобнее/ресурсоэкономичнее реализовать использование итема из инвентаря? Единственное, что мне пришло в голову - добавить в массив записей третье поле, куда будет записываться номер ячейки и затем подставлять этот номер и ID в пакет. Но возникает одно "но": а если вдруг итем был перемещён? Либо, скажем, у меня в инвентаре 150 микстур бодрости, 100 в первой ячейке и 50 во второй. В выпадающем списке формы я выбираю предмет по названию, а в пакет подставляется соответствующий ID и номер ячейки. Микстуры в первой/второй ячейке заканчиваются, и пакет уже будет недействителен. Следовательно, мне нужно хотя бы раз в несколько секунд перечитывать инвентарь, верно? Насколько неправильным будет такое решение? ))

Ах да, забыл добавить. Не хочу делать вызов по горячей клавише ) это несколько не труъ.

Спасибо.

krukovis
29.05.2012, 17:28
Следовательно, мне нужно хотя бы раз в несколько секунд перечитывать инвентарь, верно?
Инвентарь нужно считывать перед тем, как ты собираешься что то использовать. Перебор в 32 значения - это совершенно не ресурсоемкая задача. Да и вообще сильно не заморачивайся по поводу затрат ресурсов. Учитывая отклик от сервера в 500 мс, задержки в твоих циклах должны быть равны примерно 1000 мс (+-200 мс). А выполнение операций (циклов и прочего) занимает примерно 20 мс. Поэтому твоя программа будет работать примерно 10% времени и 90% времени будет просто находится в паузе.

ktulx
29.05.2012, 17:34
Инвентарь нужно считывать перед тем, как ты собираешься что то использовать.

Это само собой. Что вообще скажешь о механизме, который я описал? "Нормально"? ) Спасибо за ответ о ресурсоёмкости. Меня слегка беспокоил этот вопрос.

krukovis
29.05.2012, 18:01
Что вообще скажешь о механизме, который я описал? "Нормально"?
Механизм должен быть такой, как мне кажется:
1)Ты выбираешь название предмета из списка в инвентаре, а программа запоминает его ID, без привязки к номеру ячейки.
2) Программа считывает в массив данные о предметах в инвентаре. Где ключ - № ячейки, а значение - ID.
3) Далее ты ищешь первую ячейку в которой у тебя лежит нужный предмет. Ищешь по значению (ID). Поиск по значению как раз и выдает номер ячейки. В Delphi же ключи считаются от нуля, на сколько я знаю. И у тебя ячейки идут от нуля.
4) Далее ты отправляешь пакет на использование нужного тебе предмета определив № ячейки и зная ID.

Meg(0)
31.05.2012, 12:14
TalkToNPC(1234); // здесь 1234 - это ид конкретного NPC (не путать ID с WID)
так ошибку показывает
а так ничего не происходит...
procedure TalkToNPCCall(aPParams:PParams);Stdcall;
var NPCID:DWORD;
BaseAddress,CallAddress:Pointer;
begin
BaseAddress:=ptr($00A571E0);
NPCID:=$801045de;
CallAddress:=ptr($00630B60);
asm
pushad
mov edx, dword ptr [BaseAddress]
mov ecx, dword ptr [edx+$34]
push NPCID
add ecx, $EC
call CallAddress
popad
end;
end;

procedure TalkToNPC(NPCID:Cardinal);
var aParams:TParams;
v:HWND;
begin
aParams.Param1:=NPCID;
InjectFunc(v,@TalkToNPCCall,@aParams,SizeOf(aParam s));
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
TalkToNPC($438);
end;

может не туда написал id нпс?

dwa83
31.05.2012, 15:44
NPCID:=$801045de;
Не ВИД а ИД, было всё правильно - $438 приходило сюда из параметра PParams.
mov ecx, dword ptr [edx+$34]
ну не 34 тут а 20, я ведь писал
TalkToNPC($438);
всё правильно, но почему здесь именно значение $438 и почему именно в шестнадцатиричной форме? Перевожу в десятичное, получаю 1080, лезу в базу ПВ, нахожу непонятно какого НПС без имени и без толкового описания(ссылка ([Ссылки могут видеть только зарегистрированные и активированные пользователи])). Это чей ИД?

Добавлено через 41 минуту
ktulx, а откуда вы хотите вообще брать ID? Считать из списка предметов, которые в данный момент находятся в инвентаре или знать ID-ы предметов заранее?

Я себе сделал без заморочек.

В проге сделал массив такого типа

ID банок для 0 левела
ID банок для 5 левела
ID банок для 12 левела
ID банок для 20 левела
...

Разместил на форме заранее заполненный комбо-бокс, в котором выбирается левел используемых банок.
Уровень банок 0
Уровень банок 5
Уровень банок 12
Уровень банок 20
...

Далее в зависимости от того какая строка в комбо-боксе выбрана, берётся из массива нужный ID и ищется ячейка в которой лежит предмет с таким ID, смотрится её номер, и вызывается инжект с известным номером и известным ID. Если нужного предмета не нашлось, бот летит покупать банки.

Раньше было так: бралось первое значение из массива, сканировался инвентарь от конца до начала(чтобы использовались сначала последние ячейки и банки наименьшего левела) на наличие первого ID, если находили, использовался этот предмет. Если не находили, то брали второй ID из массива и опять сканировали инвентарь от конца к началу, если вообще нет ни одной банки ни для какого левела, то летели закупаться.

Meg(0)
31.05.2012, 23:37
dwa83, не заметил,что не исправил 34 на 20,вот сейчас так сделал
TalkToNPC($4445);
тоже никакой реакции,добавил сюда поиск окна,вдруг он ранее нахождение окна не считывает,поставил так,тоже ничего не происходит..(
procedure TalkToNPC(NPCID:Cardinal);
var aParams:TParams;
v:HWND;
begin
v:=FindWindow(nil,Pchar('Perfect World));
if v <> 0
then
begin
aParams.Param1:=NPCID;
InjectFunc(v,@TalkToNPCCall,@aParams,1);
end;
end;

NPCID:=aPParams^.Param1;

dwa83
01.06.2012, 17:36
TalkToNPC($4445);
Откуда вы берёте 4445? если из базы то этому ID соответствует торговец ЕСЛИ ЧИСЛО В ДЕСЯТИЧНОМ ВИДЕ, в шестнадцатиричном соответствует опять же непонятному НПС. Уберите знак "$".

procedure InjectFunc(ProcessID: Cardinal; Func, aParams: Pointer; aParamsSize: DWord);
А вы туда хэндл окна суёте, да и процесс не открыли перед инжектом.

Добавлено через 4 часа 0 минут
Написал функцию закрытия любого окна:
Функция на VB.Net с использованием ASM'а. Ниже на Delphi.

''' <summary> Закрытие окна </summary> актуально на 01.02.2012
Public Sub CloseWindow(ByVal windowOffset As Integer)
Dim intProcID As Integer = PW_WINDOW.ProcessId
Dim CallAddress As Integer = &H616EA0
Dim asm As New ASM()

asm.Pushad()

asm.Mov_EAX(BaseAddress)
asm.Mov_EAX_DWORD_Ptr_EAX()
asm.Mov_EAX_DWORD_Ptr_EAX_Add(&H1C)
asm.Mov_EAX_DWORD_Ptr_EAX_Add(&H18)
asm.Mov_EAX_DWORD_Ptr_EAX_Add(&H8)
asm.Mov_EAX_DWORD_Ptr_EAX_Add(windowOffset)
asm.Push_EAX()

asm.Push68(&HACC3BC) 'Btn_Close

asm.Mov_EBP(CallAddress)
asm.Call_EBP()

asm.Popad()
asm.Ret()
asm.RunAsm(intProcID, 0)

End Sub
Принимает в качестве параметра смещение окна
0x2B8 Действия
0x2C0 Игроки и группы
0x2C4 Служба поддержки
0x314 Характеристики персонажа
0x32C Ремонт
0x36C Призыв духа
0x3E8 Помощь
0x40C Инвентарь и Окно Торговли и Ремонта
0x428 Диалог с NPC
0x438 Домашние животные
0x458 Окно алхимика
0x468 Панель 1-9
0x470 Горячие клавиши
0x4B0 Настройки
0x4C4 Умения
0x50C Системная панель
0x51C Задания

Добавлено через 25 минут
Вот на Delphi - если найдете синтаксические ошибки - скажите - поправлю. Delphi не установлен, писал в блокноте.

procedure WinClose(WinOffset: PParams); stdcall;
var
PW_Call: Pointer;
const
PW_BASE_ADDR=$B27A04;
PW_BTN_CLOSE=$ACC3BC;

begin
PW_Call := Pointer($616EA0);
WIN_OFFSET := WinOffset^.Param1;

asm
pushad

mov eax, PW_BASE_ADDR
mov eax, dword ptr [eax]
mov eax, dword ptr [eax+$1C]
mov eax, dword ptr [eax+$18]
mov eax, dword ptr [eax+$8]
mov eax, dword ptr [eax+WIN_OFFSET]
push eax

push PW_BTN_CLOSE

call PW_Call

popad
end;
end;

procedure CloseWindow(windowOffset:dword);
begin
aParams.Param1 := windowOffset;
InjectFunc(aHandle,@WinClose,@aParams,SizeOf(aPara ms));
end;

Очень прошу указать актуальные адреса и смещения для данной функции. Или может кто-нибудь поделиться рабочим инжектом закрытия окна диалога?

krukovis
01.06.2012, 22:21
Очень прошу указать актуальные адреса и смещения для данной функции. Или может кто-нибудь поделиться рабочим инжектом закрытия окна диалога?

Вот тут и функция и исходники для 1.4.5
[Ссылки могут видеть только зарегистрированные и активированные пользователи]

Meg(0)
13.06.2012, 09:55
Откуда вы берёте 4445? если из базы то этому ID соответствует торговец ЕСЛИ ЧИСЛО В ДЕСЯТИЧНОМ ВИДЕ, в шестнадцатиричном соответствует опять же непонятному НПС.
да,это ID из базы,торговец...перевожу в шестнадцатиричный,получается 115D,без $ не работает,ошибку показывает

сделал вот так...но тоже ничего не происходит

procedure TalkToNPCCall(aPParams:PParams);Stdcall;
var NPCID:DWORD;
BaseAddress,CallAddress:Pointer;
begin
BaseAddress:=ptr($00A571E0);
NPCID:=aPParams^.Param1;//$801044b2; //aPParams^.Param1;//$801045de;
CallAddress:=ptr($00630B60);
asm
pushad
mov edx, dword ptr [BaseAddress]
mov ecx, dword ptr [edx+$20]
push NPCID
add ecx, $EC
call CallAddress
popad
end;
end;

procedure TalkToNPC(NPCID:Cardinal);
var aParams:TParams;
v:HWND;
Pid,hProcess:DWord;
begin
v:=FindWindow(nil,Pchar('Perfect World'));
if v <> 0
then
begin
GetWindowThreadProcessId(v,@PId);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS,False,PId );
aParams.Param1:=NPCID;
InjectFunc(PId,@TalkToNPCCall,@aParams,1);
end;
end;



procedure TForm1.Button6Click(Sender: TObject);
begin
TalkToNPC($115D);
end;

end.

dwa83
13.06.2012, 18:35
перевожу в шестнадцатиричный,получается 115D
Зачем?

1)Берём ID nps из базы(оно там в десятичном виде) к примеру 4445
2) прямо так и подставляем 4445 без знака $
либо если это нужно(зачем не понятно) переводим в шестнадцатиричный вид - $115D и подставляем шестнадцатиричное значение, естественно со значком $, иначе ругаться будет на символы (A..F) без указания того, что это шеснадцатиричное значение.
Ид взят правильно, но проблема видимо теперь не в этом.. А расстояние до НПС соблюдаете? Нужно стоять рядом именно с этим НПС который в базе(не с другими).

Добавлено через 11 минут
но тоже ничего не происходит
Не вылетов, ни зависов, ничего совсем?

Прошу прощения, нужно не ид а вид прописывать(( каюсь, запутал, сильно не бить. Просто нужно брать из базы ид, а потом в массиве мобов\нпс искать его ВИД, и его уже нужно в инжект.. ещё раз сорь, что сразу не проверил, смутило вот это NPCID:=aPParams^.Param1;

Meg(0)
13.06.2012, 23:22
нужно не ид а вид прописывать(( каюсь, запутал, сильно не бить. Просто нужно брать из базы ид, а потом в массиве мобов\нпс искать его ВИД, и его уже нужно в инжект..
вид можно узнать с помощи консоли пв? вот к примеру это он? $801045de;и его вписать

TalkToNPC($801045de);
так? но куда тогда вставлять ид ?

dwa83
14.06.2012, 00:25
вид можно узнать с помощи консоли пв? вот к примеру это он? $801045de;и его вписать

TalkToNPC($801045de);
так? но куда тогда вставлять ид ?
Да, это WID. ID конкретно в этой функции не нужен, правильнее было сразу написать NPCWID:=aPParams.. Хотя я на 100% не уверен что WID не меняется..

Meg(0)
14.06.2012, 02:00
всёравно ничего не происходит(((

procedure TalkToNPCCall(aPParams:PParams);Stdcall;
var NPCID:DWORD;
BaseAddress,CallAddress:Pointer;
begin
BaseAddress:=ptr($00A571E0);
NPCID:=aPParams^.Param1;//$801044b2; //aPParams^.Param1;//$801045de;
CallAddress:=ptr($00630B60);
asm
pushad
mov edx, dword ptr [BaseAddress]
mov ecx, dword ptr [edx+$20]
push NPCID
add ecx, $EC
call CallAddress
popad
end;
end;

procedure TalkToNPC(NPCID:Cardinal);
var aParams:TParams;
v:HWND;
Pid,hProcess:DWord;
begin
v:=FindWindow(nil,Pchar('Perfect World'));
if v <> 0
then
begin
GetWindowThreadProcessId(v,@PId);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS,False,PId );
aParams.Param1:=NPCID;
InjectFunc(PId,@TalkToNPCCall,@aParams,1);
end;
end;



procedure TForm1.Button6Click(Sender: TObject);
begin
TalkToNPC($801045de); //4445
end;

end.

krukovis
14.06.2012, 09:51
Хотя я на 100% не уверен что WID не меняется..
WID - World ID - мировой ID - или ID объекта (как вы помните GameObject разделяется по типу NPC, Mob, Pet).
WID не меняется в рамках данной локации у NPC и Mob т.к. WID назначается единожды при создании объекта, но у Pet меняется каждый раз при вызове и отзыве. Поэтому лучше всего находить WID каждый раз перед инжектом по постоянному параметру ID (или Name).


всёравно ничего не происходит(((
На сколько я вижу - это функция не TolkToNpc, а FullTarget (на днях обновлял у себя ее), поэтому "должно происходить" лишь выделение объекта (NPC в данном случае).
Вот как вызов FullTarget выглядит для 1.4.5 на asm:
'Full Target 1.4.5 RuOff
'Address Hex dump Command Comments
'0048D555 |> \A1 E071A500 MOV EAX,DWORD PTR DS:[0A571E0] ; Base Address
'0048D55A |. 8B48 20 MOV ECX,DWORD PTR DS:[EAX+20] ; Host Player Action Offset
'0048D55D |. 57 PUSH EDI ; /Arg1, target WID
'0048D55E |. 81C1 EC000000 ADD ECX,0EC ; |
'0048D564 |. E8 27321A00 CALL 00630790 ; \elementclient.00630790, call Full Target Functions

Добавлено через 7 минут
А вызываю диалог с NPC я уже давно пакетами, потому что проще. Пакет для вызова диалога с NPC:
23 00 D1 3C 10 80 - открыть диалог с NPC. (c 2 по 5 = 4 байта - WID NPC)

dwa83
14.06.2012, 10:38
На сколько я вижу - это функция не TolkToNpc, а FullTarget
Возможно куски их вызова похожи(так как всё кроме адреса одинаково)? Я сейчас не могу проверить, так ли это, потому что Target делаю пакетом, но вот беру из своего рабочего бота функцию открытия диалога с NPC:
//__________________________________________________ ____________________________
// Открытие диалога с НПС по WID
void INJECTOR::OpenDialog(DWORD wid)
{
char fdata[30]="\x60\x8B\x15\x00\x00\x00\x00\x8B\x4A\x20\x68\x11\x 11\x11\x11\x81\xC1\xEC\x00\x00\x00\xBB\x22\x22\x22 \x22\xFF\xD3\x61\xC3";
DWORD func=F_DIALOG;
DWORD ba=BA;
memcpy(fdata+3,&ba,4);
memcpy(fdata+11,&wid,4);
memcpy(fdata+22,&func,4);
InjectFunction(&fdata,30);
}

Если загнать массив опкодов в Olly то получится вот это:
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Что соответствует:
PUSHAD
MOV EDX,DWORD PTR DS:[BA]
MOV ECX,DWORD PTR DS:[EDX+20]
PUSH WID
ADD ECX,0EC
MOV EBX,00630B60
CALL EBX
POPAD
RETN
строчку MOV EBX,00630B60 я сам уже добавлял, раньше было просто CALL addr
Пожоже всё, кроме адреса
Адрес у меня такой:
#define F_DIALOG 0x630B60
Потому наверное просто похожие куски кода вызова, но странно что не работает, а у меня всё гуд..

krukovis
14.06.2012, 11:11
Пожоже всё, кроме адреса
Да. Посмотрел сейчас - оказывается такая подготовка параметров у многих функций.



Target делаю пакетом
Я и выделяю пакетом и диалог открываю пакетом. А функция FullTarget мне для OffsetRetriver'а нужна была.

Meg(0), а тебе что мешает на пакеты перейти?

Meg(0)
14.06.2012, 15:58
Meg(0), а тебе что мешает на пакеты перейти?
я не умею ими пользоваться..не разбираюсь что как и от кудого((
я не знаю,как и что именно записывать в delphie то,что я нашёл в ollydbg к примеру с открытого диалога с нпс...

krukovis
14.06.2012, 15:59
я не умею ими пользоваться..не разбираюсь что как и от кудого((
Ну а функция отправки пакета у тебя есть?

dwa83
14.06.2012, 16:16
я не умею ими пользоваться..не разбираюсь что как и от кудого((
Тут ничего сложного. Есть хотя бы 1 функция для инжекта которая норм работает? Если так, то 90% уже готово.
Если такая функция есть, то она инжектится и получает в качестве параметра какое нибудь значение, например WID, и затем с этим параметром вызывает клиентскую функцию. Нам нужна ещё одна функция, для инжекта, которая так же будет инжектиться и вызывать КЛИЕНТСКУЮ ФУНКЦИЮ ОТПРАВКИ ПАКЕТА. А в качестве параметров она получает не какие-нибудь WID или ID, а адрес, где лежит пакет и его длину(пакет кстати перед инжектом функции тоже надо заинжектить, чтобы лежал в адресном пространстве клиента). И сама функция посылки пакета есть на форуме и новый адрес клиентской функции отправки тоже имеется. В первом посте этой же темы есть и инжектор и функция для инжекта, которая отправляет пакет, а в теме адреса и оффсеты есть актуальный адрес вызова.

Meg(0)
14.06.2012, 22:00
Ну а функция отправки пакета у тебя есть?

есть функция отправки пакетов

dwa83, ничего рабочего нету..кроме WALK он вроде работает..но летит персонаж непонятно куда,а всё потому,что у меня не получается полуичть информацию о текущем место положении...когда пытаюсь это сделать постоянно показывает ошибки(

krukovis
14.06.2012, 22:53
ичего рабочего нету..кроме WALK он вроде работает..
Ты же вроде на Delphi пишешь.
Вот готовый инжект на Delphi и исходники ([Ссылки могут видеть только зарегистрированные и активированные пользователи]).

Попробуй переделать его под свои нужды.

Meg(0)
15.06.2012, 01:37
да,я смотрел,пытался....но ничего..в данном случае я не знаю,куда вписывать WID нпс ... ,
вот тут к примеру при нажатии баттона активируется процедура винклоуз, которая тянет за собой win close call и тогда закрывается диалог по офсету нажатия кнопки закрытия диалога 41С
WinClose($41C); //Закрыть окно Торговли и Ремоната.
talktoNPC($438)// поидее открытие диалога с НПС как там написанно...но с каким нпс..(

dwa83
15.06.2012, 01:48
но с каким нпс..(
С нпс у которого WID - $438)) Но это значение - пример, нормальные выглядят как раз вот так
alkToNPC($801045de)

Добавлено через 20 минут
InjectFunc(PId,@TalkToNPCCall,@aParams,1);
Ёшкин-кошкин, что это у вас?
(PId,@TalkToNPCCall,@aParams,1)
Гляньте теперь в оригинал:
InjectFunc(aHandle,@TalkToNPCCall,@aParams,SizeOf( aParams));

Но ведь у нас параметр DWORD, и SizeOf(DWORD) будет 4 а не 1 байт. Не в этом ли проблема?

Meg(0)
15.06.2012, 15:57
исправил,но всё так же ничего не происходит...ведь должен хотя б вылететь клиент если что-то не так? а у меня просто ничего не происходит


procedure InjectFunc(ProcessID: Cardinal; Func, aParams: Pointer;
aParamsSize: DWord);
var
hThread: THandle;
lpNumberOfBytes: DWord;
ThreadAddr, ParamAddr: Pointer;
begin
if ProcessID<>0 then
begin
// ---- Выделяем место в памяти процесса, и записываем туда нашу функцию
ThreadAddr := VirtualAllocEx(ProcessID, nil, 256, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(ProcessID, ThreadAddr, Func, 256, lpNumberOfBytes);

// ---- Также запишем параметры к ней
ParamAddr := VirtualAllocEx(ProcessID, nil, aParamsSize, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(ProcessID, ParamAddr, aParams, aParamsSize, lpNumberOfBytes);

// ---- Создаем поток, в котором все это будет выполняться.
hThread := CreateRemoteThread(ProcessID, nil, 0, ThreadAddr, ParamAddr, 0, lpNumberOfBytes);

// ---- Ожидаем завершения функции
WaitForSingleObject(hThread, INFINITE);

// ---- подчищаем за собой
CloseHandle(hThread);
VirtualFreeEx(ProcessID, ParamAddr, 0, MEM_RELEASE);
VirtualFreeEx(ProcessID, ThreadAddr, 0, MEM_RELEASE);
end;
end;

procedure PacketCall(aPParams:PParams); stdcall;
var
CallAddress,pPacket:pointer;
Len:DWord;
begin
CallAddress:=Pointer($0063DB70); // Старый адрес - $005D7C30
Len:=aPParams^.Param1;
pPacket:=@aPParams^.Packet;
asm
pushad
mov ecx, dword ptr [PW_BASE_ADDRESS]
mov ecx, dword ptr [ecx+$20]
push Len
push pPacket
call CallAddress
popad
end;
end;

procedure TalkToNPCCall(aPParams:PParams);Stdcall;
var NPCID:DWORD;
BaseAddress,CallAddress:Pointer;
begin

NPCID:=aPParams^.Param1;
CallAddress:=ptr($00630B60);
asm
pushad
mov edx, dword ptr [PW_BASE_ADDRESS]
mov ecx, dword ptr [edx+$20]
push NPCID
add ecx, $EC
call CallAddress
popad
end;
end;

procedure TalkToNPC(NPCID:Cardinal);
var aParams:TParams;
v:HWND;
Pid,hProcess:DWord;
begin
v:=FindWindow(nil,Pchar('Perfect World'));
if v <> 0
then
begin
GetWindowThreadProcessId(v,@PId);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS,False,PId );
aParams.Param1:=NPCID;
InjectFunc(hProcess,@TalkToNPCCall,@aParams,4);//пробовал hpocess, pid, хэндл окна...
end;
end;



procedure TForm1.Button6Click(Sender: TObject);
begin
TalkToNPC($801045de);
end;

krukovis
15.06.2012, 18:38
исправил,но всё так же ничего не происходит...ведь должен хотя б вылететь клиент если что-то не так? а у меня просто ничего не происходит
Ничего не происходит - это на самом деле хороший результат. Это говорит о том, что функция правильная, но значения не правильные. Для того, чтобы открыть диалог с NPC его сначала нужно выделить. Определить его WID (по значению TargetWID в структуре персонажа). А затем передать этот параметр в функцию TalkToNPC. И чтобы нам было проще помочь - делать это все нужно в исходниках на которые я давал ссылку. Чтобы кто то, кто понимает в этом, мог открыть реальный проект, отловить баги и сказать где у тебя ошибка.

Meg(0)
16.06.2012, 01:57
вот,сори за неаккуратность,но пытаюсь сделать,что б хоть что-то работало)
[Ссылки могут видеть только зарегистрированные и активированные пользователи]

krukovis
16.06.2012, 11:23
вот,сори за неаккуратность
А код разве не в файлах *.pas хранится? Где они?
И давай пожалуйста все таки аккуратнее. Потому что от того на сколько читаемо и понятно зависит и твое понимание того что ты делаешь и других людей.

Meg(0)
16.06.2012, 14:41
вот.....[Ссылки могут видеть только зарегистрированные и активированные пользователи]

krukovis
16.06.2012, 16:56
вот.....[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Извини, но в твоем коде черт ногу сломит. Ты сам не понимаешь что там, поэтому не можешь отловить баги. Постарайся писать более понятно и каждую строчку комментировать.
Для примера - вот как может выглядеть функция WalkTo: [Ссылки могут видеть только зарегистрированные и активированные пользователи]

Далее, чтобы починить функцию TolkToNPC, тебе нужно написать функцию возвращающую WID цели персонажа. Чтобы передавать результат в функцию TolkToNPC.

NikitaVer
23.06.2012, 13:37
Помогите никак не пойму: В процедуре ( procedure StrToByte(Packet:string; var aParams:TParams); )
Вот строчка >>> aParams.Packet[i]:=strtoint('$'+bytecode[i*2+1]+bytecode[i*2+2]);
В ней мне не ясно откуда взялся bytecode[i*2+1]+bytecode[i*2+2] (с чем он связан?)

BritishColonist
23.06.2012, 15:51
NikitaVer, эта функция переводит строку в массив байтов, причём строка должна быть записана, например, так:
'90EB' .
Цикл бежит по всей строке и берёт по два символа подряд, переводя их в шестнадцатеричные числа. Т.е. берутся два символа, к ним приписывается значок '$' и результат переводится в число.
На первой итерации цикла будет так:
'$' + '9' + '0' -> число $90.
На второй так:
'$' + 'E' + 'B' -> число $EB.

Meg(0)
27.06.2012, 14:53
Для примера - вот как может выглядеть функция WalkTo: [Ссылки могут видеть только зарегистрированные и активированные пользователи]

спасибо за пример,но почему не работает перемещение по Z? (

krukovis
30.06.2012, 22:25
спасибо за пример,но почему не работает перемещение по Z? (

Ну там есть такой параметр как WalkMode - 1 полет, 0 пешком.
В примере используется WalkMode = 0 - пешком.
Так вот нужно активировать полет и поменять WalkMode на 1.

tianddu
01.07.2012, 18:04
а обновленный инжект скила есть у кого а то старый с новыми адресами крашит клиент(

Nobody4all
11.07.2012, 22:01
Может кто помочь с атакой?
в оле код

mov ecx,DWORD PTR DS:[00924E0C]
push 0
push edi // в edi находится npcid
mov edx,DWORD PTR DS:[ECX+1C]
mov ecx,DWORD PTR DS:[EDX+8]
call elementc.*** / адресс функции


собсна пишу по аналогии

P1:=aPParams^.WID; // тут передаю wid моба
addr:=pointer($00429640);
asm
pushad
MOV EDI,P1
MOV ECX,DWORD PTR DS:[$924E0C]
push 0
push EDI
MOV EDX,DWORD PTR DS:[ECX+$1C]
MOV ECX,DWORD PTR DS:[EDX+$8]
CALL addr
popad

где 00924E0C - baseaddr
WID моба смотрю через консоль-> d_npcid, тобиш wid правильный.
С ошибкой не вылетает всё нормально, но не атакует - где я накосячил? пол дня голову ломаю :noemotion:

NikitaVer
12.07.2012, 16:33
Ребят помогите пытаюсь послать пакет на медитацию (пробую с малого) , но т.к. я мало в этом понимаю, то прошу помощи в поиске ошибки . Ситуация такая : сервер на посыл пакета либо никак не отвечает, либо выбрасывает из клиента (второе чаще).
P.S. Форум смотрел и изучал внимательно (и pwlab- тоже). Но ответ на вопрос (Почему клиент вылетает ???) не нашел. rghost.ru/39171222

krukovis
12.07.2012, 18:28
Но ответ на вопрос (Почему клиент вылетает ???) не нашел. rghost.ru/39171222

Клиент вылетает потому, что не может исполнить функцию, которую ты пытаешь в него заинжектить . Поставь брейк-поинты и отследи какие значения грузятся в переменные.

UPD:
Ну а тут рабочий инжект на Delphi и исходники.
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Измени под свою задачу. Лучше переделывать то, что уже работает.
И начни разбираться с комментирования кода.

NikitaVer
12.07.2012, 22:05
Спасибо, буду работать))) Просто затягивает.... Вот уже к инжектам подбираюсь)

vladoscom93
14.07.2012, 17:40
люди вот процедура из этого топика при компиляции дельфин выдает ошибку что неизвестна вот эта штука bytecode что с ней делать
что это за массив где его объявлять
procedure StrToByte(Packet:string; var aParams:TParams);
var
i:integer;
begin
i:=(length(Packet) div 2)-1;
aParams.Param1:=i+1;
for i:=0 to i do
aParams.Packet[i]:=strtoint('$'+bytecode[i*2+1]+bytecode[i*2+2]);
end;

krukovis
14.07.2012, 18:16
люди вот процедура из этого топика при компиляции дельфин выдает ошибку что неизвестна вот эта штука bytecode что с ней делать
что это за массив где его объявлять
procedure StrToByte(Packet:string; var aParams:TParams);
var
i:integer;
begin
i:=(length(Packet) div 2)-1;
aParams.Param1:=i+1;
for i:=0 to i do
aParams.Packet[i]:=strtoint('$'+bytecode[i*2+1]+bytecode[i*2+2]);
end;

А вот же NikitaVer выложил как он объявляет это и использует rghost.ru/39171222
Только у него Packet вместо bytecodeaParams.Packet[i]:=strtoint('$'+Packet[i*2+1]+Packet[i*2+2]);.
Ну а в общем случае - это строка представляющая байт-код пакета. '2E00' например. А эта функция переведет строку в массив байт {0x2E, 0x00}

Perimetr
09.08.2012, 21:32
Подскажите пожалуйста инжектируемый ASM-код движения для версии "Земли Духов"
пробую это - но может, что не так ?

pushad;
mov eax, dword ptr [GameAddress];
mov esi, dword ptr [eax+0x34];
mov ecx, dword ptr [esi+0x10BC];
push 1;
call CallAddress1;
mov edi, eax;
lea eax, dword ptr [esp+0x18]; // ... ???
push eax;
push mode;
mov ecx, edi;
call CallAddress2;
mov ecx, dword ptr [esi+0x10BC];
push 0;
push 1;
push edi;
push 1;
call CallAddress3;
mov eax, dword ptr [GameAddress];
mov eax, dword ptr [eax+0x34];
mov eax, dword ptr [eax+0x10BC];
mov eax, dword ptr [eax+0x30];
mov ecx, dword ptr [eax+0x4];
mov eax, x;
mov dword ptr[ecx+0x20], eax;
mov eax, z;
mov dword ptr[ecx+0x24], eax;
mov eax, y;
mov dword ptr[ecx+0x28], eax;
popad;

VC++6.0

sumikot
09.08.2012, 22:20
У меня так ([Ссылки могут видеть только зарегистрированные и активированные пользователи]), координаты пишутся отдельно. У тебя координаты подставляются после вызовов функций. В принципе разницы нет, только адреса поставь правильно.

NikitaVer
17.08.2012, 16:14
У кого есть пример рабочего инжекта на юзание скилла? Ксиньте плиз.

Perimetr
19.08.2012, 23:18
В XP - инжект и чтение-запись в память работает отлично ..
Хотел узнать - будет-ли работать на 7-ке ?

Dinmaite
19.08.2012, 23:49
Хотел узнать - будет-ли работать на 7-ке ?
Будет.

Perimetr
07.09.2012, 02:58
Может у кого было такое .. бегает по инжекту кода, все правильно, но порой случается, что тупо двигается в какую-то точку типа 0 0 0 - всегда в одну и туже, и в эту-же точку почти всегда пытается двинуться, как-бы дергается в нее и потом бежит правильно ..
Может куда-то еще надо прописать коорды пункта назначения, кроме тех. что пишутся в инжектируемом коде (Asm) и передаются в структуре параметров ?

Timofey123
11.09.2012, 19:56
Подскажите пожалуйста инжект для прыжка для текущей версии Руофф) По форуму искал, сам пытался найти аналогично "Поиск инжектов" или "Наш код в чужом процессе" ([Ссылки могут видеть только зарегистрированные и активированные пользователи]) - но все что нашел не работает :nono:

DHouse
01.10.2012, 00:39
У кого есть рабочий инжект для отправления сообщения через чат игры или иной способ?

АпАпАпчих
05.11.2012, 22:20
У меня так ([Ссылки могут видеть только зарегистрированные и активированные пользователи]), координаты пишутся отдельно. У тебя координаты подставляются после вызовов функций. В принципе разницы нет, только адреса поставь правильно.

pushad
mov edx, BaseAdress
mov ecx, dword ptr [edx]
mov edx, dword ptr [ecx+0x1C]
mov esi, [edx+0x34]
mov ecx, dword ptr [esi+ActionArrOfs]
mov eax, dword ptr [esi+WalkMode]
push 0x01
mov edx, WalkCall1
call edx
mov edi, eax
push Param_add // адрес координат для движения
push fly// 0- пешком, 1- полет, вплавь
mov ecx, edi
mov edx, WalkCall2
call edx
push 0x00
push 0x01
push edi
push 0x01
mov ecx, dword ptr [esi+ActionArrOfs]
mov edx, WalkCall3
call edx
popad
ret

Не могу понять. Param_add // адрес координат для движения, координаты это же 3 переменные, как к сразу трём адрес указать? или тут указатель на массив из трех параметров нужен?

Amineurin
15.11.2012, 15:10
problem solved :)

ktuulx
28.11.2012, 06:52
Подскажите, пожалуйста, код инжекта нажатия клавиши. Не могу найти.
Конкретно интересуют 1-9, F1-F8.

Спасибо.

NikitaVer
28.12.2012, 08:28
Лучше используй вызов самого скилла\действия. Где-то на форуме это есть

krukovis
28.12.2012, 16:52
Подскажите, пожалуйста, код инжекта нажатия клавиши. Не могу найти.
Конкретно интересуют 1-9, F1-F8.
А этого кода в паблик никто не выкладывал никогда.

Savval
11.01.2013, 14:21
А этого кода в паблик никто не выкладывал никогда.
Это вопрос из разряда "Как вы сказали вас зовут?" или "Так где, вы говорите, лежат ключи от сейфа?" =)
А по теме - на элитпвперс выкладывали. Ток надо ручками искать - поиск не помог.

[Kira]
15.01.2013, 16:01
Никто не подскажет как найти адрес в инжекте SellCall? Или придется пакетами продавать?

krukovis
15.01.2013, 16:49
;4062044']Никто не подскажет как найти адрес в инжекте SellCall? Или придется пакетами продавать?

Конечно пакетами. Зачем усложнять себе жизнь?

tianddu
26.01.2013, 16:29
а есть у кого инжект для приватных сообщений?

читтерр
14.02.2013, 21:48
Доброго всем дня.
Подскажите пожалуйста код инжекта на взлет/посадку. В OD нашел единственный вызов функции:

0045BB69 50 PUSH EAX
0045BB6A E8 E1800000 CALL elementc.00463C50

не пойму что за параметр передается.
Заранее признателен.

ПС: в регистре адрес какой-то структуры в стеке, которая загружена задолго до вызова; что за структура - хз(

wajskopf
18.02.2013, 13:07
Нашел несложный код для отправки пакетов на С++, но неработает... Может подскажете как допилить?
Соответственно менял значения 0x60e310 и 0xa5b90c на соответствующие (PackCall = 0x0069F9C0, BA = 0x00b8fbcc)... Клиент не крашит, но прога выдает ошибку.


char buffer[32];
DWORD sendFunction = 0x60e310;
DWORD *base0 = (DWORD *)0xa5b90c;

void SendPacket(char * pkt, int len)
{
DWORD ptr2 = *(DWORD *)(*(DWORD *)0xa5b90c + 0x20);
__asm{
push len
push pkt
mov ecx,ptr2
call sendFunction
}
}

void AttackTarget()
{
const int len = 3;
buffer[0] = 3;
buffer[1] = 0;
buffer[2] = 0;
SendPacket(buffer, len);
}

void DropGold(int amount)
{
int am = amount;
const int len = 6;
buffer[0] = 0x14;
buffer[1] = 0x00;
memcpy(buffer + 2,&am,4);
SendPacket(buffer,len);
}

krukovis
18.02.2013, 15:53
Нашел несложный код для отправки пакетов на С++
Вот исходники бота на плюсах. Может оттуда возьмешь? [Ссылки могут видеть только зарегистрированные и активированные пользователи]

wajskopf
18.02.2013, 20:13
изучаю того бота. Ставит в тупик строчка

char fdata[29]="\x60\x8B\x0D\x00\x00\x00\x00\x8B\x49\x20\x68\x11\x 11\x11\x11\x68\x22\x22\x22\x22\xB8\x33\x33\x33\x33 \xFF\xD0\x61\xC3";

MSVC какбы говорит что должно быть char fdata[30]

Попробовал адаптировать код из того бота:


// Инъекция и отправка пакета

// Структура пакета
struct PACKET
{
int len;
BYTE Bytes[60];
};

BYTE SendPacket(PACKET* pack)
{
HANDLE hProcThread;

char fdata[30]="\x60\x8B\x0D\x00\x00\x00\x00\x8B\x49\x20\x68\x11\x 11\x11\x11\x68\x22\x22\x22\x22\xB8\x33\x33\x33\x33 \xFF\xD0\x61\xC3";
int lenfunc=30;
DWORD func=PackCall;
DWORD ba=BA;
DWORD len=pack->len;

//HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,pid) ;
if (!hProcess){ MessageBoxW(0,L"Not hProcess",0,0); return 0;}

WriteProcessMemory(hProcess,pParam,pack->Bytes,len,NULL);

DWORD addr=DWORD(pParam);
memcpy(fdata+3,&ba,4);
memcpy(fdata+11,&len,4);
memcpy(fdata+16,&addr,4);
memcpy(fdata+21,&func,4);

WriteProcessMemory(hProcess,pFunction,fdata,lenfun c,NULL);

hProcThread = CreateRemoteThread(hProcess,NULL,NULL,(LPTHREAD_ST ART_ROUTINE)pFunction,NULL,NULL,NULL);
if(hProcThread==INVALID_HANDLE_VALUE) // не удалось создать поток
{
//CloseHandle(hProcess);
MessageBoxW(0,L"Not Well",0,0);
return 0;
}

WaitForSingleObject(hProcThread, INFINITE); // ожидаем завершения работы потока
CloseHandle(hProcThread); // освобождаем память
//CloseHandle(hProcess);
MessageBoxW(0,L"Well",0,0);
return 1; // успешная инъекция и выполнение кода
}

//__________________________________________________ ____________________________
// Убрать таргет
void TargetOff()
{
PACKET pack;
pack.len=2;
pack.Bytes[0]='\x08';
pack.Bytes[1]='\x00';
SendPacket(&pack);
}


клиент крашит...

Вроде бы работает...
забыл перед отправкой пакета вот это сделать:

DWORD* pfunc = (DWORD*)VirtualAllocEx(hProcess,NULL,1024,MEM_COMM IT,PAGE_READWRITE);
pFunction = pfunc;
pParam = pfunc+64;


Добавлено через 12 часов 59 минут
Еще вопрос, подскажете пакеты на диалог с нпс? точнее диалог я открываю, а далее мне надо выбрать пункт диалога...

krukovis
19.02.2013, 09:41
Еще вопрос, подскажете пакеты на диалог с нпс? точнее диалог я открываю, а далее мне надо выбрать пункт диалога...
Отлавливайте Пакет Листенером. Каждый квест - отдельный пакет.

wajskopf
20.02.2013, 12:20
За советы спасибо. Во многом продвинулся. Но опять застрял... Для работы с аукционом, например, требуется WID персонажа причем в hex
Подскажите функцию для преобразования WID из DWORD в строку вида:

char playerId [5] = "\x00\x1c\x2с\x3с";

либо

char playerId[4] = {'\x00', '\x1c', '\x2с', '\x3с'};

Заранее спасибо.

krukovis
20.02.2013, 12:56
Подскажите функцию для преобразования WID из DWORD в строку вида:
Здесь обсуждают функции для инжекта, а не методы пребразования. Для этого есть соответсвующая тема или соответствующие форумы.