Регистрация Главная Сообщество
Сообщения за день Справка Регистрация
Навигация
Zhyk.org LIVE! Реклама на Zhyk.org Правила Форума Награды и достижения Доска "почета"

Работаем с хештейблами на примере мобов вокруг нас

-

Разработка ПО для Perfect World

- Бюро разработчиков Zhyk.Ru: создание ботов, снифферов и прочих программ для Perfect World

Ответ
 
Опции темы
Старый 28.07.2011, 14:54   #1
 Сержант
Аватар для jdark
 
jdark скоро будет известенjdark скоро будет известенjdark скоро будет известен
Регистрация: 30.08.2010
Сообщений: 121
Популярность: 249
Сказал(а) спасибо: 10
Поблагодарили 78 раз(а) в 23 сообщениях
 
По умолчанию Работаем с хештейблами на примере мобов вокруг нас

На примере написанной мной программки
xCube.
Смещения ру офф клиента можно взять [Ссылки могут видеть только зарегистрированные пользователи. ]

Написана на Codegear C Builder 2007 ( впрочем от 6 билдера до XE, особо разницы нету...с юникодом ток немного)

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

Описание проекта: на форме у нас 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));
}
//---------------------------------------------------------------------------

Ну вот)) критикуйте)) будем добавлять править и все такое
  Ответить с цитированием
Пользователь сказал cпасибо:
388672 (24.08.2013)
Старый 28.07.2011, 17:08   #2
 Сержант
Аватар для whoami
 
whoami на правильном путиwhoami на правильном пути
Регистрация: 07.09.2010
Сообщений: 124
Популярность: 147
Сказал(а) спасибо: 22
Поблагодарили 87 раз(а) в 18 сообщениях
 
По умолчанию Re: Работаем с хештейблами на примере мобов вокруг нас

jdark, это как раз к вопросу о том, что "программа написанная на Borland Builder ... работает пошустрее [чем под .NET]". На самом деле, не так важно на чём пишут программу, важно как это делают. Твой алгоритм обхода списка мобов - просто жутко не оптимальный по времени исполнения, громоздкий, да ещё в редких случаях обходит не всех мобов. Правда, для задачи подсчёта сфер в кубе это не так критично, а вот если ты варкланов на згд ищешь, такой обход списка никуда не годится.

На самом деле, нет там никаких "страниц памяти", есть массив односвязных списков. Их и надо обходить по очереди. Правильный обход списка есть в PWFrameWork:
[Ссылки могут видеть только зарегистрированные пользователи. ]
  Ответить с цитированием
Старый 29.07.2011, 09:57   #3
 Сержант
Аватар для jdark
 
jdark скоро будет известенjdark скоро будет известенjdark скоро будет известен
Регистрация: 30.08.2010
Сообщений: 121
Популярность: 249
Сказал(а) спасибо: 10
Поблагодарили 78 раз(а) в 23 сообщениях
 
По умолчанию Re: Работаем с хештейблами на примере мобов вокруг нас

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

Последний раз редактировалось jdark; 29.07.2011 в 10:43.
  Ответить с цитированием
Старый 29.07.2011, 10:40   #4
 Сержант
Аватар для whoami
 
whoami на правильном путиwhoami на правильном пути
Регистрация: 07.09.2010
Сообщений: 124
Популярность: 147
Сказал(а) спасибо: 22
Поблагодарили 87 раз(а) в 18 сообщениях
 
По умолчанию Re: Работаем с хештейблами на примере мобов вокруг нас

jdark, нет, подсчёт у тебя тоже кривой. Одни и те же ячейки считываются из памяти много раз. Переписывать на С++ обход списка мне лень, а на C# код уже есть, я ссылку дал. На словах тоже объяснил, что надо сделать: считать сразу весь массив по GA +8 +24 +18, сразу все 0х300 элементов, потом по отдельности пройти до конца все эти 0х300 списков (большинство из них будут пустыми или из 1 элемента).
  Ответить с цитированием
Старый 29.07.2011, 10:52   #5
 Сержант
