jdark
28.07.2011, 14:54
На примере написанной мной программки
xCube ([Ссылки могут видеть только зарегистрированные и активированные пользователи]).
Смещения ру офф клиента можно взять тут ([Ссылки могут видеть только зарегистрированные и активированные пользователи])
Написана на Codegear C Builder 2007 ( впрочем от 6 билдера до XE, особо разницы нету...с юникодом ток немного)
4Zhyk.ru ([Ссылки могут видеть только зарегистрированные и активированные пользователи]*********/fd15774)
Описание проекта: на форме у нас 4 компонента: PopupMenu, ImageList, Timer, TrayIcon.
Итак: чего нам надо сделать
1. Посчитать шарики в 5, 27 комнатах
2. Смотреть в таргет на предмет наличия гусениц.
Что для этого потребуется: Смотреть свой таргет, заглянем в смещения
GAME_ADD = A5BFCC;
Структура игрока:
GA +20: HostPlayer Struct
+B0C; -Target
Смотреть окружающих нас мобов:
GA +8 +24 +14: - Mobs count
Структура мобов
GA +8 +24 +18 +[I*4] + (+0)^J +4: (I in [0..300 hex])
+11C MobWorldID
+120 MobID
Как нам надо читать: если хотим прочитать кто у нас в таргете, смотрим выше описанные смещения и считываем 4 бафта по смещению GA, далее по полученному смещению +20, далее по полученному + B0C - получили таргет.
С мобами интересная вещь, самому лень было сразу осиливать))
там где +0 это значит считать в это адресе адрес след. элемента
(+0)^J это наши страницы памяти
в итоге у нас получится такая охинея
1-я страница GA +8 +24 +18 +[I*4] +4:
2-я страница GA +8 +24 +18 +[I*4] +0 +4:
2-я страница GA +8 +24 +18 +[I*4] +0 +0 +4:
и так далее, особо останавливаться не будем, по ходу поймем :)
а теперь вгрыземся в код
смотрим комменты после // дабы оставить код рабочим
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
DWORD dwPid=0;
HANDLE hProc;
int iRed, iWhite, iBlue;
int iGA = 0xa5bfcc; // Гейм Адресс
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Exit1Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
Form1->Hide(); // прячемся в трей
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
// собственно по таймеру, у меня он кажется установле в 400мс, запускаем основную обработку
// объявляем переменные, замечу борланд как то не адекватно читает память если не инизиализировать переменные заранее
DWORD dwPlCount=0;
DWORD dwMass=0, dwPlId=0;
DWORD dwWid=0;
DWORD dwTarget=0;
iRed=0; iWhite=0; iBlue=0;
//Ищем окошко с названием Perfect World и получаем его хенлд
HWND hHandle = FindWindow("ElementClient Window","Perfect World");
//По хэндлу получаем индефикатор процесса, чтобы читать память
GetWindowThreadProcessId(hHandle, &dwPid);
//открываем выбранный процесс
hProc = OpenProcess(0xfff, false, dwPid);
if (hProc) // проверяем открыли
{
DWORD dwTemp = 0;
DWORD dwFind = 0;
//----------------------читаем таргет GA +20 +B0C
ReadProcessMemory(hProc, (LPVOID) iGA, &dwTemp, 4, NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x20), &dwTarget, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTarget + 0xb0c), &dwTarget, 4 , NULL);
//---------------------------------------------------------
//-------------------------читаем структуру мобов GA + 20 мы уже считали в dwTemp, дальше +8 +24
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x8), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x24), &dwTemp, 4 , NULL);
//------------------------------- в dwTemp GA +20 +8 +24, и считываем +14 это таргет, а GA +20 +8 +24 +18 это начало массива
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x14), &dwPlCount, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x18), &dwMass, 4 , NULL);
//-----------самая порнуха [I*4] + (+0)^J +4: (I in [0..300 hex])
// делаем это в 2х циклах, переменная i это J
// ii это I, 300 в 16тиричной это 768
for (int i = 0; i < 5; i++) {
for (int ii = 0; ii < 768; ii++)
{
//считали GA +8 +24 +18 +[I*4]
ReadProcessMemory(hProc, (LPVOID) (dwMass + ii*4), &dwTemp, 4 , NULL);
// тут пошел разбор страниц
switch (i){
case 1:
//1-я страница GA +8 +24 +18 +[I*4] +4:
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
break;
case 2:
//2-я страница GA +8 +24 +18 +[I*4] +0 +4: и далее...
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
break;
case 3:
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
break;
case 4:
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
break;
case 5:
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
break;
default:
;}
// и вот почти пройдена наша 3х этажная хнень)) дочитываем +4 до GA +8 +24 +18 +[I*4] + (+0)^J +4 . тут мы добрались уже до самой ячейки структуры моба
ReadProcessMemory(hProc, (LPVOID) (dwTemp+4), &dwTemp, 4 , NULL);
// мда, названа dwPlId, писал для игроков :) вобщем не пугаемся это айдишка моба GA +8 +24 +18 +[I*4] + (+0)^J +4 +120 MobID
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x120), &dwPlId, 4 , NULL);
// если в записи чтото присутствует читаем и WorldID моба GA +8 +24 +18 +[I*4] + (+0)^J +4 +11C MobWorldID
if (dwPlId > 0){
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x11c), &dwWid, 4 , NULL);
dwFind++;
// тут уже непосредственно реализация программы, если в нашем таргете попался моб с идентичным WID, смотрим кто это
// если 18710 значит это злая гусеница, красим трей иконку в красный цвет
// если 18711 в зеленый, ну и если не гусеницы то в серенький
if (dwTarget == dwWid){
switch (dwPlId) {
case 18710:TrayIcon1->IconIndex = 1;break;
case 18711:TrayIcon1->IconIndex = 2;break;
default: TrayIcon1->IconIndex = 0;
;}}
// дальше считаем сферки в 5 или 27 комнате
// просто инкрементируем счетчик, по названию переменной думаю понятно где какой шарик
switch (dwPlId) {
case 18716: iRed++; break;
case 18717: iWhite++; break;
case 18718: iBlue++; break;
default:
;}
dwPlId=0;
}
// если мы прочитанное количество мобов совпало с GA +8 +24 +14: - Mobs count останавливаем циклы, дабы не гонять память в пустую
if (dwFind == dwPlCount) break;
}
if (dwFind == dwPlCount) break;
}
};
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TrayIcon1Click(TObject *Sender)
{
ShowMessage(
"Красных: " + IntToStr(iRed) + "\n\r" +
"Белых: " + IntToStr(iWhite) + "\n\r" +
"Синих: " + IntToStr(iBlue));
}
//---------------------------------------------------------------------------
Ну вот)) критикуйте)) будем добавлять править и все такое
xCube ([Ссылки могут видеть только зарегистрированные и активированные пользователи]).
Смещения ру офф клиента можно взять тут ([Ссылки могут видеть только зарегистрированные и активированные пользователи])
Написана на Codegear C Builder 2007 ( впрочем от 6 билдера до XE, особо разницы нету...с юникодом ток немного)
4Zhyk.ru ([Ссылки могут видеть только зарегистрированные и активированные пользователи]*********/fd15774)
Описание проекта: на форме у нас 4 компонента: PopupMenu, ImageList, Timer, TrayIcon.
Итак: чего нам надо сделать
1. Посчитать шарики в 5, 27 комнатах
2. Смотреть в таргет на предмет наличия гусениц.
Что для этого потребуется: Смотреть свой таргет, заглянем в смещения
GAME_ADD = A5BFCC;
Структура игрока:
GA +20: HostPlayer Struct
+B0C; -Target
Смотреть окружающих нас мобов:
GA +8 +24 +14: - Mobs count
Структура мобов
GA +8 +24 +18 +[I*4] + (+0)^J +4: (I in [0..300 hex])
+11C MobWorldID
+120 MobID
Как нам надо читать: если хотим прочитать кто у нас в таргете, смотрим выше описанные смещения и считываем 4 бафта по смещению GA, далее по полученному смещению +20, далее по полученному + B0C - получили таргет.
С мобами интересная вещь, самому лень было сразу осиливать))
там где +0 это значит считать в это адресе адрес след. элемента
(+0)^J это наши страницы памяти
в итоге у нас получится такая охинея
1-я страница GA +8 +24 +18 +[I*4] +4:
2-я страница GA +8 +24 +18 +[I*4] +0 +4:
2-я страница GA +8 +24 +18 +[I*4] +0 +0 +4:
и так далее, особо останавливаться не будем, по ходу поймем :)
а теперь вгрыземся в код
смотрим комменты после // дабы оставить код рабочим
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
DWORD dwPid=0;
HANDLE hProc;
int iRed, iWhite, iBlue;
int iGA = 0xa5bfcc; // Гейм Адресс
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Exit1Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
Form1->Hide(); // прячемся в трей
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
// собственно по таймеру, у меня он кажется установле в 400мс, запускаем основную обработку
// объявляем переменные, замечу борланд как то не адекватно читает память если не инизиализировать переменные заранее
DWORD dwPlCount=0;
DWORD dwMass=0, dwPlId=0;
DWORD dwWid=0;
DWORD dwTarget=0;
iRed=0; iWhite=0; iBlue=0;
//Ищем окошко с названием Perfect World и получаем его хенлд
HWND hHandle = FindWindow("ElementClient Window","Perfect World");
//По хэндлу получаем индефикатор процесса, чтобы читать память
GetWindowThreadProcessId(hHandle, &dwPid);
//открываем выбранный процесс
hProc = OpenProcess(0xfff, false, dwPid);
if (hProc) // проверяем открыли
{
DWORD dwTemp = 0;
DWORD dwFind = 0;
//----------------------читаем таргет GA +20 +B0C
ReadProcessMemory(hProc, (LPVOID) iGA, &dwTemp, 4, NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x20), &dwTarget, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTarget + 0xb0c), &dwTarget, 4 , NULL);
//---------------------------------------------------------
//-------------------------читаем структуру мобов GA + 20 мы уже считали в dwTemp, дальше +8 +24
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x8), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x24), &dwTemp, 4 , NULL);
//------------------------------- в dwTemp GA +20 +8 +24, и считываем +14 это таргет, а GA +20 +8 +24 +18 это начало массива
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x14), &dwPlCount, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x18), &dwMass, 4 , NULL);
//-----------самая порнуха [I*4] + (+0)^J +4: (I in [0..300 hex])
// делаем это в 2х циклах, переменная i это J
// ii это I, 300 в 16тиричной это 768
for (int i = 0; i < 5; i++) {
for (int ii = 0; ii < 768; ii++)
{
//считали GA +8 +24 +18 +[I*4]
ReadProcessMemory(hProc, (LPVOID) (dwMass + ii*4), &dwTemp, 4 , NULL);
// тут пошел разбор страниц
switch (i){
case 1:
//1-я страница GA +8 +24 +18 +[I*4] +4:
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
break;
case 2:
//2-я страница GA +8 +24 +18 +[I*4] +0 +4: и далее...
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
break;
case 3:
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
break;
case 4:
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
break;
case 5:
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
ReadProcessMemory(hProc, (LPVOID) (dwTemp), &dwTemp, 4 , NULL);
break;
default:
;}
// и вот почти пройдена наша 3х этажная хнень)) дочитываем +4 до GA +8 +24 +18 +[I*4] + (+0)^J +4 . тут мы добрались уже до самой ячейки структуры моба
ReadProcessMemory(hProc, (LPVOID) (dwTemp+4), &dwTemp, 4 , NULL);
// мда, названа dwPlId, писал для игроков :) вобщем не пугаемся это айдишка моба GA +8 +24 +18 +[I*4] + (+0)^J +4 +120 MobID
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x120), &dwPlId, 4 , NULL);
// если в записи чтото присутствует читаем и WorldID моба GA +8 +24 +18 +[I*4] + (+0)^J +4 +11C MobWorldID
if (dwPlId > 0){
ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x11c), &dwWid, 4 , NULL);
dwFind++;
// тут уже непосредственно реализация программы, если в нашем таргете попался моб с идентичным WID, смотрим кто это
// если 18710 значит это злая гусеница, красим трей иконку в красный цвет
// если 18711 в зеленый, ну и если не гусеницы то в серенький
if (dwTarget == dwWid){
switch (dwPlId) {
case 18710:TrayIcon1->IconIndex = 1;break;
case 18711:TrayIcon1->IconIndex = 2;break;
default: TrayIcon1->IconIndex = 0;
;}}
// дальше считаем сферки в 5 или 27 комнате
// просто инкрементируем счетчик, по названию переменной думаю понятно где какой шарик
switch (dwPlId) {
case 18716: iRed++; break;
case 18717: iWhite++; break;
case 18718: iBlue++; break;
default:
;}
dwPlId=0;
}
// если мы прочитанное количество мобов совпало с GA +8 +24 +14: - Mobs count останавливаем циклы, дабы не гонять память в пустую
if (dwFind == dwPlCount) break;
}
if (dwFind == dwPlCount) break;
}
};
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TrayIcon1Click(TObject *Sender)
{
ShowMessage(
"Красных: " + IntToStr(iRed) + "\n\r" +
"Белых: " + IntToStr(iWhite) + "\n\r" +
"Синих: " + IntToStr(iBlue));
}
//---------------------------------------------------------------------------
Ну вот)) критикуйте)) будем добавлять править и все такое