PDA

Просмотр полной версии : [Скрипт] "Патчер памяти" или "Пишем флайхак" [Delphi]


Dinmaite
05.09.2010, 14:05
Причин к написанию данной темы было три:
1. Меня попросили.
2. Когда-то давно я очень долго искал подобную тему, и не нашел.
3. Флайхаки работают только на фришках.

Итак начнем.
Первым делом опишу какие функции мы будем использовать:

1. FindWindow (модуль Windows)
function FindWindow(lpClassName, lpWindowName: PChar): HWND; stdcall;
lpClassName - Имя класса окна (для PW - ElementClient Window)
lpWindowName - Текст заголовка окна (для PW - Element Client, для офа ПВ - Perfect World)
С помощью этой функции мы получим дескриптор (handle) окна.

2. GetWindowThreadProcessId (модуль Windows)
function GetWindowThreadProcessId(hWnd: HWND; lpdwProcessId: Pointer = nil): DWORD; stdcall; overload;
hWnd - дескриптор окна.
lpdwProcessId - указатель на переменную типа Dword, после использования функции в него скопируется идентификатор потока создавшего окно.
От этой функции нам нужен идентификатор потока (PID).

3. OpenProcess (модуль Windows)
function OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; stdcall;
dwDesiredAccess - Устанавливает права доступа к объекту (мы будем получать полные права доступа PROCESS_ALL_ACCESS)
bInheritHandle - Параметр дескриптора наследования.
dwProcessId - идентификатор потока.
С помощью этой функции мы получим права доступа к памяти объекта, и идинтификатор объекта.
После окончания работы с идентификатором объекта необходимо закрыть его функцией CloseHandle.

4. ReadProcessMemory (модуль Windows)
function ReadProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer;
nSize: DWORD; var lpNumberOfBytesRead: DWORD): BOOL; stdcall;
hProcess - Идентификатор объекта
lpBaseAddress - указатель на адрес из которого будем читать
lpBuffer - указатель на переменную-буфер, в которую будем читать значение из памяти.
nSize - количество байт, которое мы хотим прочитать.
lpNumberOfBytesRead - переменная-буфер, в которой устанавливается значение соответствующее количеству прочитанных байт.
С помощью этой функции мы будем "подбираться" к нужному нам адресу.

5. WriteProcessMemory (модуль Windows)
function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer;
nSize: DWORD; var lpNumberOfBytesWritten: DWORD): BOOL; stdcall;
hProcess - Идентификатор объекта
lpBaseAddress - указатель на адрес в который будем писать
lpBuffer - указатель на переменную-буфер, значение которой будем записывать в память.
nSize - количество байт, которое мы запишем в память
lpNumberOfBytesRead - переменная-буфер, в которой устанавливается значение соответствующее количеству записанных байт.

Теперь немного о структуре памяти Perfect World.
На жуке и иных порталах много говорят о оффсетах, но не все понимают что же это за зверь.
Оффсет это смещение относительно некоего адреса памяти.

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

На скриншоте все что выше красной стрелки - отрицательные смещения, все что ниже - положительные.

К примеру у нас есть базовый адрес игры Perfect World - $009C0E6C и есть смещение $1C.
Запись вида [ba]+$1C значит что нужно прочесть значение лежащее по адресу $009C0E6C и прибавить к нему $1C, таким образом мы получим адрес начала блока игровой сессии, который по незнанию называют базовым адресом (более приемлимое (и принятое) название base pointer - базовый указатель) и используют в PWGtm (то есть можно сказать что [ba]+$1C=bp).
Запись вида [ba]+$1C+$20 значи что нам нужно прочесть значение лежащее по базовому адресу, прибавить к нему $1C, и получить базовый указатель, затем прочитать значение лежащее по адресу базового указателя и прибавить к нему $20. Таким образом мы получим указатель на начало структуры данных о персонаже.
$668 - смещение адреса в памяти отвечающего за полет (на самом деле в по этому адресу находится битовая структура с флагами состояния персонажа, но для простоты мы будем работать с целым байтом), относительно начала структуры данных о персонаже. Путь [ba]+$1C+$20+$668 приведет нас к нему.

Итак надеюсь все понятно, начнем кодить :)
Для начала бросим на форму две кнопки, и назовем их ВКЛ и ВЫКЛ

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

Переключимся на редактор кода и напишем процедурку:

procedure FlyHack(state:bool);
const
base_addr=$009C0E6C;
fly_offset=$668;
var
WndHndl:THandle;
buf:byte;
ipbuf,PID,hProcess,BytesCount:dword;
begin
WndHndl:=findwindow('ElementClient Window',nil);
GetWindowThreadProcessId(WndHndl, @PID);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, PID);
if hProcess <> 0 then // Проверяем получен ли идентификатор объекта
try
ReadProcessMemory(hProcess, ptr(base_addr), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$1C), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$20), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+fly_offset), @buf, sizeof(buf), BytesCount);
if (buf<>$0) and (buf<>$10) then
messagebox(0,'Неверная версия клиента','Пишем флайхак',16)
else
begin
if state=true then // Если нажали "ВКЛ"
begin
buf:=$10;
writeprocessmemory(hProcess,ptr(ipbuf+fly_offset), @buf,1,BytesCount);
messagebox(0,'Клиент пропатчен','Пишем флайхак,64);
end;
if state=false then // Если нажали "ВЫКЛ"
begin
buf:=$0;
writeprocessmemory(hProcess,ptr(ipbuf+fly_offset), @buf,1,BytesCount);
messagebox(0,'Клиент пропатчен','Пишем флайхак',64);
end;
end;
finally
closehandle(hProcess);
end;
end;


Теперь в обработчики событий OnClick наших кнопок запишем:
для "ВКЛ" - FlyHack(true);
для "Выкл" - FlyHack(false);

Вуаля, флайхак готов.

В аттаче исходник проекта.

jdark
06.09.2010, 11:59
а не подскажите делаю тоже самое но для джампа, смещение у него
+BF4 Jumping

заменил fly_offset=$BF4;
buf 10 на 1, и не работает зараза

Dinmaite
06.09.2010, 12:02
Если и подскажу, то не в этой теме.

Mazzahaka777
07.09.2010, 13:58
Вопрос:как юзать хекс\dec оффсеты Оо

Dinmaite
07.09.2010, 14:04
Вопрос не ясен, расскажи хотя бы где ты их собираешься юзать и для чего.

Mazzahaka777
07.09.2010, 14:14
Собсно для извлечения инфы из процесса(левел бла бла и тд).откуда ?offset retriever by noob
Или это не те оффсеты ?х)

Dinmaite
07.09.2010, 14:36
Да я как-то вот не могу понять что конкретно ты хочешь спросить.
Для извлечения инфы нужно читать байты по смещениям указанным в той теме.

Mazzahaka777
07.09.2010, 14:41
Ну так ведь нужно знать оффсеты что бы прочитать из памяти так вот я хочу узнать как из (оффсет левела из offsetretriever клиент 1.3.4) 00000448 сделать (пример)$009C0E6C.

AEBus
07.09.2010, 18:01
Тебе поможет инженерный калькулятор, точнее обычный calc.exe аоторый встроен в windows но вид его поменян на инженерный


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

Sergiuz
10.09.2010, 13:40
Практически понятно
т.е. для получение к примеру уровня мы используем код:

ReadProcessMemory(hProcess, ptr(base_addr), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$1C), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$20), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$464), @buf, sizeof(buf), BytesCount);

и обрабатываем переменную buf.
У меня не возникло проблем с числовыми значениями.
А вот когда использую оффсет имя персонажа $608 и перевожу процедурой inttostr (buf) он мне дает значение типа 7046586 . Так вот вопрос как получить имя персонажа?
Если не трудно подскажи ;)

Kitsune
10.09.2010, 13:49
Sergiuz, имя персонажа это не число, а строка. Я хоть и не знаю делфи, но что-то мне подсказывает, что inttostr - это перевод числа в строку.

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


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
// ~~~ Procedure to get UNICODE STRING from memory
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
function TaPWT.getSTRING(aProcessID, aPointer: Cardinal; length: integer): WideString;
var
dwReaded: DWORD;
buf16: array [0 .. 16] of WideChar;
buf32: array [0 .. 32] of WideChar;
buf64: array [0 .. 64] of WideChar;
begin
if length = 16 then
begin
ReadProcessMemory(aProcessID, ptr(aPointer), @buf16, length, dwReaded);
Result := buf16;
end;
if length = 32 then
begin
ReadProcessMemory(aProcessID, ptr(aPointer), @buf32, length, dwReaded);
Result := buf32;
end;
if length = 64 then
begin
ReadProcessMemory(aProcessID, ptr(aPointer), @buf64, length, dwReaded);
Result := buf64;
end;
end;

Sergiuz
10.09.2010, 14:34
TBX1n, спасибо
Но теперь возникла еще одна проблема по оффсету с именем персонажа выдает китайский иероглиф.
П.С. убрал смещение $20, то с использование оффсета $608 получаю сообщение
"Золотой карп бессмертный. Вы не можете его поймать если не заслуживаете этого" Ну это так лирическое отступление.

Dinmaite
10.09.2010, 14:53
потому что оффсет имени [ba]+$1C+$20+$608+$0

НЕТилиДа
10.09.2010, 17:08
Я не понимаю зачем писать флайхак если его можно щас скачать.
Ведь сервак всеравно откидывать будет

Nitrosgen
10.09.2010, 17:21
НЕТилиДА, это просто руководство, для тех, кто хочет разобраться в клиенте пв, для тех, кто хочет научиться писать программы под него но не знает что и как
оно показывает пример программирования на делфи

НЕТилиДа
10.09.2010, 17:48
НЕТилиДА, это просто руководство, для тех, кто хочет разобраться в клиенте пв, для тех, кто хочет научиться писать программы под него но не знает что и как
оно показывает пример программирования на делфи

Аааа ясно :d
Но тогда еще один вопрос, кто играет на малазийском или американсом.
Есть ли там флайхак или нет ? Просто интересно, смогли ли обойти эту защиту

Dinmaite
10.09.2010, 17:50
Специально для НЕТилиДА:
На Интернациональном нет, китайский я не знаю.

Через часок почищу тему.

Sergiuz
10.09.2010, 17:57
потому что оффсет имени [ba]+$1C+$20+$608+$0

Результат пустая строка :sad:

Dinmaite
10.09.2010, 18:04
Напиши сюда базовый адрес, который используешь.

Sergiuz
10.09.2010, 18:07
Напиши сюда базовый адрес, который используешь.

тот который у тебя в примере: $009C0E6C

Dinmaite
10.09.2010, 18:18
В аттаче таблица для CE, в ней указанный мною путь к адресу ника.
Ник читается. А раз ник читается, значит что-то ты неверно делаешь.

Sin Aiko
12.09.2010, 00:01
В аттаче таблица для CE
А что за программа CE и где её скачать? Простите за нубство.

Dinmaite
12.09.2010, 00:19
А что за программа CE и где её скачать? Простите за нубство.

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

Sergiuz
12.09.2010, 13:12
В аттаче таблица для CE, в ней указанный мною путь к адресу ника.
Ник читается. А раз ник читается, значит что-то ты неверно делаешь.

В СЕ все проходит на Ура. Когда пытаюсь отобразить через программу получаю вот это:
[Ссылки могут видеть только зарегистрированные и активированные пользователи]

