Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Perfect World
You last visited: Today at 19:22

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Rus. server

Discussion on Rus. server within the Perfect World forum part of the MMORPGs category.

Reply
 
Old 12/27/2009, 08:45   #1156
 
elite*gold: 0
Join Date: Jul 2008
Posts: 43
Received Thanks: 16
Quote:
Originally Posted by Shamanpovt View Post
Ребят, подскажите: делаю таргет инекцией. код такой:
MOV_EAX(Dec("0098ADDC"))
MOV_EAX_DWORD_PTR_EAX()
MOV_EDI(Dec("801050D6"))
MOV_EDI_DWORD_PTR_EDI()
PUSH_EDI()
MOV_ECX_DWORD_PTR_EAX_ADD(Dec("20"))
ADD_ECX(Dec("EC"))
MOV_EDX(Dec("005B7B70"))
CALL_EDX()
Но клиент завершается аварийно. В чём ошибка?
Смущает, вот это:
MOV_EDI(Dec("801050D6"))
MOV_EDI_DWORD_PTR_EDI()
PUSH_EDI()

попробуй вместо этого:
MOV_EDI(Dec("801050D6"))
PUSH_EDI()

Насколько помню, там просто ID моба в стек запихать надо. А ты в регистр EDI пихаешь ID, а потом пытаешься этот ID трактовать как некий адрес и берёшь значение по этому адресу и потом пихаешь его в стек.
dj_al is offline  
Old 12/27/2009, 09:33   #1157
 
elite*gold: 0
Join Date: Nov 2009
Posts: 96
Received Thanks: 31
Quote:
Originally Posted by dj_al View Post
Смущает, вот это:
MOV_EDI(Dec("801050D6"))
MOV_EDI_DWORD_PTR_EDI()
PUSH_EDI()

попробуй вместо этого:
MOV_EDI(Dec("801050D6"))
PUSH_EDI()

Насколько помню, там просто ID моба в стек запихать надо. А ты в регистр EDI пихаешь ID, а потом пытаешься этот ID трактовать как некий адрес и берёшь значение по этому адресу и потом пихаешь его в стек.
Все правильно там было - вот образец ..
в стек прячутся не данные а указатель на них

mov eax, BaseAddress;
mov eax, dword ptr[eax];

mov edi, MonsterID;
mov edi, [edi];
push edi;

mov ecx, dword ptr[eax+0x20];
add ecx, 0xEC;

mov edx, CallAddress;
call edx;

- можно и так и так написать и попробывать - клиента из-за этого именно не выбивает
просто ID цели будет не тот - а это не критично

Скорее всего потому что ты посылаешь не функцию а OPcode
функция она сама прячет все регистры перед работой потом востанавливает
а в Автоите надо тебе перед и после поставить pushad() .... pop(edi) popad() возможно и команду RET() ..
origmas is offline  
Old 12/27/2009, 10:30   #1158
 
muzhig's Avatar
 
elite*gold: 0
Join Date: Sep 2009
Posts: 85
Received Thanks: 27
Quote:
Originally Posted by silkytail View Post
Любопытно было бы взглянуть на логику, если это как-либо обобщено, а не тупо захардкожена последовательность действий.
Я тут хочу замахнуться на что-то типа goal-oriented аи, но пока не очень ясно, как это можно сделать.
лично я рассматриваю бота как автомат. У автоматов есть та называемые устойчивые состояния. Ну в игре например это указатель текущего действия, насколько я понимаю.
у бота моего тоже есть флаг действия.
0-ничего не делаем
1-летим к waypoint
2-летим к выбранной цели (цель лубого плана: нпс, моб, рес, игрок итд)
3-активируем цель(убиваем моба, бафаем)
255-блокировка ЧС (черезвычайная ситуация- когда продолжать работу как обычно бот уже не может. Это грозит здоровью или еще чем нибудь. есть еще флаг причины блокировки, чтобы потом эту блокировку снять)

(эти устойчивые состояния добавятся, я так думаю)

