|
Как написать бота с нуля [Borland C++ Builder 6] - Разработка ПО для Perfect World - Бюро разработчиков Zhyk.Ru: создание ботов, снифферов и прочих программ для Perfect World |
03.06.2012, 21:15
|
#31
|
|
|
|
Пехотинец
|
Регистрация: 21.03.2012
Сообщений: 83
Популярность: 1178
Сказал(а) спасибо: 18
Поблагодарили 101 раз(а) в 53 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
________________
╔═╗
║ ˑ ˑ ╬ ╬
╚═╝
Последний раз редактировалось dwa83; 03.06.2012 в 21:22.
|
|
|
07.09.2012, 13:25
|
#32
|
|
|
|
Разведчик
|
Регистрация: 06.09.2012
Сообщений: 2
Популярность: 10
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
Возник вопрос.
Как считать с клиента имя персонажа или моба.
Смещение уже нашел попытался найти, но выдало полный бред, если не сложно, то пожалуйста в виде рабочего кода. Я пишу на C++ Borland
|
|
|
07.09.2012, 15:08
|
#33
|
|
|
|
Рыцарь
|
Регистрация: 19.11.2008
Сообщений: 385
Популярность: 13343
Сказал(а) спасибо: 124
Поблагодарили 217 раз(а) в 109 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
|
Цитата: |
|
|
|
|
|
|
|
|
|
Я пишу на C++ Borland
|
|
|
|
|
|
Код на другом языке думаю не составит труда прочитать?) Пишу на FreeBASIC, возможно тебе поможет чем нибудь.
Руоф 1.4.5 Build 2305
Код:
#include "windows.bi"
Dim PID As UInteger
Dim hProcess As Handle
Dim buffer As dWord
Dim outBuffer as WString * 8
GetWindowThreadProcessId(FindWindow("ElementClient Window", "Perfect World"), @PID)
hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, PID)
'---------------------------------------------
ReadProcessMemory(hProcess, &hA571E0, @buffer, sizeof(buffer), NULL)
ReadProcessMemory(hProcess, buffer+&h1C, @buffer, sizeof(buffer), NULL)
ReadProcessMemory(hProcess, buffer+&h34, @buffer, sizeof(buffer), NULL)
ReadProcessMemory(hProcess, buffer+&h66C, @buffer, sizeof(buffer), NULL)
ReadProcessMemory(hProcess, buffer+&h0, @outBuffer, sizeof(outBuffer), NULL)
'---------------------------------------------
CloseHandle(hProcess)
print outBuffer
sleep
Офсеты взял из темы sumikot`а.
|
|
|
08.09.2012, 00:50
|
#34
|
|
|
|
Пехотинец
|
Регистрация: 21.03.2012
Сообщений: 83
Популярность: 1178
Сказал(а) спасибо: 18
Поблагодарили 101 раз(а) в 53 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
Считываю в массив а затем перевожу из юникода в анси. Я на билдере шестом пишу, потому приходится с юникодом колдовать, так как более поздние версии с ним норм работают.
1)определить массив для хранения считанных символов
2)считать юникод-строку имени или названия
(в основном строки в клиенте в юникоде, 2 байта на символ, строка оканчивается двойным нулём)
3)преобразовать в удобную для работы строку(я неревожу в анси)
Вот например функция считывания для структуры READER из этой статьи
addr - адрес строки юникода
mass - массив в который считываем
len - количество считываемых байт
Код:
void READER::Read_Mass(DWORD addr, char* mass, int len)
{
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,pid);
ReadProcessMemory(hProcess,(void*)addr,mass,len,0);
CloseHandle(hProcess);
}
Преобразовываю вот такой ерундой(самому не обязательно такие "велосипеды" писать, должны быть готовые средства)
len - количество СИМВОЛОВ(не байт), или проще указать размерность_массива/2
Код:
AnsiString READER::UnicodeToAnsi(char *mass, int len)
{
AnsiString txt="";
for (int i=0; i<len; i++)
{
BYTE lo=mass[i*2];
BYTE hi=mass[i*2+1];
if ((lo==0)&&(hi==0)) break;
if ((lo==1)&&(hi==4)) {lo=168; hi=0;}
if ((lo==81)&&(hi==4)) {lo=184; hi=0;}
if (hi==4) lo+=176;
txt+=(char)lo;
}
return txt;
}
Применительно к статье можно использовать например так
Код:
DWORD str_addr=...вычисляем адрес строки по нужным оффсетам
char str[40]={0};
get.Read_Mass(str_addr, str, 40); // считываем
AnsiString string=get.UnicodeToAnsi(str, 20);
________________
╔═╗
║ ˑ ˑ ╬ ╬
╚═╝
|
|
|
08.09.2012, 17:21
|
#35
|
|
|
|
Разведчик
|
Регистрация: 06.09.2012
Сообщений: 2
Популярность: 10
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
прописал все вроде как надо, но выдает ошибку:
[BCC32 Error] Reader.h(46): E2316 'READER::myName(char *)' is not a member of 'READER'
|
|
|
11.09.2012, 22:43
|
#36
|
|
|
|
Пехотинец
|
Регистрация: 21.03.2012
Сообщений: 83
Популярность: 1178
Сказал(а) спасибо: 18
Поблагодарили 101 раз(а) в 53 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
|
Цитата: |
|
|
|
|
|
|
|
|
|
прописал все вроде как надо, но выдает ошибку:
[BCC32 Error] Reader.h(46): E2316 'READER::myName(char *)' is not a member of 'READER'
|
|
|
|
|
|
Пишет что функция myName не является членом READER, вы видимо не обьявили эту функцию в h-файле внутри структуры READER, либо обьявление отличается от реализации, и потому считается другой функцией(проверьте одинаковость в обьявлении и самой реализации). Реализация функции то написана, но как член структуры она видимо не указана.
Внутри
struct READER
{
...
...
// обьявите функцию, чтобы компилятор знал что она существует как метод структуры(класса)
возвращаемый_тип myName(char *);
...
...
}
________________
╔═╗
║ ˑ ˑ ╬ ╬
╚═╝
|
|
|
13.10.2012, 14:01
|
#37
|
|
|
|
Разведчик
|
Регистрация: 05.10.2012
Сообщений: 4
Популярность: 10
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
Здравствуйте!!! Пытаюсь повторить программу но столкнулся с рядом проблем:
1. в MVS C++ 2010 отсутствуют шрифты «AnsiString», вышел из положения путем использования ссылок на WCHAR массив.
2. Чтобы вывести pid в элемент Label:
Label1->Caption=bot.client.pid;
его надо преобразовать в тип System string^, если ктот знает какой функцией это можно сделать подскажите пожалуйста.
Разобрался!!! DWORD это тот же unsigned long для работы с ним есть клас System .UInt32:
Код:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
UInt32 Сpid;
Cpid=bot.client.pid;
this->label1->Text=Cpid.ToString();
}
3. При проверке программы путем вывода результатов в консоль:
Код:
#include <Windows.h>
#include "stdafx.h"
#include <TlHelp32.h>
#include <iostream>
using namespace std;
void Init(void);
DWORD pid; // Идентификатор Процесса
DWORD PIDByProcName(WCHAR *ProcessName); // определение pid по имени процесса
int _tmain(int argc, _TCHAR* argv[])
{
Init();
char c;
cout<<pid;
cin>>c;
return 0;
}
void Init(void)
{ pid= PIDByProcName(L"elementclient.exe"); }
DWORD PIDByProcName(WCHAR *ProcessName)
{
PROCESSENTRY32 ProcessEntry;
HANDLE pHandle;
DWORD pid;
pHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
ProcessEntry.dwSize = sizeof(ProcessEntry);
pid=0;
bool loop=Process32First(pHandle, &ProcessEntry);
while (loop)
{
loop=Process32Next(pHandle, &ProcessEntry);
if (*ProcessEntry.szExeFile == *ProcessName)
{
pid = ProcessEntry.th32ProcessID;
CloseHandle(pHandle);
break;
}
}
return pid;
}
Выдает ID "explorer.exe", хотя если вместо "elementclient.exe" подставить какой-то другой процесс ID выдает верный. Если можно подскажите почему?
Разобрался!!! оператор if сравнивает по первому элементу строки и выдает 1 соответствующий вариант которым является explorer.exe
Последний раз редактировалось wolfser; 19.10.2012 в 01:03.
|
|
|
25.10.2012, 20:57
|
#38
|
|
|
|
Разведчик
|
Регистрация: 20.10.2012
Сообщений: 2
Популярность: 178
Сказал(а) спасибо: 0
Поблагодарили 6 раз(а) в 2 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
Как считать имя персонажа? Пишу в MS VS 2008. Пока получается считать только один какой-то иероглиф.
Последний раз редактировалось coder007; 25.10.2012 в 22:02.
|
|
|
26.10.2012, 16:04
|
#39
|
|
|
|
Разведчик
|
Регистрация: 16.01.2010
Сообщений: 6
Популярность: -75
Сказал(а) спасибо: 2
Поблагодарили 19 раз(а) в 2 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
Читаю так
Код:
WCHAR ch[n];
ReadProcessMemory(hProcess,(void*)(name_addr),&ch,(n*2),0);
где n- кол-во считываемых символов.
|
|
|
28.10.2012, 18:16
|
#40
|
|
|
|
Разведчик
|
Регистрация: 05.10.2012
Сообщений: 4
Популярность: 10
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
Для получения ID процесса использую класс Process:
Код:
void CClient::PIDByProcName(String ^PrNm)
{
Process ^PrEn;
PrEn=PrEn->GetProcessesByName(PrNm)[0];
Cpid=PrEn->Id;
ProcNm=PrEn->ToString();
}
клас Process позволяет определить сколько процессов с одинаковым именем запущенно и выбрать нужный.
Вопрос: можно ли читать память процесса и записывать в неё через класс Process?
|
|
|
30.10.2012, 15:03
|
#41
|
|
|
|
Разведчик
|
Регистрация: 16.01.2010
Сообщений: 6
Популярность: -75
Сказал(а) спасибо: 2
Поблагодарили 19 раз(а) в 2 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
|
|
|
30.10.2012, 19:52
|
#42
|
|
|
|
Разведчик
|
Регистрация: 05.10.2012
Сообщений: 4
Популярность: 10
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
|
Цитата: |
|
|
|
|
|
|
|
|
|
Да, можно. Зная pid процесса получаешь его handle, через OpenProcess. Затем этот handle передаешь в ф-и (Read/Write)ProcessMemory
|
|
|
|
|
|
Класс System:: Diagnostics::Process не имеет членов OpenProcess и (Read/Write)ProcessMemory. Есть возможность связать с файлом на диске для запуска приложения с параметрами метод Start(...\*.exe), и только при такой инициализации процесса задается сойство Handle.
Я его использцю для получения pid, путем подключения к уже запущеному процессу методом GetProcessesByName(String), этот метод возвращает массив компонентов Process связанных с запущенными процессами имеющими одно название.
Как на меня, то намного проще получить pid через класс Process чем описанным в данной теме методом.
Кому интересно:
Код:
//проверяю запущен хоть 1 клиент
Int32 colpr=System::Diagnostics::Process::GetProcessesByName(L"elementclient").Length;
if(colpr)
{
//если запущен добавляю итем в comboBox1 c именем перса
//для дальнейшего выбора нужного окна
Client *bot=new Client[colpr]; //создаю указатель структуру типа Client
//и выделяю память под масив типа Client
int i;
for (i=0; i<=colpr-1; i++)
{//инициализирую масыв типа Client
System::Diagnostics::Process ^process=process->GetProcessesByName(L"elementclient")[i];
(bot+i)->pid=process->Id;
//читаю имя перса
String ^str;
for (int j=0 ; j<=20; j++)
{
str=str+(((bot+i)->Read_Char((bot+i)->NmAdr()+0x0)+j)->ToString());
}
//добавляю итем с именем перса в comboBox1
comboBox1->Items->Add(str);
str="";//обнуляю имя перса
}
delete[] bot;// удаляю масив типа Client (делать объязательно!!! Чтоб не засорять память)
}
else
{
//если не запущено ни одного окна с игрой вывожу предупреждение
this->label3->Text = L"Клиент не запущен!!!";
}
Как видно из примера можно сразу определить количество запущенных окон с игрой, определить pid каждого окна и т.д. насколько позволит смекалка
Ps: начал использовать класс Process чтоб облегчить себе поиск pid так как в МВСтудии 2010 нет строки AnsiString, а функции чтения и записи памяти использую предложеные в данной теме.
|
|
|
16.11.2012, 14:29
|
#43
|
|
|
|
Пехотинец
|
Регистрация: 21.03.2012
Сообщений: 83
Популярность: 1178
Сказал(а) спасибо: 18
Поблагодарили 101 раз(а) в 53 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
Код:
void FindClients()
{
char classname[256];
kolbot=0; // количество запущеных клиентов
DWORD pid;
HWND Wd=FindWindow(0,0); // Найдем первое окно верхнего уровня любого класса
while (Wd!=0) // Если такое окно существует
{
GetClassName(Wd,classname,100); // получим имя класса окна
AnsiString cn=classname; // для удобства пихнём
if (cn=="ElementClient Window") // сравним с классом пв
{
SetWindowText(Wd,анси-что-то.c_str()); // если наше окно, переименуем во что-то
GetWindowThreadProcessId(Wd,&pid);
bot[kolbot].client.Init(pid); // тут в массив пид
bot[kolbot].client.wind=Wd; // тут в массив хэндл
kolbot++; // количество найденных окон прибавим
}
Application->ProcessMessages(); // Дадим возможность поработать другим
Wd=GetNextWindow(Wd,GW_HWNDNEXT); // Найдем следующее окно в системе.
}
}
я так сделал, но это bcb
________________
╔═╗
║ ˑ ˑ ╬ ╬
╚═╝
Последний раз редактировалось dwa83; 16.11.2012 в 14:32.
|
|
|
07.12.2012, 00:34
|
#44
|
|
|
|
Разведчик
|
Регистрация: 06.10.2012
Сообщений: 3
Популярность: 10
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
Доброго времени суток! Пишу на С++ MVS 2010. Делал всё по гайду. Проблема такая: при выполнении WaitForSingleObject(hProcThread, INFINITE); клиент вылетает с ошибкой (просто закрывается). В дебаге ничего не пишет. Дебаг не заходит в ассемблерную вставку. Код:
Код:
BYTE INJECTOR::InjectAndExecute(void *Func, void* Params) {
HANDLE hProcThread;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid) ;
if (!hProcess) {
return 0; // выйдем из функции если не удалось открыть процесс
}
WriteProcessMemory(hProcess, pFunction, Func, 250, NULL);
WriteProcessMemory(hProcess, pParams, Params, 250, NULL);
hProcThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)pFunction, pParams, NULL, NULL);
if(hProcThread == INVALID_HANDLE_VALUE) {
return 0; // не удалось создать поток
}
WaitForSingleObject(hProcThread, INFINITE); // ожидаем завершения работы потока
CloseHandle(hProcThread); // закрываем хэндл нашего потока
CloseHandle(hProcess); // закрываем хэндл процесса
return 1; // успешная инъекция и выполнение кода
}
Ассемблерная вставка:
Код:
void Target_THREAD(DWORD* WID) {
DWORD Id = *WID;
__asm {
MOV EDI, Id // Помещаем WID в регистр EDI
MOV EBX, 0x00630790 // Помещаем адрес клиентской функции таргета
MOV EAX,DWORD PTR DS:[BA] //
PUSH EDI // ; /Arg1
MOV ECX, DWORD PTR DS: [EAX+0x20] // ; |
ADD ECX, 0x0EC // ; |
CALL EBX // ; \elementc.00606A70
}
}
Подскажите кто советом, в чём может быть проблема?
|
|
|
07.12.2012, 06:40
|
#45
|
|
|
|
Разведчик
|
Регистрация: 07.09.2010
Сообщений: 9
Популярность: 10
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Как написать бота с нуля [Borland C++ Builder 6]
|
Цитата: |
|
|
|
|
|
|
|
|
|
Доброго времени суток! Пишу на С++ MVS 2010. Делал всё по гайду. Проблема такая: при выполнении WaitForSingleObject(hProcThread, INFINITE); клиент вылетает с ошибкой (просто закрывается). В дебаге ничего не пишет. Дебаг не заходит в ассемблерную вставку. Код:
Код:
BYTE INJECTOR::InjectAndExecute(void *Func, void* Params) {
HANDLE hProcThread;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid) ;
if (!hProcess) {
return 0; // выйдем из функции если не удалось открыть процесс
}
WriteProcessMemory(hProcess, pFunction, Func, 250, NULL);
WriteProcessMemory(hProcess, pParams, Params, 250, NULL);
hProcThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)pFunction, pParams, NULL, NULL);
if(hProcThread == INVALID_HANDLE_VALUE) {
return 0; // не удалось создать поток
}
WaitForSingleObject(hProcThread, INFINITE); // ожидаем завершения работы потока
CloseHandle(hProcThread); // закрываем хэндл нашего потока
CloseHandle(hProcess); // закрываем хэндл процесса
return 1; // успешная инъекция и выполнение кода
}
Ассемблерная вставка:
Код:
void Target_THREAD(DWORD* WID) {
DWORD Id = *WID;
__asm {
MOV EDI, Id // Помещаем WID в регистр EDI
MOV EBX, 0x00630790 // Помещаем адрес клиентской функции таргета
MOV EAX,DWORD PTR DS:[BA] //
PUSH EDI // ; /Arg1
MOV ECX, DWORD PTR DS: [EAX+0x20] // ; |
ADD ECX, 0x0EC // ; |
CALL EBX // ; \elementc.00606A70
}
}
Подскажите кто советом, в чём может быть проблема?
|
|
|
|
|
|
Адрес функции таргета 00681F50
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Похожие темы
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
[Помогите!] Написать бота!
|
romel |
Вопросы и ответы, обсуждения |
2 |
10.02.2012 18:39 |
[Помогите!] Как же написать бота?
|
ХАМнаМИЛЛИОН |
Школа Читера |
3 |
29.07.2011 20:58 |
[Помогите!] написать бота
|
@ndreyk@ |
Общение и обсуждение Perfect World |
32 |
23.07.2011 13:32 |
[Помогите!] хочу написать бота!
|
Фестер Аддамс |
Общение и обсуждение (Тюряга ВК) |
7 |
31.01.2011 22:36 |
Заявление об ответственности / Список мошенников
Часовой пояс GMT +4, время: 15:15.
|
|