Сам код:
procedure TForm2.Button1Click(Sender: TObject);
var
buft:array [0..16] of WideChar;
buf:byte;
ipbuf: dword;
s: string;
begin
WndHndl:=findwindow('ElementClient Window',nil);
GetWindowThreadProcessId(WndHndl, @PID);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, PID);
if hProcess <> 0 then
begin

Memo1.Lines.clear;

ReadProcessMemory(hProcess, ptr(BaseCall_Address), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$1C), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$20), @ipbuf, sizeof(ipbuf), BytesCount);

ReadProcessMemory(hProcess, ptr(ipbuf+Lvl_offset), @buf, sizeof(buf), BytesCount);
Memo1.Lines.Add('LVL: '+inttostr(buf));


ReadProcessMemory(hProcess, ptr(ipbuf+DEX_offset), @buf, sizeof(buf), BytesCount);
Memo1.Lines.Add('DEX: '+inttostr(buf));


ReadProcessMemory(hProcess, ptr(ipbuf+MAG_offset), @buf, sizeof(buf), BytesCount);
Memo1.Lines.Add('Mag: '+inttostr(buf));

ReadProcessMemory(hProcess, ptr(ipbuf+MAxHP_offset), @buf, sizeof(buf), BytesCount);
Memo1.Lines.Add('MaxHP: '+inttostr(buf));

ReadProcessMemory(hProcess, ptr(ipbuf+Name_offset+$0), @buft, 16, BytesCount);
s:=WideCharToString(buft);
Memo1.Lines.Add('Name: '+buft+' - '+s);

end
else showmessage ('not login');
end;

Оффсеты забиты константами
const
Unfreeze_Address=$9C1984;
Base_Address=$9C1514;
BaseCall_Address=$009C0E6C;
Pet_Offset=$FF8;
Jump_Offset=$BF4;
CastID_Offset=$6C4;
State_Offset=$668;
Class_Offset=$610;
Name_Offset=$608;
CHI_Offset=$53C;
MaxCHI_Offset=$524;
MaxMP_OffSet=$4A8;
MaxHP_Offset=$4A4;
DEX_Offset=$4A0;
STR_Offset=$49C;
MAG_Offset=$498;
VIT_Offset=$494;
Spirit_Offset=$478;
EXP_Offset=$474;
MP_Offset=$470;
HP_Offset=$46C;
Culti_Offset=$468;
LVL_Offset=$464;
CharID_Offset=$458;
TargetID_Offset=$384;
Fly_Offset=$668;

Теперь самое интересное:
СЕ ХП и Имя персонажа отображает правильно:
[Ссылки могут видеть только зарегистрированные и активированные пользователи]

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

Где я ошибся???

П.С.: Юзаю Delphi 2010+Windows 7
Проверить на других тачках нет возможности (

Dinmaite
12.09.2010, 19:51
ReadProcessMemory(hProcess, ptr(ipbuf+Name_offset+$0), @buft, 16, BytesCount);

Тут в пору ставить /facepalm :)
ты везде читал структуры +n+n по очереди, а почему тут решил сразу?
Верный код
ReadProcessMemory(hProcess, ptr(ipbuf+Name_offset), @ipbuf, 4, BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+0), @buft, 32, BytesCount);
Важно!! именно 32, так как строки в формате юникод, а 1 символ юникода занимает 2 байта.

Corel
25.09.2010, 07:48
Аналогичная проблема - в СЕ всепоказывается верно, программа же показывает непонятное значение хп, мп и экспы. Еще не получилось пихнуть туда же антифриз(

procedure TForm1.Button1Click(Sender: TObject);
var
buf:byte;
WndHndl:THandle;
ipbuf,PID,hProcess,BytesCount:dword;
begin
buf:=1;
writeprocessmemory(hProcess,ptr($9C1984),@buf,1,By tesCount);
end;

ReadProcessMemory(hProcess, ptr(BaseCall_Address), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$1C), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$20), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+MaxHP_offset), @buf, sizeof(buf), BytesCount);
maxhp:=inttostr(buf);
ReadProcessMemory(hProcess, ptr(ipbuf+HP_offset), @buf, sizeof(buf), BytesCount);
hp:=inttostr(buf);
hplab.Caption:=hp+'/'+maxhp;
ReadProcessMemory(hProcess, ptr(ipbuf+Maxmp_offset), @buf, sizeof(buf), BytesCount);
maxmp:=inttostr(buf);
ReadProcessMemory(hProcess, ptr(ipbuf+mp_offset), @buf, sizeof(buf), BytesCount);
mp:=inttostr(buf);
mplab.Caption:=mp+'/'+maxmp;
ReadProcessMemory(hProcess, ptr(ipbuf+exp_offset), @buf, sizeof(buf), BytesCount);
explab.Caption:=inttostr(buf);
В чем загвостка то?

UPD. На начальных уровнях никаких трабл не возникает все отлично работает, но на более менее высоких начинается бред. из 2013 показывает 235 причем снимаю шлем +35 хп становится 1978 а в проге 200. :omg: И если не секрет как заставить компонент sendkeys нажимать на клавиши в окне? Помогите нубу:bow:

Dinmaite
25.09.2010, 19:23
По первому коду - таким образом как ты это делаешь, нужно постоянно записывать 1 в этот адрес, а не 1 раз.
По второму коду - вероятно ты используешь переменную размером в 1 байт.

Corel
26.09.2010, 09:01
Действительно, проблема была в этом.
Но чем глубже в лес тем больше дров
procedure TForm1.Button1Click(Sender: TObject);
begin
SendKeys1.GetWindowHandle('Perfect World');
if SendKeys1.WindowHandle <> 0 then
SendKeys1.SendKeys('2');
end;
При нажатии никаких действий, но если установить таргет на чат в игре, то тогда при нажатии на батон1 замечательно печатает 2ки в чате:eek:
И еще неполучилось найти в памяти хп цели (и ее название):omg: Как искать то? (значения хп пета тоже найти неполучилось( )

UPD как получили это значение TargetID_Offset=$384 ? выдает в СЕ в значении вопросы.

Dinmaite
26.09.2010, 09:49
Это все так забавно :)
Начнем с простого
Target_offset:=$AF8; Где вы взяли $384?

А по поводу кода - окно ПВ с последнего обновления принимает нажатия клавиш только в активном (и размороженном) виде.
А в случае с вашим компонентом вообще только в активном окне, используйте лучше
sendmessage или postmessage.

Corel
26.09.2010, 15:54
Офсеты взял из поста Sergiuz'а.
Интересная тема, разбудила желание снова установить дельфи, но к сожалению то с чем сейчас сталкиваюсь на парах не проходили, поэтому будет море вопросов, надеюсь на достану...
Пойду косячить дальше =)

war2lock
26.09.2010, 19:24
И еще неполучилось найти в памяти хп цели (и ее название):omg: Как искать то? (значения хп пета тоже найти неполучилось( )


подскажите как найти параметры цели в таргете (хп, уровень и др. если это возможно)

зы. когдато на глаза попадалась программа pwmacros она показывала много интересного про выбраную цель ;)

ЗЫЫ. да, подскажите есть ли возможность работать с чатом напрямую (записывая читая из памяти)

AEBus
26.09.2010, 19:44
подскажите как найти параметры цели в таргете (хп, уровень и др. если это возможно)

зы. когдато на глаза попадалась программа pwmacros она показывала много интересного про выбраную цель ;)

PW Enemy Info ([Ссылки могут видеть только зарегистрированные и активированные пользователи]) думаю подойдет

Corel
27.09.2010, 04:41
ЗЫЫ. да, подскажите есть ли возможность работать с чатом напрямую (записывая читая из памяти)
Хотел бы я знать как это сделать, видимо можно поскольку на форуме выложена программа для логирования чата. Пытался найти инфу о хп моба, но как привязать ее к ВА не понял, при попытках нати сдвиг относительно ВА клиент вылетает нафиг (
И если не затруднит подскажите строки с сендмессадж, мои эксперементы с поиском хэндела окна окончились провалом(

PW Enemy Info думаю подойдет
Выкладывали бы такие програмы с исходниками, для нас нубов - цены бы небыло.

war2lock
27.09.2010, 08:57
PW Enemy Info ([Ссылки могут видеть только зарегистрированные и активированные пользователи]) думаю подойдет

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

Kvant_VS
29.09.2010, 20:10
подскажите как найти параметры цели в таргете (хп, уровень и др. если это возможно)

Сначала ищешь адрес цели (всей структуры то бишь):
перебираешь в цикле от 0 до $300 адреса
[BA] + $1C + 8 + $24 + $18 + [J*4] + 4 -- TargetAdr (Адрес цели, если цель - НИП/моб)
[BA] + $1C + 8 + $20 + $18 + [J*4] + 4 -- TargetAdr (Адрес цели, если цель - перс)

[TargetAdr+$11c] -- WID.
Если WID = WID выбранной цели, то значит мы нашли адрес именно нашего моба/нипа.
[TargetAdr +$124] -> уровень
[TargetAdr +$24c] +0 -> название
[TargetAdr +$24c] -8] -> длина названия
[TargetAdr +$12c] -> HP

Если цель - персонаж, то смещения [TargetAdr + ...] другие. Они такие же как у своего перса

war2lock
01.10.2010, 06:21
извениете сутки ковыряюсь, чет вообще затупил подскажите, что йа телаю неправильно

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


procedure user_name;
var i:integer;
adress_pst:cardinal;
s:string;
begin
label.Caption:='';
Name_Offset = 1544;
Base_Address:=10227308;
for i:=0 to 768 do begin
adress_pst:=strtoint(Readmem(Base_Address,HWNDgame ,4));
adress_pst:=strtoint(Readmem(adress_pst+$1c,HWNDga me,4));
adress_pst:=strtoint(Readmem(adress_pst+8,HWNDgame ,4));
adress_pst:=strtoint(Readmem(adress_pst+$20,HWNDga me,4));
adress_pst:=strtoint(Readmem(adress_pst+$18,HWNDga me,4));
adress_pst:=strtoint(Readmem(adress_pst+(i*4),HWND game,4));
adress_pst:=strtoint(Readmem(adress_pst+4,HWNDgame ,4));
s:=getSTRmem(strtoint(Readmem(adress_pst+Name_Offs et ,HWNDgame,4)) ,HWNDgame,32);
label.Caption:=label.Caption+s+' ';
end;


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

ЗЫ. подправил, вот так работает ))), осталось отделить настоящих персов, т.к. они раскиданы по всему массиву

Kvant_VS
01.10.2010, 19:37
осталось отделить настоящих персов, т.к. они раскиданы по всему массиву
после строчки
"adress_pst:=strtoint(Readmem(adress_pst+(i*4),HWND game,4));"
сделай проверку
if adress_pst<>0 then begin