Вся фишка в универсальности понятия цели- минимальная единица, частица общей Цели (пока бред, но я счас поясню)

К примеру, Цель- это сбор ресов. Тогда эта самая цель- или подцель - это самый близкий,выгодный, не занятый ресурс.
Если главная Цель это фарм, тогда подцели это мобы и лут.
ну и.т.д. и.т.п.

Эти подцели можно, при желании, выстраивать в цепочки, ставить в зависимость друг от друга, ставить им важность и тд.

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

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

Например, текущая цель не равна найденной цели, следовательно, либо текущая цель неактуальна, либо новая цель более выгодна. (бывает, например, летит к ресурсу какому нибудь- потом бац, прямо около перса респнулся новый ресурс- нужно забить на тот что далеко и собрать тот что под ногами) Действие очевидно- двигаться к новой цели, тк она более выгодна.

потом при следующем проходе потока, он смотрит: ага, я двигаюсь к цели такой то. Ага, расстояние до цели достаточно для ее активации (копнуть рес, ударить моба итд). Значит посылаем клиенту команду активировать, переключаем состояние в режим активации.
Следующий проход потока:

Ага, мы активируем цель. Сколько процентов готово (жизнь моба, процесс копания) Если уже все, то переключаем в режим 0 (ничего не делания)

В новой итерации, в самом начале мы ищем новую цель. И снова по кругу- полететь к цели, активировать.

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

В случае ЧС ставится блокировка, потом например прыгаем на полет, поднимаемся повыше, ждем- это в случае с мобами или здоровьем/маной
С поломкой оружия/брони или переполнением инвентаря- ТП в город, или пешком/полетом. Там продаться/купить что нужно, отремонтироваться и го назад, к ближайшей точке маршрута/цели, если таковая есть.
В ситуации с нападением на бота другим игроком, можно продумать что делать- например свалить в город. или свалить в радиальном направлении и орать ему в ПМ типа "Ты че творишь?" итд.

В общем, блокировка - это способ обойти нестандартные ситуации.
После чего переводит состояние в режим 0.

Вот, я вроде описал задумку. весьма вкраце, правда)))
Здесь остается место для универсальности- это поиск цели, способ ее активации и блокировки в непредвиденных ситуациях. В принципе, я так думаю, этим алгоритмом можно описать практически любые варианты поведения. Другое дело, что это только основа- а частные случаи нужно сидеть и писать все равно. А чтобы бот стал по настоящему универсальным.. это надо сдохнуть похоже :-)

Кстати, трек, состоящий из waypoint-ов не обязательно делать кольцом.
думаю, его можно разветвить как угодно, главное заложить логику потом, как перескакивать с точки на точку.

ЗЫ, специально для origmas:
Потоки про которые я говорю, запускаются у меня, в моей программе(никуда не инжектятся).
Внутри тела простого потока, например, обновляющего списки объектов, стоит бесконечный цикл.

while Active do
begin
{Refresh here}
sleep(500);
end;

Ну поток следящий за движением к точке более сложный, но идея все та же.
поток выключается когда ставишь Active:= false.
Так он сам понимает, что пора выходить, сохраняет что нужно и делает Terminate.
Надеюсь, доступно объяснил)))
muzhig is offline  
Thanks
3 Users
Old 12/27/2009, 10:53   #1159
 
elite*gold: 0
Join Date: Nov 2009
Posts: 96
Received Thanks: 31
Quote:
Originally Posted by muzhig View Post
..остается место для универсальности..
Вот это я понимаю - Русишь Бот получится .. еще чуть-чуть и перейдем к Экспертным системам .. поиск априорных вероятностей, базы знаний и т.д.
Система Флагов состояний - очень полезна и даже необходима - сам Клиент основывается на проверке таких флагов.
Спасибо за совет - обязательно возьму на вооружение ..))
origmas is offline  
Old 12/27/2009, 11:01   #1160
 
