|
Как написать бота с нуля [Borland C++ Builder 6] - Разработка ПО для Perfect World - Бюро разработчиков Zhyk.Ru: создание ботов, снифферов и прочих программ для Perfect World |
20.10.2017, 12:15
|
#91
|
|
|
|
Разведчик
|
Регистрация: 12.03.2015
Сообщений: 10
Популярность: 10
Сказал(а) спасибо: 1
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
|
Цитата: |
|
|
|
|
|
|
|
|
|
Может читаешь что-то не так? Покажи хотя бы код, офсеты, скажи версию PW, сервер...
|
|
|
|
|
|
Версия PW - 1.5.5 RUOFF
Оффсеты:
Код:
#define BASE 0x0DFCBA0 //Базовый адрес
#define GAME 0x1C //Игра
#define CHARACTER 0x34 //Структура Игрока
#define CR_HP 0x4C8 //ХП
#define CR_MHP 0x51C //Макс. ХП
#define CR_MP 0x4CC //МП
#define CR_MMP 0x520 //Макс. МП
#define CR_LVL 0x4C0 //Уровень перса
Код по сути брал практически полностью отсюда, вот весь READER.h
Код:
#include <Windows.h>
#include <Tlhelp32.h>
#include <iostream>
using namespace std;
class READER
{
public:
DWORD PID;
DWORD PersStruct;
READER()
{
DWORD buff = read(GAME);
PersStruct = read(buff + CHARACTER);
}
//Получаем LVL
int myLVL()
{
return read(PersStruct + CR_LVL);
}
//Считываем данные из клиента
DWORD read(DWORD addr)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID); // открываем процесс
DWORD value;
ReadProcessMemory(hProcess, (void*)addr, &value, 4, 0); // считываем значение по заданному адресу
CloseHandle(hProcess); // закроем процесс
return value; // вернём считанное значение
}
};
Среда - VS2017
Последний раз редактировалось BJIoM; 20.10.2017 в 17:19.
Причина: Заправил код в теги
|
|
|
20.10.2017, 18:00
|
#92
|
|
|
|
Разведчик
|
Регистрация: 06.02.2013
Сообщений: 24
Популярность: 10
Сказал(а) спасибо: 8
Поблагодарили 3 раз(а) в 2 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
Ошибка в том что ты считываешь не по GameAddress, а по самому оффсету 1C :
а нужно сначала считать значение в БА, прибавить к считанному значению GameOffset (1C) и считать по тому адресу что получил
Код:
DWORD temp1 = read(BASE);
DWORD temp2 = read(temp1 + GAME);
PersStruct = read(temp2 + CHARACTER);
или же можно использовать твой код, но подставлять фактический GameAddress, т.к. он статичен как и базовый(для руофа 0FE00200 вродь)
|
|
|
20.10.2017, 19:15
|
#93
|
|
|
|
Разведчик
|
Регистрация: 12.03.2015
Сообщений: 10
Популярность: 10
Сказал(а) спасибо: 1
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
Попробовал оба варианта и все равно считывает -858993460 вместо 75
Кстати, при попытке считать HP и MP выдается это же значение
Последний раз редактировалось BJIoM; 20.10.2017 в 19:20.
Причина: Попробовал считать другие значения
|
|
|
20.10.2017, 22:24
|
#94
|
|
|
|
Разведчик
|
Регистрация: 06.02.2013
Сообщений: 24
Популярность: 10
Сказал(а) спасибо: 8
Поблагодарили 3 раз(а) в 2 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
|
|
|
20.10.2017, 22:32
|
#95
|
|
|
|
Разведчик
|
Регистрация: 12.03.2015
Сообщений: 10
Популярность: 10
Сказал(а) спасибо: 1
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
в main.cpp как раз таки и идет вызов этого метода
Сегодня переписал чисто для себя этот метод, добавив вывод действий в лог
Код:
//Получаем LVL
int myLVL()
{
log.log("WORK", "Считываем уровень перса...");
int check = read(PersStruct + CR_LVL);
if ((check < 1) || (check > 105))
{
log.log("ERROR", "Считанное из памяти значение (" + to_string(check) + ") выходит за пределы диапазона уровней (1-105)");
return ERR_LVL;
}
else return check;
}
Аналогично сделал функции для хп и мп
В итоге лог:
Код:
[DEBUG] PID процесса "elementclient.exe": 10880
[WORK] Считываем уровень перса...
[ERROR] Считанное из памяти значение (-858993460) выходит за пределы диапазона уровней (1-105)
[WORK] Считываем здоровье перса...
[ERROR] Считанное из памяти значение (-858993460) отрицательно, хотя здоровье не может быть отрицательно
[WORK] Считываем ману перса...
[ERROR] Считанное из памяти значение (-858993460) отрицательно, хотя мана не может быть отрицательна
|
|
|
21.10.2017, 00:58
|
#96
|
|
|
|
Рыцарь
|
Регистрация: 19.11.2008
Сообщений: 385
Популярность: 13343
Сказал(а) спасибо: 124
Поблагодарили 217 раз(а) в 109 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
|
Цитата: |
|
|
|
|
|
|
|
|
в main.cpp как раз таки и идет вызов этого метода
Сегодня переписал чисто для себя этот метод, добавив вывод действий в лог |
|
|
|
|
|
Пробовал читать жёстко? Без ридера, используя лишь ReadProcessMemory?
Добавлено через 7 минут
И ещё, где ты вот это вот потерял? А то, открыть память открыл, прочитать прочитал, закрыл, а что открывал, откуда читал, не ясно...
Код:
hWindow = FindWindow("ElementClient Window", "Perfect World")
GetWindowThreadProcessId(hWindow, @PID)
FreeBASIC если что, winapi само собой...
Последний раз редактировалось Sirioga; 21.10.2017 в 01:09.
Причина: Добавлено сообщение
|
|
|
21.10.2017, 01:46
|
#97
|
|
|
|
Разведчик
|
Регистрация: 12.03.2015
Сообщений: 10
Популярность: 10
Сказал(а) спасибо: 1
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
|
Цитата: |
|
|
|
|
|
|
|
|
|
Пробовал читать жёстко? Без ридера, используя лишь ReadProcessMemory?
|
|
|
|
|
|
Нет, попробую
Как я уже говорил, я взял код из гайда, просто переименовал метод (Read_32 -> read)
|
Цитата: |
|
|
|
|
|
|
|
|
DWORD READER::Read_32(DWORD addr)
{
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,pid) ; // открываем процесс
DWORD value;
ReadProcessMemory(hProcess,(void*)addr,&value,4,0) ; // считываем значение по заданному адресу
CloseHandle(hProcess); // закроем процесс
return value; // вернём считанное значение
} |
|
|
|
|
|
И вроде как по логике он и так должен работать
Последний раз редактировалось BJIoM; 21.10.2017 в 14:05.
|
|
|
23.10.2017, 03:03
|
#98
|
|
|
|
Разведчик
|
Регистрация: 12.03.2015
Сообщений: 10
Популярность: 10
Сказал(а) спасибо: 1
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
Заметил возможную причину неправильного считывания
Добавив в конструктор отправку инфы в лог (заодно убрал класс клиента, сделав поиск PID вашим методом прямо в классе READER, переименовав его в GAME) обнаружил такое
лог:
Код:
[DEBUG] Данные из BASE ADDRES: 3435973836
[DEBUG] + GA: 3435973836
[DEBUG] + CHARACTER: 3435973836
Код конструктора:
Код:
GAME()
{
HWND hWnd = FindWindow(NULL, "Perfect World");
GetWindowThreadProcessId(hWnd, &PID);
log.log("DEBUG", "PID процесса \"elementclient.exe\": " + to_string(PID));
DWORD buff = read(BA);
log.log("DEBUG", "Данные из BASE ADDRES: " + to_string(buff));
buff = read(buff + GA);
log.log("DEBUG", "+ GA: " + to_string(buff));
PersStruct = read(buff + CHARACTER);
log.log("DEBUG", "+ CHARACTER: " + to_string(PersStruct));
}
Почему-то получаются одинаковые значения и из-за этого уровень, здоровье и мана считываются неправильными значениями
Последний раз редактировалось BJIoM; 23.10.2017 в 03:07.
|
|
|
23.10.2017, 07:00
|
#99
|
|
|
|
Пехотинец
|
Регистрация: 27.03.2012
Сообщений: 70
Популярность: 4766
Сказал(а) спасибо: 82
Поблагодарили 37 раз(а) в 20 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
я в свое время на такую же проблему натыкался (как я тебя понимаю), но у меня были свои заморочки из-за нераспространенного языка. открывай cheat engine и смотри память клиента так - что ты там читаешь.
в лог выводи адрес и значение, лежащее в этом адресе.
основной затык у меня сейчас в считывании юникода и непонятных +0+0+0+0 страниц
почему оффсет ga+struct+name+0 дает ник перса, а не ga+struct+name
есть отличная тема по этому топику, может ты плохо искал: https://zhyk.ru/forum/showthread.php?t=144367
Код:
HWND hWnd = FindWindow(NULL, "Perfect World");
GetWindowThreadProcessId(hWnd, &PID);
log.log("DEBUG", "PID процесса \"elementclient.exe\": " + to_string(PID));
DWORD buff = read(BA);
log.log("DEBUG", "Данные из BASE ADDRES: " + to_string(buff));
buff = read(buff + GA);
log.log("DEBUG", "+ GA: " + to_string(buff));
PersStruct = read(buff + CHARACTER);
log.log("DEBUG", "+ CHARACTER: " + to_string(PersStruct));
а сколько у тебя GA?
GA=+1C
CHARACTER=+20 или +34
не перепутал ли ты GA = 9C1514 c GA=+1C
Последний раз редактировалось sabbaot01; 23.10.2017 в 08:05.
|
|
|
23.10.2017, 12:16
|
#100
|
|
|
|
Разведчик
|
Регистрация: 12.03.2015
Сообщений: 10
Популярность: 10
Сказал(а) спасибо: 1
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
|
|
|
23.10.2017, 17:22
|
#101
|
|
|
|
Пехотинец
|
Регистрация: 27.03.2012
Сообщений: 70
Популярность: 4766
Сказал(а) спасибо: 82
Поблагодарили 37 раз(а) в 20 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
Цитата:
открывай cheat engine и смотри память клиента так - что ты там читаешь.
Сначала грешил на оффсеты, но CheatEngine по тому же адресу все нормально прочитал, как привести выводимое значение в нормальный вид?
Я ЧИТАЛ ЭТО
вот так религия позволяет сделать в CheatEngine?
|
|
|
23.10.2017, 18:40
|
#102
|
|
|
|
Рыцарь
|
Регистрация: 19.11.2008
Сообщений: 385
Популярность: 13343
Сказал(а) спасибо: 124
Поблагодарили 217 раз(а) в 109 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
|
Цитата: |
|
|
|
|
|
|
|
|
Почему-то получаются одинаковые значения и из-за этого уровень, здоровье и мана считываются неправильными значениями |
|
|
|
|
|
Покажи полный код своей канители, а не куски, что было ясно и понятно где затык.
Мне вообще кажется, что ты читаешь не из памяти клиента, а непойми откуда вообще.
|
|
|
23.10.2017, 18:54
|
#103
|
|
|
|
Разведчик
|
Регистрация: 12.03.2015
Сообщений: 10
Популярность: 10
Сказал(а) спасибо: 1
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
GAME.h
Код:
#include <Windows.h>
#include <Tlhelp32.h>
#include "LOGGER.h"
#include "OFFSETS.h"
using namespace std;
class GAME
{
public:
DWORD PID;
DWORD PersStruct;
LOG log;
GAME()
{
HWND hWnd = FindWindow(NULL, "Perfect World");
GetWindowThreadProcessId(hWnd, &PID);
log.log("DEBUG", "PID процесса \"elementclient.exe\": " + to_string(PID));
DWORD buff = read(BA);
log.log("DEBUG", "Данные из BASE ADDRES: " + to_string(buff));
buff = read(buff + GA);
log.log("DEBUG", "+ GA: " + to_string(buff));
PersStruct = read(buff + CHARACTER);
log.log("DEBUG", "+ CHARACTER: " + to_string(PersStruct));
}
//Получаем LVL
int myLVL()
{
log.log("WORK", "Считываем уровень перса...");
int check = read(PersStruct + CR_LVL);
if ((check < 1) || (check > 105))
{
log.log("ERROR", "Считанное из памяти значение (" + to_string(check) + ") выходит за пределы диапазона уровней (1-105)");
return ERR_LVL;
}
else
{
log.log("FINE", "Уровень персонажа :" + to_string(check));
return check;
}
}
//Получаем HP
int myHP()
{
log.log("WORK", "Считываем здоровье перса...");
int check = read(PersStruct + CR_HP);
if ((check < 0))
{
log.log("ERROR", "Считанное из памяти значение (" + to_string(check) + ") отрицательно, хотя здоровье не может быть отрицательно");
return ERR_HP;
}
else
{
log.log("FINE", "Здоровье персонажа :" + to_string(check));
return check;
}
}
//Получаем MP
int myMP()
{
log.log("WORK", "Считываем ману перса...");
int check = read(PersStruct + CR_MP);
if ((check < 0))
{
log.log("ERROR", "Считанное из памяти значение (" + to_string(check) + ") отрицательно, хотя мана не может быть отрицательна");
return ERR_MP;
}
else
{
log.log("FINE", "Мана персонажа :" + to_string(check));
return check;
}
}
//Считываем данные из клиента
DWORD read(DWORD addr)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID); // открываем процесс
DWORD value;
ReadProcessMemory(hProcess,(void*) addr, &value, 4, 0); // считываем значение по заданному адресу
CloseHandle(hProcess); // закроем процесс
return value; // вернём считанное значение
}
};
OFFSETS.h
Код:
//ОФФСЕТЫ
#define BA 0x0DFCBA0 //Базовый адрес
#define GA 0x1C //Игра
#define CHARACTER 0x34 //Структура Игрока
#define CR_HP 0x4C8 //ХП
#define CR_MHP 0x51C //Макс. ХП
#define CR_MP 0x4CC //МП
#define CR_MMP 0x520 //Макс. МП
#define CR_LVL 0x4C0 //Уровень перса
//Коды ошибок
#define ERR_LVL 1 //Ошибка: Уровень за пределами интервала (1-105)
#define ERR_HP 2 //Ошибка: Отрицательный уровень здоровья
#define ERR_MP 3 //Ошибка: Отрицательный уровень маны
Main.cpp
Код:
#include "Headers\GAME.h"
#include <conio.h>
#include <locale.h>
using namespace std;
const bool bDebug = true;
int main()
{
setlocale(LC_ALL, "RUSSIAN");
GAME PW;
if (PW.myLVL() != ERR_LVL) cout << PW.myLVL() << "\n";
if (PW.myHP() != ERR_HP) cout << PW.myHP() << "\n";
if (PW.myMP() != ERR_MP) cout << PW.myMP() << "\n";
system("Pause");
return 0;
}
Логгер думаю не обязательно, но пусть
Код:
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
extern const bool bDebug;
class LOG
{
public:
LOG()
{
ofstream log;
log.open("log.log", ios::trunc);
}
//Запись в лог
void log(string TAG, string TEXT)
{
ofstream log;
log.open("log.log", ios::app | ios::out);
if ((TAG != "DEBUG") || (bDebug == true))
{
log << "[" << TAG << "] " << TEXT << '\n';
cout << "[" << TAG << "] " << TEXT << '\n';
}
};
};
|
|
|
29.10.2017, 15:43
|
#104
|
|
|
|
Пехотинец
|
Регистрация: 27.03.2012
Сообщений: 70
Популярность: 4766
Сказал(а) спасибо: 82
Поблагодарили 37 раз(а) в 20 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
пытаюсь в ооп, код на с++/с#/делфи тяжко читать, поэтому спрошу на авось:
как организовать классы с персонажами?
т.е. в качестве имени объектов я хотел бы иметь имя персонажа, но имя персонажа и прочее в классе персонажа присвается после создания такого объекта.
что обычно стоит подразумевается под this ?
|
|
|
30.10.2017, 19:48
|
#105
|
|
|
|
Пехотинец
|
Регистрация: 21.03.2012
Сообщений: 83
Популярность: 1178
Сказал(а) спасибо: 18
Поблагодарили 101 раз(а) в 53 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
выполнился конструктор класса. а далее
DWORD PID;
DWORD PersStruct;
LOG log;
GAME()
{
PID = 1;// может так к примеру попробовать, чтоб пид не был равен 0
HWND hWnd = FindWindow(NULL, "Perfect World");
GetWindowThreadProcessId(hWnd, &PID); // пид скорее всего = 0
|
Цитата: |
|
|
|
|
|
|
|
|
Функция GetWindowThreadProcessId возвращает обратно идентификатор потока, который создал определяемое окно, но необязательно идентификатор процесса, который создал это окно..... Если этот параметр - не ПУСТО (NULL), функция GetWindowThreadProcessId копирует идентификатор процесса в переменную; иначе, она этого не делает.. |
|
|
|
|
|
//здесь значение пид в лог и сравнение с реальным в диспетчере
....
}
А вообще мне кажется, нецелевое использование GetWindowThreadProcessId, хотя хз.
пс:
this->свойство\метод
доступ к методу или свойству текущего класса(внутри реализации которого пишется).
Имеет смысл указывать, если вдруг имя метода класса или свойство совпадает с локальной(глобальной) функцией\переменной. Чтоб компилятор мог отличить их.
к примеру:
void Class1::Method1(int var1)
{
this->var1 = var1; // тут свойству класса Class1 с именем var1 присваивается значение другой переменной с таким же именем.
}
других причин обязательного использования this-> у меня, например, пока не было вроде.
}
Добавлено через 16 минут
|
Цитата: |
|
|
|
|
|
|
|
|
т.е. в качестве имени объектов я хотел бы иметь имя персонажа, но имя персонажа и прочее в классе персонажа присвается после создания такого объекта. |
|
|
|
|
|
может конструктор с параметром(именем перса к примеру), внутри которого по значению этого имени и инициализируются параметры отдельного экземпляра? Немного разывчатый вопрос..
class Pers
{
public:
Pers(char * GameName); // как-то инициализирует внутренности по игровому имени
}
Pers priest("Nagibator777");
Pers tank("AlioshaVoin");
А зачем? использование нескольких окон одновременно?
________________
╔═╗
║ ˑ ˑ ╬ ╬
╚═╝
Последний раз редактировалось dwa83; 30.10.2017 в 20:05.
Причина: Добавлено сообщение
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Похожие темы
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
[Помогите!] Написать бота!
|
romel |
Вопросы и ответы, обсуждения |
2 |
10.02.2012 17:39 |
[Помогите!] Как же написать бота?
|
ХАМнаМИЛЛИОН |
Школа Читера |
3 |
29.07.2011 19:58 |
[Помогите!] написать бота
|
@ndreyk@ |
Общение и обсуждение Perfect World |
32 |
23.07.2011 12:32 |
[Помогите!] хочу написать бота!
|
Фестер Аддамс |
Общение и обсуждение (Тюряга ВК) |
7 |
31.01.2011 21:36 |
Заявление об ответственности / Список мошенников
Часовой пояс GMT +4, время: 23:07.
|
|