war2lock
04.10.2010, 09:56
подскажите пжалста еще, если несложно ))
1. адрес смещения цели 2808, если туда записать идентификатор песонажа, то таргет появляется, но стукнуть по таргету нельзя, вообще непойму куда копать (
2. читаю из адресов $3C $40 $44 местоположение персонажа высота определяется правильное значение умноженое на 10, а вот х и у какято белеберда то 1500 вместо 500, то 7 вместо 400

Kitsune
04.10.2010, 10:01
war2lock,
1. В сторону FullTarget Inject'а :)
2.
(X + 4000) / 10 = Игровой Х
(Z + 5500) / 10 = Игровой Z
(Y / 10) = Игровой Y

Dinmaite
04.10.2010, 10:03
подскажите пжалста еще, если несложно ))
1. адрес смещения цели 2808, если туда записать идентификатор песонажа, то таргет появляется, но стукнуть по таргету нельзя, вообще непойму куда копать (
2. читаю из адресов $3C $40 $44 местоположение персонажа высота определяется правильное значение умноженое на 10, а вот х и у какято белеберда то 1500 вместо 500, то 7 вместо 400

1 - Нужно верно заносить id персонажа, а именно инжектом. (код не скажу, потому как под руоф не работаю по части ботов)
2 - высота определяется как ([bp]+$20+$44)/10, координата x и у так же требуют дополнительного расчета.

war2lock
05.10.2010, 15:20
извениете сутки ковыряюсь, чет вообще затупил подскажите, что йа телаю неправильно

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


procedure user_name;
var i:integer;
adress_pst:cardinal;
s:string;
begin
label.Caption:='';
Name_Offset = 1544;
Base_Address:=10227308;
for i:=0 to 768 do begin
adress_pst:=strtoint(Readmem(Base_Address,HWNDgame ,4));
adress_pst:=strtoint(Readmem(adress_pst+$1c,HWNDga me,4));
adress_pst:=strtoint(Readmem(adress_pst+8,HWNDgame ,4));
adress_pst:=strtoint(Readmem(adress_pst+$20,HWNDga me,4));
adress_pst:=strtoint(Readmem(adress_pst+$18,HWNDga me,4));
adress_pst:=strtoint(Readmem(adress_pst+(i*4),HWND game,4));
adress_pst:=strtoint(Readmem(adress_pst+4,HWNDgame ,4));
s:=getSTRmem(strtoint(Readmem(adress_pst+Name_Offs et ,HWNDgame,4)) ,HWNDgame,32);
label.Caption:=label.Caption+s+' ';
end;


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

ЗЫ. подправил, вот так работает ))), осталось отделить настоящих персов, т.к. они раскиданы по всему массиву

:nono: данная процедура находит не всех персонажей :nono:

Dinmaite
05.10.2010, 15:26
:nono: данная процедура находит не всех персонажей :nono:

Потому что персонажи могут быть не только на первом листе памяти.
Дабы не описывать все это дело самом, обращусь к описанию GrieVeR-13.


GA +8 +20 +18 +[I*4] + (+0)^J +4: Players Struct (I in [0..300])
....
....
Запись BA +218 +8 +[I*4] + (+0)^J +4 для разных значений J расшифровывается как:
J = 0: BA +218 +8 +[I*4] +4
J = 1: BA +218 +8 +[I*4] +0 +4
J = 2: BA +218 +8 +[I*4] +0 +0 +4
J = 3: BA +218 +8 +[I*4] +0 +0 +0 +4
J = 4: BA +218 +8 +[I*4] +0 +0 +0 +0 +4
J = 5: ...
Продолжать, пока не будут найдены все элементы. Элементы неравномерно распределены по всему массиву. Количество элементов можно посмотреть по адресу, указанному в первой строке описания каждой структуры.

war2lock
06.10.2010, 10:49
встречный вопрос: как узнать чему равно J ? перебрал 10 страниц все значения пустые (

Kitsune
06.10.2010, 11:02
war2lock, J от 0 до бесконечности, пока не найдешь все записи. Обычно J больше 4х не бывает.

И мне кажется вы не так поняли смысл перебора с J.
J - это кол-во дополнительных сдвигов в памяти.

Если J == 0, то выглядит так
J = 0: BA +218 +8 +[I*4] +4

Если J == 1, то выглядит так
J = 1: BA +218 +8 +[I*4] +0 +4

Если J == 2, то выглядит так
J = 1: BA +218 +8 +[I*4] +0 +0 +4

и т.д.

war2lock
07.10.2010, 10:46
разобрался спс, вроде с первого взгляда работает ), терь ещеб понять как валхак сделать

Dinmaite
07.10.2010, 19:31
Очень просто - пиши в ячейки координат персонажа свои значения, но не слишком отдаленные от текущих (так в PWGtm, как сделано в ревоботе не знаю).

Kvant_VS
08.10.2010, 01:21
я бы даже не додумался делать так, думая, что это ничего не даст)

war2lock
08.10.2010, 14:25
Очень просто - пиши в ячейки координат персонажа свои значения, но не слишком отдаленные от текущих (так в PWGtm, как сделано в ревоботе не знаю).

двигается только камера :nono:
смещения
$3С
$40
$44
, а как подвинуть персонажа?

Kitsune
08.10.2010, 14:46
war2lock, шевельнутся персонажем :)

С обычным ВХ всегда зажимали пробел/z или любое движение wasd

Sanych89
18.10.2010, 02:42
хм. загорелся идеей сделать что-нибудь волхакообразное, но как-то в стенку упёрся (в переносном смысле). относительно чего берутся смещения $3С, $40, $44?

Kitsune
18.10.2010, 10:24
Sanych89, BA + $1C + ($3С или $40 или $44)

Sanych89
18.10.2010, 19:00
всё равно какая-то беда.
ReadProcessMemory(hProcess, ptr(base_addr), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$1C), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+x_offset), @x, sizeof(x), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+y_offset), @y, sizeof(y), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+z_offset), @z, sizeof(z), BytesCount);
в качестве констант
base_addr=$009C0E6C;
x_offset=$3c;
y_offset=$40;
z_offset=$44;

когда добавлял
ReadProcessMemory(hProcess, ptr(ipbuf+$20), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+hp_offset), @hp, sizeof(hp), BytesCount);
то hp успешно записывал. типы данных проверял byte, word, integer.
где я накосячил?)

Dinmaite
18.10.2010, 19:48
[ba]+$1C+$20+$3C
остальные аналогично.

Sanych89
18.10.2010, 20:07
с этого и начинал. не то оО

Kitsune
18.10.2010, 20:10
Sanych89, это то, просто вы пишете "гoвнокод", если не работает.

1. Читаем значение памяти по адресу BA в переменную N
2. Читаем значение памяти по адресу (N+$1С) и записываем в N (это GameRun)
3. Читаем значение памяти по адресу (N+$20) и записываем в N (это адрес началы структуры игрока в памяти)
4. Читаем значение памяти по адресу (N+$3C) и записываем в X (это наш X)
4. Читаем значение памяти по адресу (N+$40) и записываем в Y (это наш Y)
4. Читаем значение памяти по адресу (N+$44) и записываем в Z (это наш Z)

Sanych89
18.10.2010, 20:29
хм. *****кодом это я не называю. и искренне недоумеваю, почему не работает:
procedure koord;
const
base_addr=$009C0E6C;
hp_offset=1132;
x_offset=$3C;
y_offset=$40;
z_offset=$44;

var
WndHndl:THandle;
hp:integer;
ipbuf,PID,hProcess,BytesCount:dword;
x,y,z : word;
begin
WndHndl:=findwindow('ElementClient Window',nil);
GetWindowThreadProcessId(WndHndl, @PID);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, PID);

if hProcess <> 0 then // Проверяем получили ли мы идентификатор объекта
try
ReadProcessMemory(hProcess, ptr(base_addr), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$1C), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$20), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+x_offset), @x, sizeof(x), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+hp_offset), @hp, sizeof(hp), BytesCount);
showmessage(inttostr(x));
showmessage(inttostr(hp));
finally
closehandle(hProcess);
end;
end;
hp показывает успешно, вместо координат - что-то не то. пробовал менять тип данных на integer, byte, shortint. да, я читал на предыдущей странице, что
(X + 4000) / 10 = Игровой Х
(Z + 5500) / 10 = Игровой Z
(Y / 10) = Игровой Y

Dinmaite
18.10.2010, 20:32
А надо не только читать но и задумываться над тем что читаешь)

Это преобразование не верное.

Верно так

(X + 4000) / 10 = Игровой Х
(Y + 5500) / 10 = Игровой Y
(Z / 10) = Игровой Z

Мало того

const
base_addr=$009C0E6C;
hp_offset=1132;
x_offset=$3C;
z_offset=$40;
y_offset=$44;

Sanych89
18.10.2010, 20:38
хорошо, с y и z понял, но на них ещё не смотрел.
сейчас всё равно работаю только с x - и как-то не выходит.

Dinmaite
18.10.2010, 20:41
Переменные должны соответствовать читаемуму типу. Координаты - значение с плавающей запятой...

Sanych89
18.10.2010, 22:41
да, спасибо. с single заработало.
но теперь столкнулся с проблемой, с которой стокнулся Kvant_VS. попрыгать - не помогает. сдвигаться пытался даже на 0.01.
основная проблема вновь в днк?)

Dinmaite
19.10.2010, 00:04
Я не совсем понимаю что ты имеешь ввиду.

Sanych89
19.10.2010, 00:26
изменяю координату по х. пробовал сдвигать по 0.01. двигается только камера. если после этого прыгнуть, или ещё что - возвращаюсь на исходное место.

Dinmaite
19.10.2010, 10:18
А ты покажи код КАК ты двигаешь. Кроме того, визуально джампхак и похож на перемещение камеры.

Sanych89
19.10.2010, 11:26
procedure movex;
const
base_addr=$009C0E6C;
x_offset=$3C;
y_offset=$44;
z_offset=$40;
dx = 0.01;
var
WndHndl:THandle;
ipbuf,PID,hProcess,BytesCount:dword;
x,y,z : Single;
begin
WndHndl:=findwindow('ElementClient Window',nil);
GetWindowThreadProcessId(WndHndl, @PID);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, PID);

if hProcess <> 0 then
try
ReadProcessMemory(hProcess, ptr(base_addr), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$1C), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$20), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+x_offset), @x, sizeof(x), BytesCount);
x := x + dx;
writeprocessmemory(hProcess,ptr(ipbuf+x_offset),@x ,sizeof(x),BytesCount);
finally
closehandle(hProcess);
end;
end;

Kitsune
19.10.2010, 11:54
Sanych89,
Может стоит попробовать прибавлять 1.0 хотябы? Коориданты мира PW имеют вид примерно такой: 1657.763.

Прибавляя 0.01 вы врядли сдвинитесь с места.

Sanych89
19.10.2010, 13:58
пробовал - всё равно двигается только камера. при сдвиге на 0.01 - небольшое смещение камеры имеется. но персонаж в любом случае остаётся на месте.

Kitsune
19.10.2010, 14:06
Sanych89, так и должно быть... Тему может стоит почитать с 1ой страницы?

Sanych89
19.10.2010, 14:50
пересмотрел, начиная с первой страницы. ты про то, что на оффе откидывает, когда находишься высоко от уровня земли? проблема связана не с этим.

Virial
02.11.2010, 12:54
Тоже решил приобщиться к созданию сканеров и патчеров.
Расковырял устройство чата, по нубству потратив на это дело два часа, хотя там всё до крайности просто, и даже адреса все статические. Если кому надо, могу выложить описание.
Думаю теперь создать чат-логгер, который будет скидывать всю болтовню в файл, предварительно отфильтровав по определённому шаблону (например, записывать только сообщения, содержащие подстроки "прод" и "купл" или все посты от человека с нужным ником)...
Вообще, у меня сложилось впечатление, что PW - крайне дружественная среда для начинающего ботмейкера: не ругается, не палит, спокойно поддаётся сканированию, запускается в окне. Даже не представляю, как ковыряют к примеру Aion, где Фрост каждый чих палит, не говоря уж о том, чтоб запустить нечто вроде CE и переключаться туда-сюда.

Kitsune
02.11.2010, 13:13
PW Chat Logger ([Ссылки могут видеть только зарегистрированные и активированные пользователи])