elite*gold: 0
Join Date: Nov 2009
Posts: 69
Received Thanks: 5
У меня пока запросы к боту чуть-чуть поскромнее Цель находит в таргет не берет(. От себя добавил CloseHandle(Proc); перед CallRemoteFunction(Proc,(LPVOID)PriorID); и OpenProc(); после, а то видеть клиента переставал

Novohyd is offline  
Old 12/27/2009, 11:28   #1161
 
elite*gold: 0
Join Date: Nov 2009
Posts: 96
Received Thanks: 31
Novohyd

Еще раз попробуй такой вариант - сег. ночью спец. пробывал - РАБОТАЕТ, насчет
процесса - да, ты правильно заметил ..

//---------------------------------------------------------------------------
static DWORD WINAPI SelectMonster(LPCVOID lpParam )
{ DWORD BaseAddress = 0x0098ADDC;
DWORD CallAddress = 0x005B7B70;
DWORD MonsterID = (DWORD)lpParam;
__try
{ __asm
{ mov eax, BaseAddress;
mov eax, dword ptr[eax];
mov edi, MonsterID;
mov edi, [edi];
push edi;
mov ecx, dword ptr[eax+0x20];
add ecx, 0xEC;
mov edx, CallAddress;
call edx;
}
}
__except(1){}
return 0;
}
//---------------------------------------------------------------------------
bool CBotDlg::CallRemoteFunction(HANDLE hProcess, LPVOID lpParam)
{ HANDLE hThread = NULL;
LPVOID ThreadCodeAddr = NULL; //Inject Fuction Address after allocate
LPVOID ThreadDataAddr = NULL; //Inject Fuction Stack Address after allocate
LPVOID Func = SelectMonster; //Inject Function
DWORD ThreadID; //
DWORD dwWritten; //
ThreadCodeAddr=VirtualAllocEx(hProcess,NULL,256,ME M_COMMIT,PAGE_READWRITE);
WriteProcessMemory(hProcess,ThreadCodeAddr,Func,25 6,&dwWritten);
ThreadDataAddr=VirtualAllocEx(hProcess,NULL,64,MEM _COMMIT,PAGE_READWRITE);
WriteProcessMemory(hProcess,ThreadDataAddr,&lpParam,64,&dwWritten);
hThread = CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START _ROUTINE)ThreadCodeAddr,ThreadDataAddr,NULL,&ThreadID);
if (!hThread) return false;
else WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
VirtualFreeEx(hProcess,ThreadCodeAddr,256,MEM_RELE ASE);
VirtualFreeEx(hProcess,ThreadDataAddr, 64,MEM_RELEASE);
CloseHandle(hProcess);
return true;
}
//---------------------------------------------------------------------------
origmas is offline  
Thanks
1 User
Old 12/27/2009, 11:32   #1162
 
silkytail's Avatar
 
elite*gold: 0
Join Date: Jun 2008
Posts: 142
Received Thanks: 13
Quote:
Originally Posted by muzhig View Post
лично я рассматриваю бота как автомат. У автоматов есть та называемые устойчивые состояния. Ну в игре например это указатель текущего действия, насколько я понимаю.
Ты на самом деле частично описываешь goap, только наверно не знашь, что это такое Между goap и автоматами (fsm) разница на самом деле принципиально, хоть их и можно совмещать при желании.
Например для иллюстрации можно поставить цель "убивать мобов", для которой есть план:
условия: оружие не сломано, инвентарь не полон, банки в наличии, етц
действие <догоняем, убиваем, етц, это тоже подпланы>
эффект: мобы умирают

Если в процессе выполнения нарушается какое-то из условий, например ломается оружие, то нам нужно будет найти последовательность действий, которая приводит нас в состояние "оружие не сломано". Допустим, у нас будет такой план "починка":
условия: стоим у торговца
действие: чинимся
эффект: оружие не сломано
А чтобы дойти до торговца от текуцего места, нам пригодится план "перемещение"
условия: <что тут написать не очень представляю>
действие: <бежим, летим, пользуемся телепортом?>
Эффект: нахождение у торговца

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