Аватар для jdark
 
jdark скоро будет известенjdark скоро будет известенjdark скоро будет известен
Регистрация: 30.08.2010
Сообщений: 121
Популярность: 249
Сказал(а) спасибо: 10
Поблагодарили 78 раз(а) в 23 сообщениях
 
По умолчанию Re: Работаем с хештейблами на примере мобов вокруг нас

идею понял
как нибудь сделаю

кстати поч думаешь что одни и теже много раз?
линейно пробегает последовательно, повторов там нету

единственно ты правильно сказал что лучше сделать 1 чтение страницы, а потом ее разобрать чем считывать по 4 байта

Последний раз редактировалось jdark; 02.08.2011 в 07:43.
  Ответить с цитированием
Старый 21.08.2011, 05:57   #6
 Сержант
Аватар для jdark
 
jdark скоро будет известенjdark скоро будет известенjdark скоро будет известен
Регистрация: 30.08.2010
Сообщений: 121
Популярность: 249
Сказал(а) спасибо: 10
Поблагодарили 78 раз(а) в 23 сообщениях
 
По умолчанию Re: Работаем с хештейблами на примере мобов вокруг нас

Сделал по аналогии с игроками рядом))) оптимизировал на сколько хватило фантазии ))

Код:
DWORD dwPlCount=0;
    DWORD dwGuild=0;
	DWORD dwMass=0, dwPlId=0, name = 0 ;

    ListView1->Clear();
	WideChar wcName [64];

	dwPid = dwFindClient[ComboBox1->ItemIndex];


	if (ComboBox1->ItemIndex > -1 )
	{
		hProc = OpenProcess(0xfff, false, dwPid);
		if (hProc)
		{
				DWORD dwTemp = 0;
				DWORD dwFind = 0;

				ReadProcessMemory(hProc, (LPVOID) iGA, &dwTemp, 4, NULL);
				ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x8), &dwTemp, 4 , NULL);
				ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x20), &dwTemp, 4 , NULL);
				ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x14), &dwPlCount, 4 , NULL);
				ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x18), &dwMass, 4 , NULL);

				Edit1->Text = dwPlCount;

				ReadProcessMemory(hProc, (LPVOID) (dwMass), &str, sizeof(str), NULL);
				for (int ii = 0; ii < 768; ii++)
					{
							for (int i = 1; i < 5; i++)
							{
								if (str[ii])
								{
									dwTemp = str[ii];
									switch (i){
										case 5:
											ReadProcessMemory(hProc, (LPVOID) (dwTemp),    &dwTemp, 4 , NULL);
										case 4:
											ReadProcessMemory(hProc, (LPVOID) (dwTemp),    &dwTemp, 4 , NULL);
										case 3:
											ReadProcessMemory(hProc, (LPVOID) (dwTemp),    &dwTemp, 4 , NULL);
										case 2:
											ReadProcessMemory(hProc, (LPVOID) (dwTemp),    &dwTemp, 4 , NULL);
										case 1:
											ReadProcessMemory(hProc, (LPVOID) (dwTemp+4), &dwTemp, 4 , NULL);
									default:;}

									if (dwTemp) {
										ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x460), &dwPlId, 4 , NULL);
										ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x5E4), &dwGuild, 4 , NULL);

										ReadProcessMemory(hProc, (LPVOID) (dwTemp + 0x618), &name, 4 , NULL);
										ReadProcessMemory(hProc, (LPVOID) (name), &wcName, 64 , NULL);

										dwFind++;

										ListItem = ListView1->Items->Add();
										ListItem->Caption = IntToStr(dwFind);
										ListItem->SubItems->Add(dwPlId);
										ListItem->SubItems->Add(wcName);
										ListItem->SubItems->Add(dwGuild);
									}
									if (dwFind == dwPlCount) break;
							}
						}
						if (dwFind == dwPlCount) break;

					}

		} else Label1->Caption = Time().TimeString() +  " Bind fail";
	}



}
  Ответить с цитированием