Virial
02.11.2010, 13:19
Это-то понятно, но охота ведь самому разобраться, прежде чем переходить к более сложным вещам. Например, что-то мне подсказывает, что аук так просто не дастся, и какой-нибудь автоперебивальщик ставок придётся делать очень долго.
Ну и, наконец, у самопальных программ есть важное преимущество: тут уж 100% уверенность, что они не содержат скрытых хаков и встроенных кейлоггеров.

777gamer777
06.11.2010, 18:30
Чет я не понял:
1)откуда упало $1C,$20
2) И вообще, как определять оффсеты?

Kitsune
06.11.2010, 18:34
777gamer777,
1. из памяти клиента
2. почитайте статью [Ссылки могут видеть только зарегистрированные и активированные пользователи] и поймете как оффсеты находят.

777gamer777
06.11.2010, 21:10
Попробывал поковырять координаты, но двигается только камера, возможно ли как-то заставить двигаться перса (как например в боте или в гео боте)

Kitsune
06.11.2010, 21:32
777gamer777, на одном изменении памяти далеко не уедешь. Для всего "цивильного" нужны инжекты, если делать ингейм бота.

777gamer777
06.11.2010, 21:38
TBX1n, injection?

Kitsune
06.11.2010, 21:55
777gamer777, да.

777gamer777
07.11.2010, 15:38
J - это кол-во дополнительных сдвигов в памяти.

Если J == 0, то выглядит так
J = 0: BA +218 +8 +[I*4] +4

Если J == 1, то выглядит так
J = 1: BA +218 +8 +[I*4] +0 +4

Если J == 2, то выглядит так
J = 1: BA +218 +8 +[I*4] +0 +0 +4

и т.д.
Объясните плиз, что здесь I

Kitsune
07.11.2010, 15:45
777gamer777, I от 0 до 795.

777gamer777
07.11.2010, 15:50
TBX1n, спс), а J от 0 до 4?

Kitsune
07.11.2010, 16:15
777gamer777, от 0 до бесконечности. Пока не найдешь все элементы структуры.

777gamer777
07.11.2010, 16:42
TBX1n, я так понял эти значения мобов или игроков вокруг?

Kitsune
07.11.2010, 16:46
777gamer777, какие значения?
Лучше объясните целиком, что вы хотите сделать, а то мы не экстрасенсы и читать ваши мысли не можем.

777gamer777
07.11.2010, 17:31
TBX1n, Я хочу написать простенького бота (решил попробывать свои силы), который будет бить мобов, собирать лут, пить банки. С лутом и банками ясно, таргет мобов будет эмуляцией нажатия клавиши Tab, но для таргета следующего моба надо знать хп предыдущего, а также, желательно, лвл. Вот я и не пойму как получить информацию а затаргенной цели. Подскажите плиз. Заранее спасибо.
P.S Даже если не придется знать информацию о цели, то я все равно хочу научиться ее получать

Nitrosgen
07.11.2010, 18:26
TBX1n, Я хочу написать простенького бота (решил попробывать свои силы), который будет бить мобов, собирать лут, пить банки. С лутом и банками ясно, таргет мобов будет эмуляцией нажатия клавиши Tab, но для таргета следующего моба надо знать хп предыдущего, а также, желательно, лвл. Вот я и не пойму как получить информацию а затаргенной цели. Подскажите плиз. Заранее спасибо.
P.S Даже если не придется знать информацию о цели, то я все равно хочу научиться ее получать

GA +8 +24 +18 +[I*4] + (+0)^J
+4: Mobs Struct (I in [0..300])

GA +8 +24 +14: - Mobs count
+3C MobLocX (float)
+40 MobLocZ (float)
+44 MobLocY (float)
+B4 MobType (6 - mob; 7 - NPC; 9 -
Pet) +11C MobWorldID
+120 MobID
+12C MobHP
+164 MobMaxHP
+225 MobFeature (0- None; 1 -
Accelerating; 2 - Pacifist; 3 - Enh. physical protection; 4 - Enh. magical
protection; 5 - Enh. physical attack; 6 -
Enh. magical attack; 7 - Berserk; Enh.
Life; 9 - Weakness)
+240 See: +225
+24C +0 MobName (UText) +2B8 MobAction (1 - Passive; 2 - P.
Attacks; 3 - M. Attacks; 4 - Dies; 5 -
Moves)
+2D4 MobPTargetID
+2D8 MobMTargetID
+2DC Mob Attack flag (1b) +310 + [I*2] MobBuffs (I in [0..N])
(1b)
+314 Mob Buffs Count
Источник данных: [Ссылки могут видеть только зарегистрированные и активированные пользователи]

Kitsune
07.11.2010, 20:01
777gamer777, структуру списка мобов нитроген уже предоставил вам выше.

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

777gamer777
07.11.2010, 20:24
ок, спасибо=)

Добавлено через 1 час 0 минут
Сорри за нубство, на я так и не понял как найти структуру, в которой присутствуют переменные.
Например структура клана (BA +218 +8 +[I*4] + (+0)^J: Clans Struct (I in [0..389]))
т.е. на delphi это будет выглядеть примерно так?

procedure TForm1.Button1Click(Sender: TObject);
var i,j:integer; //i,j в структуре
wnd:HWND;bytescount,pid,ipbuf,hprocess : dword;
const ba=$009C0E6C; //Базовый адресс
begin
wnd:=findwindow(nil,'Perfect World');
GetWindowThreadProcessId(wnd,@pid);
hprocess:=openprocess(PROCESS_ALL_ACCESS, False, PID);
for i:=0 to 389 do
begin
readprocessmemory(hprocess,ptr(ba),@ipbuf,sizeof(i pbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$218),@ipbuf, sizeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$8),@ipbuf,si zeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+i*4),@ipbuf,s izeof(ipbuf),bytescount);
{Дальше вообще не понятно.1) Всмысле надо прибавить $0 J раз? 2) Вы сказали, что J надо брать до бесконечности. Вопрос:как это сделать?3)И вообще, как определить что нашлась "нужная структура"?И зачем прибавлять $0? 4) Разве что-то от этого измениться? }
//Приведите плиз пример с J, если это возможно. Буду очень благодарен.
end;
end;

777gamer777
08.11.2010, 21:29
Помогите плз)
И еще почему-то все кнопки нормально эмулирует а TAB (VK_TAB) не прет? Мб защита стоит, кто знает?

Добавлено через 3 минуты
А вернее не только ТАБ, а все кнопки, которые бы я ни настраивал на автопоиск

Kitsune
08.11.2010, 21:39
777gamer777, для того, чтобы клиент начал принимать нажатия кнопок его надо разморозить.

777gamer777
08.11.2010, 21:40
хм, многие клавиши он спокойно принимает, т е надо для конкретных разморозить?

Kitsune
08.11.2010, 21:41
777gamer777, для всех надо. К тому же таб относится к системным клавишам и посылать надо не WM_KEYDOWN, а WM_SYSKEYDOWN.

Dinmaite
08.11.2010, 21:46
Функциональные кнопки блокируются "защитой". Помогает разморозка окна или "крякинг" :)
По поводу J

procedure TForm1.Button1Click(Sender: TObject);
var i,j:integer; //i,j в структуре
wnd:HWND;bytescount,pid,ipbuf,hprocess : dword;
const ba=$009C0E6C; //Базовый адресс
begin
wnd:=findwindow(nil,'Perfect World');
GetWindowThreadProcessId(wnd,@pid);
hprocess:=openprocess(PROCESS_ALL_ACCESS, False, PID);
j:=0;
for i:=0 to 389 do
begin
readprocessmemory(hprocess,ptr(ba),@ipbuf,sizeof(i pbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$218),@ipbuf, sizeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$8),@ipbuf,si zeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+i*4),@ipbuf,s izeof(ipbuf),bytescount);
for j:=0 to j do
begin
readprocessmemory(hprocess,ptr(ipbuf+0),@ipbuf,s izeof(ipbuf),bytescount);
end;

//читаем то что нам надо
inc(j);
end;
end;

Прибавление нуля дает нам доступ к другим страницам памяти.

777gamer777
09.11.2010, 19:42
Спс, т .е циклы должны быть вложенными?
и еще вопросы:
for j:=0 to j do
begin
readprocessmemory(hprocess,ptr(ipbuf+0),@ipbuf,s izeof(ipbuf),bytescount);
end;
цикл выполняется только 1 раз
И, как я понял, +$0 - это переход на другую страницу?

Kitsune
09.11.2010, 20:22
777gamer777,
1. цикл выполняется от 0 до J раз

...
//читаем то что нам надо
inc(j);
...
2. да, это переход на другую страницу

777gamer777
10.11.2010, 14:39
1.Каждый элемент структуры клана, это адресс определенного клана, о котором можно что-то узнать, например лвл, имя...?
2. Мне хочется понять как все устроено и как выполняется этот программный код
сначала I:=0;j:=0;
будет выполнятся так:
// 1 шаг
readprocessmemory(hprocess,ptr(ba),@ipbuf,sizeof(i pbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$218),@ipbuf, sizeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$8),@ipbuf,si zeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+0*4),@ipbuf,s izeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+0),@ipbuf,s izeof(ipbuf),bytescount);//$0 или просто 0
// что мы этим узнали?
//2 шаг
readprocessmemory(hprocess,ptr(ba),@ipbuf,sizeof(i pbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$218),@ipbuf, sizeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$8),@ipbuf,si zeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+2*4),@ipbuf,s izeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+0),@ipbuf,s izeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+0),@ipbuf,s izeof(ipbuf),bytescount);

//Получается с ростом i, растет и J?
и вообще, что это за структура, а то я что-то вообще запутался((

Kitsune
10.11.2010, 15:09
777gamer777,
J инкрементируется после того, как I достигло своего максимального значения, а зачем I становится 0 и по новой...

Структура это некий объект в памяти клиента, который содержит в себе какие-то элементы, например: инты, стринги, флоты и т.д.

Для доступа к самим данным структуры нам сначала необходимо найти адрес начала этой структуры в памяти.

Для этого мы как раз и бегаем по "страницам".

Адреса начал структур в памяти на первой странице выглядит так:
BA +218 +8 +[I*4]

На 2ой: BA +218 +8 +[I*4] +0
На 3ей: BA +218 +8 +[I*4] +0 +0
На 4ой: BA +218 +8 +[I*4] +0 +0 +0

Соответственно для получения всех элементов 1ый страницы надо просканировать 795 адресов. I от 0 до 795 же. Когда мы закончили сканировать 795 элементов, мы переходим на следующую "страницу" и по новой сканируем.

777gamer777
10.11.2010, 15:27
TBX1n, Спасибо) вот допустим мы нашли все элементы структуры, допустим структуры мобов, ткпкрь нужно для каждого элемента находить, например, название моба. И тогда мы узнаем всех мобов, которые нас окружают?

Kitsune
10.11.2010, 15:46
777gamer777, да, именно так. Но я обычно сразу получаю информацию к примеру о клане, если структура существует.

Например:
BA +218 +8 +[500*4], где 500 - это элемент на странице.
Если значение по этому адресу != 0, значит структура существует и мы можем получить данные:
+4 ClanID
+8 +4 +0 ClanName
+8 +8 ClanLvl

Dinmaite
10.11.2010, 15:49
Куда лучше брать информацию о каждом мобе во время сканирования, а не после того как мы получили адреса начала структур каждого моба.
Сканировать довольно удобно в записи.

777gamer777
10.11.2010, 15:56
Спасибо вам огромное)) кажется прояснилось

kaktess
10.11.2010, 16:27
Ну так ведь нужно знать оффсеты что бы прочитать из памяти так вот я хочу узнать как из (оффсет левела из offsetretriever клиент 1.3.4) 00000448 сделать (пример)$009C0E6C.