Так вот, вопросов посему множество.
Например, как можно формализовать планы и цели так, чтобы это не было зашито только в коде и можно было это настраивать? Какой-то свой редактор или компилируемый язык?
Или, как придать некой гибкости всему этому - например раз мы все равно дошли до торговца, как выразить то, что заодно неплохо было бы продать лут и купить банок? Да еще и зайти к банкиру выгрузить полезное. Есть ощущение, что цели и планы надо снабдить весами и динамически их рассчитывать.

Ты, дарагой мужиг, что-то уже как-то реализовал, или тоже фантазируешь ? Поделися кодом если что есть.
silkytail is offline  
Old 12/27/2009, 11:58   #1163
 
elite*gold: 0
Join Date: Apr 2009
Posts: 237
Received Thanks: 403
Quote:
Кстати, трек, состоящий из waypoint-ов не обязательно делать кольцом.
думаю, его можно разветвить как угодно, главное заложить логику потом, как перескакивать с точки на точку.
У моего бота карта представлена в виде графа, вершины которого, например, места сбора реса, нип’ы и т.д., ребра – «расстояние» (вернее, время, требуемое для достижение точки с учетом всех трех координат и скорости передвижения). Выбор ближайшей точки – алгоритм Дейкстры. Возникла исключительная ситуация, потребовалось боту банками запастись, бот легко находит кратчайший путь к цели, если нет возможности телепортироваться туда…
dwar is offline  
Old 12/27/2009, 11:58   #1164
 
elite*gold: 0
Join Date: Nov 2009
Posts: 96
Received Thanks: 31
Ну че Novohyd - прививается зараза - Али как ?

-- беги за Клинским ..))
origmas is offline  
Old 12/27/2009, 11:59   #1165
 
elite*gold: 0
Join Date: Oct 2009
Posts: 20
Received Thanks: 2
Вот такой код:
$PID = WinGetProcess("Element Client")
PUSHAD()
MOV_EAX(Dec("0098ADDC"))
MOV_EAX_DWORD_PTR_EAX()
MOV_EDI(Dec("801050D6"))
MOV_EDI_DWORD_PTR_EDI()
PUSH_EDI()
MOV_ECX_DWORD_PTR_EAX_ADD(Dec("20"))
ADD_ECX(Dec("EC"))
MOV_EDX(Dec("005B7B70"))
CALL_EDX()
POPAD()
RET()
INJECTCODE($PID)