Старый 22.08.2011, 13:12   #7
 Сержант
Аватар для whoami
 
whoami на правильном путиwhoami на правильном пути
Регистрация: 07.09.2010
Сообщений: 124
Популярность: 147
Сказал(а) спасибо: 22
Поблагодарили 87 раз(а) в 18 сообщениях
 
По умолчанию Re: Работаем с хештейблами на примере мобов вокруг нас

jdark, меня всегда удивляет код типа
Код:
for(int i=0; i<10; ++i)
switch(i)
{
  case 0: ...
  case 1: ...
  case 2: ...
...
}
Чем-то подобным меня "радовали" мои студенты-первокурсники, но они не рвались писать ботов для онлайн-игр, гайды по этому делу, и даже по-моему курсовые сами не писали, а скачивали из интернетов
Но таки да, эта версия будет работать гораздо шустрее.
  Ответить с цитированием
Старый 22.08.2011, 17:52   #8
 Сержант
Аватар для jdark
 
jdark скоро будет известенjdark скоро будет известенjdark скоро будет известен
Регистрация: 30.08.2010
Сообщений: 121
Популярность: 249
Сказал(а) спасибо: 10
Поблагодарили 78 раз(а) в 23 сообщениях
 
По умолчанию Re: Работаем с хештейблами на примере мобов вокруг нас

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

а так дальше уже хз куда оптимизировать))) с линейным списком разве что ковыряться
  Ответить с цитированием
Старый 24.08.2013, 19:12   #9
Читер-спонсор
 Разведчик
Аватар для 388672
 
388672 на правильном пути
Регистрация: 01.07.2009
Сообщений: 21
Популярность: 44
Сказал(а) спасибо: 76
Поблагодарили 15 раз(а) в 5 сообщениях
 
По умолчанию Re: Работаем с хештейблами на примере мобов вокруг нас

На C#, только с именами окружающих мобов

Код:
for (int i = 0; i < 5; i++)
            {

                for (int ii = 0; ii < 768; ii++)
                {
                    var mob = MyPersonage.memory.ChainReadInt32(PWOffssAndAddrss.base_address);
                    mob = MyPersonage.memory.ChainReadInt32(mob + 0x1c);
                    mob = MyPersonage.memory.ChainReadInt32(mob + 0x1c);
                    mob = MyPersonage.memory.ChainReadInt32(mob + 0x24);
                    mob = MyPersonage.memory.ChainReadInt32(mob + 0x18);

                    mob = MyPersonage.memory.ChainReadInt32(mob + ii * 0x4);
                    switch (i)
                    {
                        case 1:
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            break;
                        case 2:
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            break;
                        case 3:
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            break;
                        case 4:
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            break;
                        case 5:
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            mob = MyPersonage.memory.ChainReadInt32(mob + 0x0);
                            break;
                        default:
                            break;
                    }

                    mob = MyPersonage.memory.ChainReadInt32(mob + 0x4);
                    mob = MyPersonage.memory.ChainReadInt32(mob + 0x260);
                    string mob_name = MyPersonage.memory.ChainReadString_Unicode(mob + 0x0, 80);
                    listBox1.Items.Add(new ListBoxItem() { Content = mob_name });
                
                }
            }

Последний раз редактировалось 388672; 24.08.2013 в 19:21.
  Ответить с цитированием
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[Пакеты] Отправляем сообщение ВСЕМ вокруг Zephy Баги и читы для Aion 14 10.07.2011 15:50
[Обсуждение] Танцы с бубном вокруг Инэта shamrik Треп 8 20.07.2010 01:57
[Программа] Работаем с базой данных PTS. RaRus Базы серверов и брут 0 11.07.2010 23:28

Заявление об ответственности / Список мошенников

Часовой пояс GMT +4, время: 21:17.

Пишите нам: [email protected]
Copyright © 2024 vBulletin Solutions, Inc.
Translate: zCarot. Webdesign by DevArt (Fox)
G-gaMe! Team production | Since 2008
Hosted by GShost.net