Dinmaite
10.11.2010, 16:59
Уважаемый, прочтите тему с начала.

777gamer777
10.11.2010, 17:30
Кое-что все-так я не понял)
1.у нас есть I, запускаем цикл от 0 до 389(это и будет количество элементов на одной странице, правильно я понял?)
2.Но с J я не понял.
Сначала сканируем все элементы на 1ой странице, и только потом прибавляем $0 и начинаем по новой и т. д.?
или начинается 1ая итерация цикла i, находим структуру, и сразу же прибаляем $0?

Dinmaite
10.11.2010, 17:37
Сначала пробегаем 1 страницу, потом вторую, потом третью. Я разве говорил что мой код вам подойдет? Я лишь показал как организовать переход по страницам.

777gamer777
10.11.2010, 19:00
Выходит, J может быть от 0 до максимального значения типа Integer, но тогда этих элементов будет нереально много, и обработка будет затруднительной... (колво элементов = max integer * 389)

Kitsune
10.11.2010, 19:04
777gamer777, как правило больше 4-5 страниц не бывает. А для остановки цикла просто выполняйте проверку: сравнение кол-ва структур которые вы нашли, с их конечным кол-вом.

Для кланов например: BA +218 +4 - кол-во кланов, которые в памяти вашего клиента.

777gamer777
10.11.2010, 19:11
Хм, всмысле BA + $218 + $4 = количество элементов структуры кланов? тогда сделать будет нетрудно)
ААА до меня доперло)) т.е вы имели ввиду не до бесконечности брать J, а делать цикл с неизвестным количеством повторений? (while или repeat)
Кстати, i умножать на 4 или на $4?

Kitsune
10.11.2010, 19:22
777gamer777, 4 дексе = 4 в хексе.

777gamer777
10.11.2010, 19:48
А инжекты обязательно писать на встроенном ассемблере или моджно занесением данных в ячейку памяти?

Kitsune
10.11.2010, 19:51
777gamer777, смысл инжекта в том, чтобы записать свой код в память процесса клиента пв и запустить его на выполнение.

Но инжекты не от балды пишутся, а берется именно тот кусок кода из ехе клиента, который подготавливает данные и вызывает функцию с параметрами, поэтому тут нет альтернатив, кроме как inline asm.

777gamer777
10.11.2010, 19:54
Я вот думаю, можно ли написать инжект для 100% получения 1-5кк из коробочки (менять и замораживать значения перед юзаньем или как-то так)

Kitsune
10.11.2010, 20:08
777gamer777, нет нельзя.
Максимум что можно в данном случаи это написать инжект на использование предмета в определенной ячейке инвентаря(такой инжект уже давно известен)

После выполнения инжекта, клиент посылает соответствующий пакет серверу (на использование предмета), сервер сам обрабатывает все и присылает ответ.

Соответственно обмануть его и заставить дать 5кк возможности нет.

777gamer777
11.11.2010, 16:15
И еще вопрос, надеюсь последний: в структуре элементы мобов идут по порядку или вразброс?

Kitsune
11.11.2010, 16:30
777gamer777, как записал в память так и хранит :) для поиска все равно надо просмотреть всю структуру.

777gamer777
11.11.2010, 16:31
ясно, спс, а то я посмотрел 1 - 9 страницу - везде 0

Kitsune
11.11.2010, 16:36
777gamer777, значит не правильно что-то делаешь. Обычно все находится до 5ой страницы.

Только код лучше сюда не кидать, за вас его писать никто не будет, да и я на C# пишу :)

777gamer777
11.11.2010, 17:13
а i надо брать от 0 до 300 или от $0 до $ 300?

Kitsune
11.11.2010, 17:19
777gamer777, До 0x300, следовательно 768.

777gamer777
11.11.2010, 21:57
procedure TForm1.Button1Click(Sender: TObject);
var wnd:HWND;bytescount,pid,ipbuf,hprocess : dword;kolvo,i,j,sum,lvl:integer;
const ba=$009C0E6C;
ga=ba+$1c;
begin
wnd:=findwindow(nil,'Perfect World');
GetWindowThreadProcessId(wnd,@pid);
hprocess:=openprocess(PROCESS_ALL_ACCESS, False, PID);
readprocessmemory(hprocess,ptr(ba),@ipbuf,sizeof(i pbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$1c),@ipbuf,s izeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$8),@ipbuf,si zeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$20),@ipbuf,s izeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$14),@sum,siz eof(sum),bytescount);
kolvo:=0;
j:=0;
while kolvo<>sum do //пока не найдем все элементы
begin

for i:=0 to 768 do
begin
lvl:=0;
readprocessmemory(hprocess,ptr(ba),@ipbuf,sizeof(i pbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$1c),@ipbuf,s izeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$8),@ipbuf,si zeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$20),@ipbuf,s izeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$18),@ipbuf,s izeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+(i*4)),@ipbuf ,sizeof(ipbuf),bytescount);
if j>0 then
begin
for j :=1 to j do
readprocessmemory(hprocess,ptr(ipbuf+$0),@ipbuf,si zeof(ipbuf),bytescount);

end;
readprocessmemory(hprocess,ptr(ipbuf+$4),@ipbuf,si zeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$464),@lvl,si zeof(lvl),bytescount);
if lvl>0 then
begin
listbox1.Items.Add(inttostr(lvl));//вывод элементов
kolvo:=kolvo+1;//если нашел элемент то прибаляем в количество
end;

end;
inc(j);
end;

end;

//чет не работает, я хочу вывести все лвлы, а оно зацикливается((

Dinmaite
11.11.2010, 23:45
ga НЕ РАВНО ba+$1c;
Пиши код красиво, и грамотно.
Пытайся использовать как можно меньше памяти, это полезно.
Всегда освобождай то что вызвал.
Не забывай что при чтении памяти может произойти ошибка.
Проверки нужно делать там, где это нужно.
Домашнее задание:
Не стоит всегда находить адрес структуры, сделай это 1 раз;
Лвл клиент получает только после того, как персонаж побывал в таргете у нас;
Проверяй наличие структуры а не данных в структуре;


procedure TForm1.Button1Click(Sender: TObject);
const
ba=$009C0E6C;
var
bytescount,pid,ipbuf,hprocess:dword;
kolvo,i,j,sum,lvl:integer;
begin
GetWindowThreadProcessId(findwindow(nil,'Perfect World'),@pid);
hprocess:=openprocess(PROCESS_ALL_ACCESS, False, PID);
if hProcess<>0 then
try
readprocessmemory(hprocess,ptr(ba),@ipbuf,sizeof(i pbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$1c),@ipbuf,s izeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$8),@ipbuf,si zeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$20),@ipbuf,s izeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$14),@sum,siz eof(sum),bytescount);
kolvo:=0;
j:=0;
while kolvo<>sum do
begin
for i:=0 to 768 do
begin
lvl:=0;
readprocessmemory(hprocess,ptr(ba),@ipbuf,sizeof(i pbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$1c),@ipbuf,s izeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$8),@ipbuf,si zeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$20),@ipbuf,s izeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$18),@ipbuf,s izeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+(i*4)),@ipbuf ,sizeof(ipbuf),bytescount);
for j :=1 to j do
readprocessmemory(hprocess,ptr(ipbuf+$0),@ipbuf,si zeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$4),@ipbuf,si zeof(ipbuf),bytescount);
readprocessmemory(hprocess,ptr(ipbuf+$464),@lvl,si zeof(lvl),bytescount);
if lvl>0 then
begin
listbox1.Items.Add(inttostr(lvl));
kolvo:=kolvo+1;
end;
end;
inc(j);
end;
finally
CloseHandle(hProcess);
end;
end;


И тогда все будет хорошо и красиво.

777gamer777
12.11.2010, 14:59
Спасибо огромное!!! Ники выводит, но есть 1 косяк: ники печатаются по нескольку раз

Kitsune
12.11.2010, 15:41
777gamer777, смотрите свой код :) в памяти клиента записи не повторяются.

q01q01
13.11.2010, 18:39
2. GetWindowThreadProcessId (модуль Windows)
function GetWindowThreadProcessId(hWnd: HWND; lpdwProcessId: Pointer = nil): DWORD; stdcall; overload;
зачем объявлена перезагрузка для функции? ведь она используется только разово в коде :) директива лишняя

777gamer777
14.11.2010, 15:41
Спс, люди, со своими ошибками разобрался) но возник новый вопрос:
Для написания автособирателя ресов (копание киркой) можно обойтись просто работой с памятью или надо писать инжекты? а если надо то что мне почитать на этот случай?)

Kitsune
14.11.2010, 17:18
777gamer777, без инжектов не обойтись.

Советую для начала прочитать:
[Ссылки могут видеть только зарегистрированные и активированные пользователи]

З.Ы. В актуальности инжектов приведенных в той теме не уверен, она как бы не "свежая" :)

777gamer777
14.11.2010, 17:28
и еще, лазил в инете, нашел инъекции, но у меня не получилось их использовать:

//Стандартная функция для применения инжекта (ошибок не выдает)
procedure InjectFunc (ProcessID:Cardinal;Func:Pointer;aParams:Pointer;a ParamsSize:DWORD);

var hThread:THandle;
lpNumberOfBytes:DWORD;
ThreadAddr,ParamAddr:Pointer;
begin
if ProcessID <> 0 then
begin
ThreadAddr:=VirtualAllocEx(ProcessID,nil,256,MEM_C OMMIT,PAGE_READWRITE); //Выделение места в памяти процесса.
WriteProcessMemory(ProcessID,ThreadAddr,Func,256,l pNumberOfBytes); //Запись в памяти нашей функции.
ParamAddr:=VirtualAllocEx(ProcessID,nil,aParamsSiz e,MEM_COMMIT,PAGE_READWRITE); //Также запись параметров к ней.
WriteProcessMemory(ProcessID,ParamAddr,aParams,aPa ramsSize,lpNumberOfBytes);
hThread:=CreateRemoteThread(ProcessID,nil,0,Thread Addr,ParamAddr,0,lpNumberOfBytes); //Создание потока, в котором будет выполняться функция.
WaitForSingleObject(hThread,INFINITE); //Ожидание времени окончания работы функции.
CloseHandle(hThread); //Очистка памяти.
VirtualFreeEx(ProcessID,ParamAddr,0,MEM_RELEASE);
VirtualFreeEx(ProcessID,ThreadAddr,0,MEM_RELEASE);
end;
end;

Далее идут функции реализации минига (копания ресов):

procedure MiningCall(aPParams:PParams);Stdcall;
var Pos,ItemSn:dword;
CallAddress:pointer;
begin
CallAddress:=ptr($005F5B40);
Pos:=aPParams^.Param1;
ItemSn:=aPParams^.Param2;
asm
pushad
push 0
push $C01 //ID Кирки (статический)
push Pos
push 0
push ItemSn
call CallAddress
add esp, $14
popad
end;
end;

procedure Mining(Pos,ItemSn:dword);
var aParams:TParams;
begin
aParams.Param1:=Pos; //Позиция кирки в инвентаре [0..N]
aParams.Param2:=ItemSn; //Серийный номер ресурса
InjectFunc(aHandle,@MiningCall,@aParams,SizeOf(aPa rams));
end;

Там, где выделено красным выдает ошибку. Помогите плиз
источник тут ([Ссылки могут видеть только зарегистрированные и активированные пользователи])

Добавлено через 22 часа 55 минут
ап, проблема все еще не решена(. Помогите, пожалуйста)