Пробовал закомментить MOV_EDI_DWORD_PTR_EDI() - всё равно аварийное завершение(
Shamanpovt is offline  
Old 12/27/2009, 12:02   #1166
 
elite*gold: 0
Join Date: Nov 2009
Posts: 96
Received Thanks: 31
Quote:
Originally Posted by Shamanpovt View Post
Вот такой код:
$PID = WinGetProcess("Element Client")
PUSHAD()
MOV_EAX(Dec("0098ADDC"))
MOV_EAX_DWORD_PTR_EAX()
MOV_EDI(Dec("801050D6"))
MOV_EDI_DWORD_PTR_EDI()
PUSH_EDI()
MOV_ECX_DWORD_PTR_EAX_ADD(Dec("20"))
ADD_ECX(Dec("EC"))
MOV_EDX(Dec("005B7B70"))
CALL_EDX()
POPAD()
RET()
INJECTCODE($PID)

Пробовал закомментить MOV_EDI_DWORD_PTR_EDI() - всё равно аварийное завершение(
стек востановлен некорректно - в него ж EDI прятали - надо вынуть от туда значение - просто POP() какой-нить перед POPAD()
origmas is offline  
Old 12/27/2009, 12:10   #1167
 
elite*gold: 0
Join Date: Oct 2009
Posts: 20
Received Thanks: 2
Quote:
Originally Posted by origmas View Post
стек востановлен некорректно - в него ж EDI прятали - надо вынуть от туда значение - просто POP() какой-нить
изменил так:
$PID = WinGetProcess("Element Client")
PUSHAD()
MOV_EAX(Dec("0098ADDC"))
MOV_EAX_DWORD_PTR_EAX()
MOV_EDI(Dec("801050D6"))
MOV_EDI_DWORD_PTR_EDI()
PUSH_EDI()
MOV_ECX_DWORD_PTR_EAX_ADD(Dec("20"))
ADD_ECX(Dec("EC"))
MOV_EDX(Dec("005B7B70"))
CALL_EDX()
POP_EDI()
POPAD()
RET()
INJECTCODE($PID)

Всё равно аварийное завершение(
Shamanpovt is offline  
Old 12/27/2009, 12:26   #1168
 
elite*gold: 0
Join Date: Nov 2009
Posts: 96
Received Thanks: 31
Quote:
Originally Posted by Shamanpovt View Post

Всё равно аварийное завершение(
ты пока это все так оставь - проверь - коды Opcode функций, но там вроде пральные. А вот сама функция INJECTCODE($PID) посмотреть надо какой ты пользуешься, если из GEObot - то она там под сомнением - из общественной копилки возьми попробуй.
origmas is offline  
Old 12/27/2009, 12:31   #1169
 
elite*gold: 0
Join Date: Apr 2009
Posts: 237
Received Thanks: 403
Quote:
Originally Posted by Shamanpovt View Post
изменил так:
POP_EDI()
POPAD()
RET()
popad = pop EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX
т.е., достаточно оставить popad (если здесь под POPAD() подразумевается аналог команды ассемблера)
dwar is offline  
Old 12/27/2009, 12:36   #1170
 
elite*gold: 0
Join Date: Jul 2008
Posts: 43
Received Thanks: 16
Quote:
Originally Posted by origmas View Post
mov edi, MonsterID;
mov edi, [edi];
push edi;
Вах молодца... А щас включи мозг и подумай что ты РЕАЛЬНО запихнул в стек таким образом.

mov edi, MonsterID; - запихиваешь ID монстра, которое по сути просто идентификатор (порядковый номер моба на сервере)

mov edi, [edi]; - начинаешь трактовать этот ID монстра как адрес и пытаешься по этому адресу взять данные и запихнуть в регистр edi

push edi; - этот мусор полученный выше - ты пихаешь в стек.

К тому кто с автоитом мучается, я не знаю в чём у тебя причина, может некорректно формируются OPCODE, либо ты инжектируешь неправильно (что скорее всего).

Вот мой код на Delphi, который работает как со старым клиентом, так и с новым, всё зависит от того, какие адреса передал через структуру праметров (для нового клиента $0098addc и $005b7b70):
Code:
procedure SelectMonster(MonID: PParams); stdcall;
(*
PW Ru Off 1.4.1
0045B30D - a1 1c 6b 97 00             - mov eax,[00976b1c] : 009771A0
0045B312 - 57                         - push edi
0045B313 - 8b 48 20                   - mov ecx,[eax+20]
0045B316 - 81 c1 ec 00 00 00          - add ecx,000000ec
0045B31C - e8 1f 2d 15 00             - call 005ae040

PW Ru Off 1.4.1 Build 2273
0045C30D - a1 dc ad 98 00             - mov eax,[0098addc] : 0098B460
0045C312 - 57                         - push edi
0045C313 - 8b 48 20                   - mov ecx,[eax+20]
0045C316 - 81 c1 ec 00 00 00          - add ecx,000000ec
0045C31C - e8 4f b8 15 00             - call 005b7b70
*)
var
  CallAddress: pointer;
  BaseAddress, P1: DWORD;
begin
  BaseAddress := MonID^.BaseAddr;
  CallAddress := Pointer(MonID^.FuncAddr);
  P1:=MonID^.Param1;
  asm
    pushad
    mov edi, P1
    mov eax, BaseAddress
    mov eax, [eax]
    push     edi
    mov ecx, DWORD PTR [eax+$20]
    add ecx, $EC
    call     CallAddress
    popad
  end;
end;
dj_al is offline  
Reply




All times are GMT +1. The time now is 19:23.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.