777gamer777
15.11.2010, 21:17
Что нужно подключить в delphi для Tparams и PParams?

Virial
16.11.2010, 14:29
Ничего подключать не надо, просто объявить нужную структуру, например:
type
TParams=record
Param1,Param2:cardinal;
end;
PParams=^TParams;

В качестве aHandle передаётся хэндл процесса - тот самый, который мы используем в ReadProcessMemory/WriteProcessMemory.

777gamer777
16.11.2010, 16:54
спасибо))

777gamer777
20.11.2010, 17:32
Спасибо, инжекты работают)) вот только рес собирается только, если к нему подойти.
Тут нужно инжект ходьбы юзать или таргета, кто-нить знает?

Kitsune
20.11.2010, 19:02
777gamer777, подбежать к цели сначала, а потом собирать лут.

Или ты хотел лут издалека собирать? хитрец...

alonwoolf
22.11.2010, 19:53
я попробовал, но у меня проблема в том, что после +&20 арес получается равный 0
А какой формат должен быть напишите плиз

Всё я разобрался))):
BA эт не тот адрес если беру BaseCall_Address то все норм

ЗЫ тока откуда берется так и не понял

Sanych89
24.11.2010, 19:00
а у меня проблемка с воллхаком.
если менять не только (в случае движения по х) [ba]+$1c+$20+$3c (положение камеры), а [ba]+$1c+$20+$638 (надпись над головой), то вполне себе перемещается, если зажимать пробел. даже можно перемещаться через пропасть - если зажимать пробел и постоянно напоминать высоте, что она не менялась.
чуть менее ректальный способ найти не удалось. как-нибудь ещё ведь можно дать серверу знать, что перемещение имело место быть, кроме как подпрыгнуть?
к сожалению, не получается фкурить, в каком месте ассемблер отправляет данные на сервер. конкретно то, что выдаётся на Find out what writes to this address -
004767D7 - d9 9e 38 06 00 00 - fstp dword ptr [esi+00000638]
но вот что с этим делать дальше - не слишком понятно. нагуглить тоже толком ничего не вышло.

Virial
25.11.2010, 13:49
Ну что ж, велосипед успешно изобретён!
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
И самое главное – никаких еретических Framework’ов, только идеологически верный Delphi! Как говорится, скажи .NET Си Шарпу...

Добавлено:
Расковырял аук, там всё довольно просто. Собираюсь набросать нечто вроде "спутника барыги", который бы анализировал цены на выбранные товары.

Virial
28.11.2010, 12:37
Ещё вопрос.
При работе с ботами и сканерами раздражает, что приходится запускать вместе с ними тормознутый клиент PW. Даже на 3ГГц-машине с 4 Гб памяти сложно запустить свыше 8 экземпляров клиента. Пока приходит на ум как-либо пропатчить его, чтоб убить нафиг весь графический движок, проигрывание звука и всё прочее, что жрёт ресурсы, оставив только собственно работу с сетью и памятью.
Конечно, удобнее было бы сделать аутгем-сканеры, но реально ли это вообще? Протокол обмена клиента с сервером известен или его расшифровка - нечто из области фантастики?

Nitrosgen
28.11.2010, 13:40
Есть же аутофгеймовый бот, аутофгеймовый торговый бот, аутофгеймовый сканер котов и обсервер
Так что все возможно
Но в паблик свои наработки никто не выложит, будьте уверены

Virial
28.11.2010, 14:49
А есть вообще хоть какая-нибудь информация по пакетам? Инжект отправки пакета нашёл, а вот как сделать то же самое, но без клиента, непонятно.

Kitsune
28.11.2010, 15:10
Virial, трафик зашифрован RC4, сжат MPPC.

Virial
28.11.2010, 15:30
Значит, даже аутгейм-боты всё равно юзают фрагменты кода клиента для создания/приёма пакетов?

Nitrosgen
28.11.2010, 15:42
С чего ты взял?

Virial
28.11.2010, 15:44
Ну раз трафик криптован... Выдрать алгоритм криптования из клиента - это надо быть мега-скиллованным, и в любом случае процесс растянется на месяцы работы.

Kitsune
28.11.2010, 15:45
Virial, сам напиши ;) я не выдирал ничего.

Virial
28.11.2010, 15:48
А сколько примерно времени ушло, чтоб разобраться в алгоритме?

Kitsune
28.11.2010, 15:56
Virial, спецификации все в открытом доступе :) гугл в помощь. Ну, а дальше самому додумывать все хитрости трафика PW.

Virial
28.11.2010, 16:07
Спасибо, ушёл курить RFC, для начала с MPPC разберусь, он вроде проще...

Добавлено через 23 часа 12 минут
Нагуглил исходники старенького аутгейм-бота (автор Vort) для PW. Скорее всего, протокол обмена уже 100 раз поменяли, но в качестве основы для изучения возможно пойдёт. Схема шифрования с тех пор не изменилась, или всё равно это копать придётся?

777gamer777
10.12.2010, 22:52
Люди, начал интересоваться ассемблером, и мне хочется понять, как устроен клиент пв (как найти нужный код для инжекта, найти определенные структуры самому (тот же аук к примеру)).
Кто знает, в какую сторону копать,что надо уметь делать для этого. Натолкните, плиз. Буду очень благодарен)

Dinmaite
10.12.2010, 23:17
Люди, начал интересоваться ассемблером, и мне хочется понять, как устроен клиент пв (как найти нужный код для инжекта, найти определенные структуры самому (тот же аук к примеру)).
Кто знает, в какую сторону копать,что надо уметь делать для этого. Натолкните, плиз. Буду очень благодарен)

Ты начал интерисоваться не ассемблером а основами крекинга :)
Или ты собираешся писать программы на асме?

"почти по теме" пример как я искал массив инвентаря в JD (тупо скопирую то что уже писал на другом форуме)

хм, попробую.
Для начала я нашел функцию использования итемов из инвентаря (для инжекта).
Далее заметил что она требует 2 параметра собственно WID итема и номер ячейки в которой лежит итем. Тоесть для успешной работы мне нужно было знать в какой ячейке лежит итем.
Так как искать массивы я не умею, решил пойти иным путем. Меня заинтерисовала строка:

MOV EAX,DWORD PTR DS:[EDI+8],

в которой собственно в регистр EAX ложится значение WID. Естественно берется оно из массива данных инвентаря.
Далее прошелся вверх по коду найдя такие строки.

MOV EAX,DWORD PTR DS:[ECX]

LEA ECX,DWORD PTR DS:[ECX+EAX*4]

MOV ECX,DWORD PTR DS:[ECX+C]

MOV EAX,DWORD PTR DS:[ECX+114C]

MOV EAX,DWORD PTR DS:[ECX+28]

MOV ECX,DWORD PTR DS:[EAX+1C]

MOV EAX,DWORD PTR DS:[B03064]

(строки приведены в обратном порядке, с конца в начало, так как я "разматываю клубок" с конца.)

Тоесть собственно говоря путь к базовому адресу.
Фактически путь к массиву итемов в инвентаре
[ba]+1c+28+114c+c+i*4+
8 - WID;

Кроме WID меня ничего не интерисовало, поэтому не заморачивался.

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

Посему их можно найти расставив брейкпоинты на все обращения к базовому адресу (что долго и неудобно).
Отсюда делаем вывод - используем СЕ, а именно его возможность трассировать вызовы функций (тоесть проверяем кто обращается к базовому адресу).
А далее начинаем копать от той функции/процедуры в которой стоп произошел при совершении нгеобходимого нам действия.

777gamer777
12.12.2010, 18:02
а,собственно, как вообще пишутся инжекты. Меня интересует сам процесс,подход,механизм.
Я ,так понимаю, там не просто меняются значения оперативной памяти, там что-то другое?
Помогите,пожалуйста разобрать код ассемблера на примере инъекции прыжка (взято с Russian Server: PWI):

procedure InjectFunc (ProcessID:Cardinal;Func:Pointer;aParams:Pointer;a ParamsSize:DWORD);
var hThread:THandle;
lpNumberOfBytes:DWORD;
ThreadAddr,ParamAddr:Pointer;
begin
if ProcessID <> 0 then
begin
ThreadAddr:=VirtualAllocEx(ProcessID,nil,256,MEM_C OMMIT,PAGE_READWRITE); //Выделение места в памяти процесса.
WriteProcessMemory(ProcessID,ThreadAddr,Func,256,l pNumberOfBytes); //Запись в памяти нашей функции.
ParamAddr:=VirtualAllocEx(ProcessID,nil,aParamsSiz e,MEM_COMMIT,PAGE_READWRITE); //Также запись параметров к ней.
WriteProcessMemory(ProcessID,ParamAddr,aParams,aPa ramsSize,lpNumberOfBytes);
hThread:=CreateRemoteThread(ProcessID,nil,0,Thread Addr,ParamAddr,0,lpNumberOfBytes); //Создание потока, в котором будет выполняться функция.
WaitForSingleObject(hThread,INFINITE); //Ожидание времени окончания работы функции.
CloseHandle(hThread); //Очистка памяти.
VirtualFreeEx(ProcessID,ParamAddr,0,MEM_RELEASE);
VirtualFreeEx(ProcessID,ThreadAddr,0,MEM_RELEASE);
end;
end;
procedure JumpCall(aPParams:PParams);Stdcall;
var CallAddress:pointer;
begin
CallAddress:=pointer($00476970); // что это за адресс?
asm
pushad // push - это добавление в стек, а 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;


Помогите,плиз. Очень хочу научится писать инжекты (не только для пв).

Dinmaite
12.12.2010, 20:07
Этот асмо-код, всего лишь подготовка параметров для функции прыжка.

При динамическом инжекте кода в чужой процесс, мы создаем свой поток в этом самом чужом процессе, и из него вызываем стандартную функцию клиента.

777gamer777
12.12.2010, 20:14
а где взять эту функцию (узнать адресс, параметры и т д)

Dinmaite
12.12.2010, 20:18
Функция находится практически методом научного тыка, примерно так как я писал в #147 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]).
Параметры берутся из кода клиента, просто нужно посмотреть что передается в функцию.

777gamer777
12.12.2010, 20:27
Т.е надо искать функцию через CE - например юзнуть итем в какой-нить ячейке, и посмотреть через CE,что изменилось? а как поставить отслеживание в CE? скажи плиз, я нуб еще

Dinmaite
12.12.2010, 20:44
[Ссылки могут видеть только зарегистрированные и активированные пользователи]

Только не то что выделено, а "Find what accesses this address"

777gamer777
12.12.2010, 20:56
нажать, а потом допустим прыгнуть?

Dinmaite
12.12.2010, 21:05
Да, но предварительно подождать пока не закончатся "ложные" срабатывания.

777gamer777
12.12.2010, 21:08
Все это надо делать относительно базового адресса

Добавлено через 1 час 10 минут
например, хочу сделать "шприц" прыжка. мне надо найти базовый адрес, нажать
"Find what accesses this address", там вылетает кучу всякой фигни. ждем, а потом прыгаем, и смотрим что занеслось? или как?
P.S как бы хотелось, чтобы кто-то все это подробно объяснил

Dinmaite
12.12.2010, 22:37
Да, примерно так.
Подробно я обьяснить могу разве что в асе. Потому как не представляю что будет не ясно и не знаю куда сделать упор.

DragonSpirit
13.12.2010, 00:13
мне интересно что за оффсеты $10 и $0?
извините, если пропустил в теме

777gamer777
13.12.2010, 22:21
Dinmaite, спасибо огромное за помощь в асе))

Njkzy80
13.01.2011, 13:29
Dinmaite, я полностью прочитал всю тему, плиз неотправляйте куда нить , а помогите советом или ссылкой. как сделать чтоб контролировалось НР или МР т.е. отображалось текущее состояние???? Плиз
Пробовал через while но все виснет.

Dinmaite
13.01.2011, 19:56
Естественно, вы ведь делаете вечный цикл (проявляю телепатические задатки)
Если хотите все это сотворить в вечном цикле - используйте потоки (нити, класс TThread)
Если хотите сделать в основном потоке - используйте таймер.

Njkzy80
13.01.2011, 21:20
СПС, огромное что откликнулись. Думал тема уже мертвая и ни кто неоткликнется. Я недавно решил занятся созданием своего бота, просто те которые есть неустраивают по тем или иным причинам(
Дэлфу неставил лет 6 уже как профиль работы поменял( Если нетрудно добавьте к этому как сделать чтоб бот постоянно следил опытом
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Label1: TLabel;
procedure FormActivate(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
PID,hProcess,ipbuf,BytesCount : dword;
buf : integer;

end;

var
Form1: TForm1;
WndHndl:THandle;
const base_addr=$009C0E6C;
const EXP_Offset=$474;

implementation

{$R *.dfm}

procedure TForm1.FormActivate(Sender: TObject);
begin

WndHndl:=findwindow('ElementClient Window',nil);
GetWindowThreadProcessId(WndHndl, @PID);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, PID);
ReadProcessMemory(hProcess, ptr(base_addr), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$1C), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$20), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+EXP_Offset), @buf, sizeof(buf), BytesCount);
Label1.Caption:=inttostr(buf);

end;


end.
Кстати почему выдает ошибку если я buf обьявляю например word

Добавлено через 7 минут
СПС понял про таймер))) Вернее вспомнил))))

Добавлено через 10 минут
Работает) Телепатия у вас супер))))
Что лучше по производительности отдельный поток или все в одном, что посоветуете?

Dinmaite
13.01.2011, 23:18
Я своих ботов пишу многопоточными, по сути четырехпоточными.
1. GUI.
2. Bot, собственно выбор таргета, подьем дропа.
3. Heal, все что касается лечения.
4. Skill, Скиллы/бафы.

Njkzy80
14.01.2011, 20:32
СПС за совет.
Я у многих ботов замечал маленький глюг, в том числе и у меня тоже с ботом происходит: Допустим ( это как пример, но принцип один) нажимается скил или банка,а по таймеру на это же время попадает еще какая нибуть функция ну например кормежка пета, так кормежка почемуто не срабатывает а ждет следующей итерации. И я не могу найти в чем причина( у своего ботика). Я конечно еще не разобрался с потоками может в этом причина у меня, но как тогда с другими ботами?
И еще, Уважаемый Dinmaite, в этой теме много говорится о разморозке окна, но нет примера, вы немогли бы привести пример как это реализовать, ПЛИЗ очень вас прошу.

Dinmaite
14.01.2011, 20:38
Для разморозки окна подойдет пример из соседней темы "Патчер памяти 2 или Пишем Джампхак"

Njkzy80
15.01.2011, 16:11
Уважаемый Dinmaite, простите плиз, но просмотрев всю тему так и не понял как разморозить окно. Прошу вас обьясните поподробнее, плиз.

Kitsune
15.01.2011, 16:22
Njkzy80, есть 2 варианта:
1. Через N-интервал времени записывать в память клиента информацию, о том, что окно в фокусе, даже если это и не так.
2. Найти в памяти функцию, которая переключает флаг заморозки и сделать так, чтобы она этого не делала.

Njkzy80
16.01.2011, 13:03
Уважаемый TBX1n спасибо и вам что также откликнулись, на мои вопросы.
Исходя из вашего ответа у меня возникло несколько вопросов:
При первом варианте небудет ли мерцания окна игры?
При втором варианте я так понимаю что придется пропатчить клиент или можно будет это както организовать в программе? Если можно то приведите пример пожалуйсто.

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

Kitsune
16.01.2011, 13:08
Njkzy80,
1. Не будет мерцаний.
2. Патчить память клиента или патчить ехе - разницы нет.
3. Найти все окна PW по классу, и прочитать по заданным оффсетам ники из каждого окна.

Njkzy80
16.01.2011, 13:47
Уважаемый TBX1n,
В том то и проблема что у я даже сообразить немогу как сделать чтобы бот нашел все окна.
Вот эта процедура находит тока один ник, а что надо сделать чтобы были найдены все ники?
WndHndl:=findwindow('ElementClient Window',nil);
GetWindowThreadProcessId(WndHndl, @PID);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, PID);
hProces:= hProcess;
ReadProcessMemory(hProces[index], ptr(base_addr), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProces[index], ptr(ipbuf+$1C), @ipbuf, sizeof(ipbuf), BytesCount) ;
ReadProcessMemory(hProces[index], ptr(ipbuf+$20), @ipbuf, sizeof(ipbuf), BytesCount) ;
ReadProcessMemory(hProces[index], ptr(ipbuf+Name_offset), @ipbuf, 4, BytesCount);
ReadProcessMemory(hProces[index], ptr(ipbuf+0), @buft, 32, BytesCount) ;
s:=WideCharToString(buft) ;
ComboBox1.Items.Add(' '+s) ;
Прошу вас ПОЖАЛУЙСТО добавте, что необходимо чтобы были найдены все ники.

Добавлено через 5 минут
Ой, извините не то скопировал, та процедура приводит к ошибке
а эта выводит только один ник
WndHndl:=findwindow('ElementClient Window',nil);
GetWindowThreadProcessId(WndHndl, @PID);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, PID);
ReadProcessMemory(hProcess, ptr(base_addr), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$1C), @ipbuf, sizeof(ipbuf), BytesCount) ;
ReadProcessMemory(hProcess, ptr(ipbuf+$20), @ipbuf, sizeof(ipbuf), BytesCount) ;
ReadProcessMemory(hProcess, ptr(ipbuf+Name_offset), @ipbuf, 4, BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+0), @buft, 32, BytesCount) ;
s:=WideCharToString(buft) ;
ComboBox1.Items.Add(' '+s) ;

ПМОГИТЕ ПРОШУ ВАС!

Dinmaite
16.01.2011, 16:18
function EnumProc (h: HWnd; Param: LongInt): Boolean; stdcall; // Îáÿçàòåëüíî stdcall !!!
var
p:array [0..255] of Char;
PID,hProc,nbyte,play_addres:dword;
bufd:dword;
bufs:array [1..60] of widechar;
Begin
GetClassName(h ,p,sizeof(p));
if p='ElementClient Window' then
begin
GetWindowThreadProcessId(h, @PID);
hProc:=OpenProcess(PROCESS_ALL_ACCESS, False, PID);
if hProc <> 0 then
begin
readprocessmemory(hProc,ptr($009C1514),@bufd,sizeo f(dword),nbyte);
readprocessmemory(hProc,ptr(bufd+$20),@bufd,sizeof (dword),nbyte);
play_addres:=bufd;
readprocessmemory(hProc,ptr(bufd+$608),@bufd,sizeo f(dword),nbyte);
readprocessmemory(hProc,ptr(bufd),@bufs,60,nbyte);
form1.NickBox.Items.Add(string(bufs));
akk[form1.NickBox.Items.Count-1].Wnd:=h;
akk[form1.NickBox.Items.Count-1].PID:=PID;
akk[form1.NickBox.Items.Count-1].play_addres:=play_addres;
end;
closehandle(hProc);
end;
EnumProc := TRUE;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
NickBox.Items.Clear; // Î÷èñòèì ñïèñîê ïåðåä íà÷àëîì ïîèñêîâ
EnumWindows (@EnumProc, 0); // è ñêàæåì - èñêàòü
end;

zaparca
18.01.2011, 11:54
Я своих ботов пишу многопоточными, по сути четырехпоточными.
1. GUI.
2. Bot, собственно выбор таргета, подьем дропа.
3. Heal, все что касается лечения.
4. Skill, Скиллы/бафы.

Можеш написать код 1. GUI. потока просто интересно как передать переменные в поток

Dinmaite
18.01.2011, 18:24
Я свой код не показываю, за редким мсключением.
Переменные в поток можно передать при создании потока (предварительно описав их в классе потока).

Njkzy80
18.01.2011, 20:07
Уважаемый Dinmaite, СПС за помощь! Три дня разбирался пытался понять сею процедуру и самое главное как из нее передать PID выбранного окна, но все таки победил и разобрался. Сейчас читаю про потоки и инжек. Надеюсь вы и TBX1n дальше сможете помогать советами. СПС вам и этому сайту.
Непрощаюсь))))
Пошел читать

Добавлено через 10 часов 8 минут
Уважаемый Dinmaite. Пожалуйсто объясните как понять и записать в коде: GA +8 +24 +18 +[I*4] + (+0)^J +4: (I in [0..300])
что такое J и I всмысле какой у них тип?
Пожалуйсто помогите!

Njkzy80
20.01.2011, 02:17
Запись BA +218 +8 +[I*4] + (+0)^J +4 для разных значений J расшифровывается как:
J = 0: BA +218 +8 +[I*4] +4
J = 1: BA +218 +8 +[I*4] +0 +4
J = 2: BA +218 +8 +[I*4] +0 +0 +4
J = 3: BA +218 +8 +[I*4] +0 +0 +0 +4
J = 4: BA +218 +8 +[I*4] +0 +0 +0 +0 +4
J = 5: ...
Продолжать, пока не будут найдены все элементы. Элементы неравномерно распределены по всему массиву. Количество элементов можно посмотреть по адресу, указанному в первой строке описания каждой структуры.
Пожалуйсто подскажите как написать цикл добавления нулей, ПРОШУ ВАС помогите начинающему!
Я написал вот таким образом:
hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, p);
ReadProcessMemory(hProcess, ptr(base_addr), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$1C), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$8), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$24), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$18), @ipbuft, sizeof(ipbuft), BytesCount);
for i:=0 to $300 do begin
ReadProcessMemory(hProcess, ptr(ipbuft+(I*4)), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$4), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$11c), @ipbuft, sizeof(ipbuft), BytesCount);
if buft<>0 then
begin
ReadProcessMemory(hProcess, ptr(ipbuft+$124), @ipbuft, sizeof(buft), BytesCount);
ListBox2.Items.Add(IntToStr(buft));
end;
end;

for i:=0 to $300 do begin
ReadProcessMemory(hProcess, ptr(ipbuft+(I*4)), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+0), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$4), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$11c), @ipbuft, sizeof(ipbuft), BytesCount);

if buft<>0 then
begin
ReadProcessMemory(hProcess, ptr(ipbuft+$124), @ipbuft, sizeof(buft), BytesCount);
ListBox2.Items.Add(IntToStr(buft));
end;
end;

и таким образом добовлял нули, дошел до 10 и все пусто
ПОМОГИТЕ!

Dinmaite
20.01.2011, 23:31
Может быть там дальше ничего нет?
А может быть вам надо перейти на вторую страницу в памяти.

Njkzy80
21.01.2011, 03:33
В том то и проблема, я и прошу помощи что я никак немогу понять как перебирать страници в цикле, как к одному участку кода добовлять целую строчку еще и в цикле.

А разве я таким образом не перебираю страници?
for i:=0 to $300 do begin
ReadProcessMemory(hProcess, ptr(ipbuft+(I*4)), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+0), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$4), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$11c), @ipbuft, sizeof(ipbuft), BytesCount);

if buft<>0 then
begin
ReadProcessMemory(hProcess, ptr(ipbuft+$124), @ipbuft, sizeof(buft), BytesCount);
ListBox2.Items.Add(IntToStr(buft));
end;
for i:=0 to $300 do begin
ReadProcessMemory(hProcess, ptr(ipbuft+(I*4)), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+0), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+0), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$4), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$11c), @ipbuft, sizeof(ipbuft), BytesCount);

if buft<>0 then
begin
ReadProcessMemory(hProcess, ptr(ipbuft+$124), @ipbuft, sizeof(buft), BytesCount);
ListBox2.Items.Add(IntToStr(buft));
end;
for i:=0 to $300 do begin
ReadProcessMemory(hProcess, ptr(ipbuft+(I*4)), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+0), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+0), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+0), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$4), @ipbuft, sizeof(ipbuft), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuft+$11c), @ipbuft, sizeof(ipbuft), BytesCount);

if buft<>0 then
begin
ReadProcessMemory(hProcess, ptr(ipbuft+$124), @ipbuft, sizeof(buft), BytesCount);
ListBox2.Items.Add(IntToStr(buft));
end;

Добавлено через 2 часа 19 минут
:cry::cry::cry::cry: Да какже получить информацию о цели????? :bow: Людиии помогите!!! У мя уже башня съезжает:shock::agreed:

Dinmaite
21.01.2011, 19:06
Информацию о цели можно получить двумя способами.
1. Получить ID цели, преобразовать ее в номер ячейки и взять информацию из массива.
2. Прочитать весь массив, найти в нем цель, считать данные.

Нет, таким образом ты не "листаешь страницы"

Njkzy80
24.01.2011, 19:04
Нет, таким образом ты не "листаешь страницы"

Максимум что смог найти тока это
"""1-я страница [BA] +8 +20 +18 +[I*4] +4:
2-я страница [BA] +8 +20 +18 +[I*4] +0 +4:
3-я страница [BA] +8 +20 +18 +[I*4] +0 +0 +4:
4-я страница [BA] +8 +20 +18 +[I*4] +0 +0 +0+4:
5-я ...
И т.д.
Через while легко реализовывается.""""
Перерыл кучу книг и сайтов , Но как реализовать так и непонял. Прошу помогите!
И еще во всех инжектах у меня компилятор ругается на aPParams:PParams - что это?
неизвестный параметр пишет и на ТParams?

Dinmaite
24.01.2011, 20:47
Я описал этот тип в своей теме.
Код уже приведен здесь, переписывать его времени у меня нет.

Vladim543
29.01.2011, 19:48
Подскажите пожалуйста, если нечего не смыслю и хочу изучить [Delphi], что бы например написать программу сбора ресов.
Сколько примерно надо времени?
Год, месяц, неделя, пару дней, 1 день.
Это что бы не парить зря свои нервы и время.

Добавлено через 3 минуты
А и можно ссылки кинуть как проще изучить.

Dinmaite
29.01.2011, 20:57
Сходите в раздел Делфи, там есть множество ссылок.

Vladim543
29.01.2011, 21:46
Dinmaite, ясно спс. А вот скоко времени займет ну хоть примерно по своему опыту.

Dinmaite
29.01.2011, 21:52
Я до сих пор узнаю что-то новое иногда, занимаюсь этим делом без малого 5 лет.

Vladim543
30.01.2011, 00:20
а можно я еще пару вопросов задам?
1. С какого языка мне начать изучать программирование? (не фига не знаю)

2. Можно ли создать бота для сбора ресов на Visual Basic 6 ? (если нет то какой язык программирования подойдет еще кроме делфи для этой цели).

Kitsune
30.01.2011, 02:43
Vladim543,
1. Стоит выбрать тот, который больше понравится.
2. Можно, но советом врядли кто-то поможет. VB мало распространенный язык. В основном пишут на C++, C#, Java, Delphi.

ultrasound
06.02.2011, 20:22
Скажите пожалуйста, а как получить ID игрока, который в таргете? И что такое targetID (GA +20+AF8) ?

Kitsune
06.02.2011, 20:50
И что такое targetID (GA +20+AF8)

ID игрока, который в таргете

з.ы. научите так меня, чтобы в своём вопросе давал ответ на него...

ultrasound
06.02.2011, 21:06
з.ы. научите так меня, чтобы в своём вопросе давал ответ на него...
:) Просто ID игрока не равно значению TargetID, которое я получаю... Вот и хотелось бы уточнить что такое TargetID

Добавлено через 11 минут
Прошу прощения, вопрос снимается - была ошибка в программе

_Wolf_
08.02.2011, 20:56
Пишу наверно не в тему, но все же.
Подскажите как передавать текст окну. Делаю через SendMessage(PW_Window_Handle, WM_CHAR, VkKeyScan(aText[i]), 0 ) Англ символы норм ввыводятся, что касается русских буковат козеряблики.

Dinmaite
08.02.2011, 21:14
Используй SendMessageW или PostMessageW
Окно ПВ понимает только юникод, моло того, передавать символы таким образом можно только если клиент в оконном режиме.

_Wolf_
08.02.2011, 21:38
Спасиб, чет я не додумался сразу попробывать.
передавать символы таким образом можно только если клиент в оконном режиме.

0_о а как играть в несколько в полноэкранке о_0

Dinmaite
08.02.2011, 21:51
Точно так же как и в оконном режиме.

ultrasound
16.02.2011, 14:29
Помогите пожалуйста. Пытаюсь определить высоту персонажа
Z : Real;
ipbuf,BytesCount : DWord;

ReadProcessMemory(hProcess, ptr(BASE_ADDRESS), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$1C), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$20), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$44), @z, sizeof(z), BytesCount);

В результате получаю значение Z = 0,007546585960847 Не понимаю в чем дело...

Добавлено через 44 минуты
Опечатка:
ReadProcessMemory(hProcess, ptr(ipbuf+$40), @z, sizeof(z), BytesCount);

r3m
16.02.2011, 19:20
Насколько я помню, переменная должна быть типа Single.

heh
27.03.2011, 22:13
procedure TForm1.Timer1Timer(Sender: TObject);
const
I=$4;/// адрес к первому члену группы
var
W: THandle;
ipbuf,baseaddr,PID,hProcess,BytesCount: DWord;
begin
baseaddr:=StrToint(Edit4.Text);
W:=FindWindow(Nil,PChar(Edit1.text));
GetWindowThreadProcessId(W, @PID);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, PID);
ReadProcessMemory(hProcess, ptr(baseaddr), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$1C), @ipbuf, sizeof(ipbuf), BytesCount);
/// GA
ReadProcessMemory(hProcess, ptr(ipbuf+$6A8), @ipbuf, sizeof(ipbuf), BytesCount);
ReadProcessMemory(hProcess, ptr(ipbuf+$14), @ipbuf, sizeof(ipbuf), BytesCount);
/// структура членов группы
ReadProcessMemory(hProcess, ptr(ipbuf+I), @ipbuf, sizeof(ipbuf), BytesCount);
///первый член группы
ReadProcessMemory(hProcess, ptr(ipbuf+$С), @ipbuf, sizeof(ipbuf), BytesCount);
/// получен его ID

и тут возник вопрос как его потом выделить в таргет по этому ID
ощущаю себя лютым нублом, но ответ ощинь важен :bow:

Dinmaite
28.03.2011, 09:35
Как и любого моба/персонажа, лично я предлагаю исользовать пакетный вариант выделения. Почитай в этой ([Ссылки могут видеть только зарегистрированные и активированные пользователи]) теме.

Jok3r666
24.08.2011, 09:26
(X + 4000) / 10 = Игровой Х
(Y + 5500) / 10 = Игровой Y
(Z / 10) = Игровой Z
Для других игроков не в таргете так же?
ba+1c+20+380+[88+(0*4)]+[i*4]+$3C \\ кидаю во флоат
x = (x+4000)/10;
просто ерунда какаято выводится

Все, отбой. Проблема была в типе. В одной процедуре все правильно было, а во второй в инт затолкал х и у.

alegr
13.09.2011, 07:49
ура! сбылась мечта идиота :) я, хоть, с делфи дружу только на интуитивном уровне, на знаниях паскаля, но всё понятно в общем)) чтож, начну подгонять под С++ мож чо и получится

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

Добавлено через 20 минут
Помогите пожалуйста. Пытаюсь определить высоту персонажа
Z : Real;


за высоту отвечает переменная Y! к тому же, я бы посоветовал сначала поэксперементировать на своём сервере с гм консолью, чтоб над головой были текущие координаты, тогда поймёшь в чём прикол)

Dinmaite[Work]
13.09.2011, 09:32
Нахождение багов - метод научного тыка. Нахождение офсетов - отсеисание либо разбор структур. На первоначальном этапе отсеивание проще и быстрее.

Подогнать данный код под C++, это "как два пальца".

За высоту отвечает та переменная, которую сам себе выберешь.

А по поводу экспериментов с консольной командой d_showpos, так для этого свой сервер не нужен.

alegr
13.09.2011, 18:15
вопрос в копилку:
1. Почему флайхак не работает на руоффе?
2. Есть ли возможность в коде клиента заранее отслеживать количество выполняемого кода? чтобы избежать инъекций... Или какие могут быть средства борьбы с этим делом?

Добавлено через 2 минуты
;1766731"]А по поводу экспериментов с консольной командой d_showpos, так для этого свой сервер не нужен.
даже так) я просто не пробовал на оффе, думал, права гма нужны для вызова консоли))

VeTaL_UA
13.09.2011, 18:45
1. Почему флайхак не работает на руоффе?
Потому, что передвижение персонажа в игровом пространстве контролируется сервером.
2. Есть ли возможность в коде клиента заранее отслеживать количество выполняемого кода? чтобы избежать инъекций... Или какие могут быть средства борьбы с этим делом?
Чётоянипонимаю... :wtf:

heila
20.05.2018, 18:46
Запустила флай с первой страницы на фришке 1,3,6. Адреса не меняла, вобще ничего не меняла.
Он мне сказал что клиент пропатчен, но по факту в игре не произошло ничего (не откидывает и как будто ничего не было). Вопрос - дело в адресе или что-то еще не так? Ведь по идее он должен был мне сказать что не та версия клиента, если дело было бы в адресе или я не права?
Попробовала на версии 1,4,1 - та же тема.
Нужен совет - есть смысл искать и менять адрес или дело не только в нем?

Sirioga
21.05.2018, 20:17
Нужен совет - есть смысл искать и менять адрес или дело не только в нем?

Если фришка реально 1.3.X, то смысл есть, если конечно не жалко пяти минут драгоценного времени на поиски.

heila
21.05.2018, 21:51
А можно ли имея базовый адрес определить какая реально версия клиента? если да, то как?

Dinmaite
30.05.2018, 01:48
А можно ли имея базовый адрес определить какая реально версия клиента? если да, то как?

На данном этапе нельзя. Экзешники серверов накрывают чем ни попадя, что смещает адресацию. При этом базовый адрес можетбыть старым, а вот остальное смещено.

Определить корректно можно просто прикинув функционал, если есть джины, автопуть или больше 3 рас - явно не 1.3.6-1.3.9, а значит клепать флай смысла особо нет - все равно будет откидывать.
В
Второй хороший вариант - найти адрес джампхака, это просто и работает даже на серверах накрытых протекторами. Далее делаем постоянную запись значения 1 по адресу джампхака и пробуем прыгать больше 10 раз. Если откидывает - версия явно выше 1.3.9.