Всем привет!
Решил выложить свой вариант PW FrameWork. Назвал я его PW FrameWork 2.0.
Совместимости между первоначальной версией и версией 2.0 нет.
Он переделан из первой версии и в нем использованы наработки TBXin и whoami и возможно еще кого то.
Классы, которые я изменял имеют пометку krukovis. Остальные классы из проекта исключены, до лучших времен.
Так они не откомментированы и как их использовать мне пока не понятно. Если разберусь - включу в проект.
Немного общих комментариев по классам:
Общий упор сделан на ООП - объектно ориентированное программирование. Я все старался представить в виде самостоятельных объектов. И все взаимодействие в виде взаимодействия объектов.
WinApi - просто сборник win api. Вынесен в отдельный класс для удобства поиска.
ClientFinder - с этого класс начинается подключение к клиенту.
Он принимает в качестве аргументов: базовый адрес клиента, смещение к структуре игры, смещение к структуре персонажа и смещение к адресу имени персонажа.
Возвращает список окон, если получится определить имя персонажа - то в виде имен персонажа, если нет - в виде имен окон.
Окно представленно классом ClientWindow.
MemoryWork - основной класс для работы с памятью.
В нем собраны удобные функции для чтения памяти и представления полученных данных в нужном формате: Int32, Int16, String и т.д
Этот класс основной для всех следующих классов, т.к. работа идет с памятью.
Он принимает в качестве аргумента класс ClientWindow и работает именно с этим окном. Что примечательно, можно создать экземпляр класса
MemoryWork для любого запущенного окна игры и можно будет работать из одной программы с несколькими окнами. Можно управлять хоть целой командой.
ASM - класс облегчающий инжект асм-функций. Вспомогательный класс для активизации различных функций клиента.
Конструктор класса ASM принимает в качестве параметра экземпляр класса MemoryWork. И соответственно инжектит функции в окно, которое связано с этим классом MemoryWork.
PacketSender - класс облегчающий использование пакетов. А точнее отправляющий пакеты. Принимает в качестве аргумента класс Packet.
Packet - статический класс - огромная база пакетов. Все очень в удобном виде.
OffsetRetriever - класс для поиска смещений и адресов по маске. Как пользоваться - пример в исходниках.
OffsetsAndAddresses - сборник смещений и адресов, использующихся в других классах
GraphicUserInterface - это набор классов описыващий графические объекты в игре и позволяющий запускать различные кнопки.
и
GameStructs - класс описывающий игровые структуры.
По поводу последних двух классов хотелось бы остановиться подробнее. В двух этих классах я хочу предложить новую концепцию работы с игровыми объектами.
Они реализуют принцип ООП и описывают окна, контролы на них, персонажа, его команду и т.д. как объекты.
При такой реализации с ними очень легко работать. Наример, чтобы нажать на кнопку нужно сделать следующее:
Создать экземпляр класса PWGUI:
PWGUI GUI = new PWGUI(SelectedWindow);//где SelectedWindow - это какое то окно PW описанное с помощью класса ClientWindow.
И работать с его свойствами и методами, как вы обычно привыкли:
//отображаем форму Win_LoginButton - форму ввода логина и пароля
GUI.Form("Win_LoginButton").Visible = true;
//открываем окно смены сервера:
GUI.Form("Win_LoginButton").Control("Btn_ChangeServer").CommandStart();
Аналогично можно работать с персонажем:
//получаем класс игры для запущенного окна
PWGameWindow game_window = new PWGameWindow(SelectedWindow);
//объявляем host-игрока для данного окна игры
PWHostPlayer MyPersonage = game_window.HostPlayer;
//Использовать Смерчь у приста
MyPersonage.UseSkill(127);
//Сесть в медитацию
MyPersonage.MeditationStart();
и т.д.
Все свойства и методы откомментированны и по описанию в навигаторе можно понять что делает то или иное свойство или метод
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Основным желанием было наметить пути командной разработки и дальнейшего улучшения фреймворка для общего блага.
Класс для работы с GUI, я считаю, дописан. Так как на своей практике не вижу что еще нужно дописывать.
Класс для работы с игрой только начат - в нем я только наметил основные моменты и я предлагаю его дополнять и расширять совместными усилиями.
Если вы будете выкладывать код с исправлениями или улучшениями - обязательным требованием будут комментарии и следование общей концепции (по аналогии).
Со своей стороны буду оказывать любую помощь и поддержку. Все объясню и расскажу. Весь новый код буду вставлять в исходный проект и выкладывать на форуме.
Исходники PW FrameWork 2.0 и пример можно скачать из вложения. Замените адреса для своего клиента перед использованием!
N00bSa1b0t
27.09.2012, 22:51
А ты баг с памятью исправил, который был у TBX1in и whoami?
Goooooogle
27.09.2012, 22:54
Во спасибо Я со старым вообще ничего не понял тут хоть более просто!
krukovis
27.09.2012, 22:54
А ты баг с памятью исправил, который был у TBX1in и whoami?
Баг с тем, что память переставала выделяться? Исправил. Память теперь выделяется один раз при открытии и дальше все классы, если что то нужно инжектить - инжектят в эту страницу.
Goooooogle
28.09.2012, 00:23
переделал оффсеты под руоф скачать ([Ссылки могут видеть только зарегистрированные и активированные пользователи])
N00bSa1b0t
28.09.2012, 00:47
Баг с тем, что память переставала выделяться
Баг с тем, что занятая память не удалялась :)
А должно быть
WinApi.VirtualFreeEx(memory.OpenedProcessHandle, memory.FuncAllocMemory, 0, WinApi.FreeType.Release);
иначе память не удалится, ибо как гласит МСДН
If the dwFreeType parameter is MEM_RELEASE, dwSize must be 0 (zero).
krukovis
28.09.2012, 07:46
Баг с тем, что занятая память не удалялась
Вот так вот :). Значит можно переписывать PW FW. :)
Ну или пусть будет как есть - страница выделяется. Вся работа идет на этой странице. Все удобно.
Для меня важнее, чтобы мы общими усилиями описали основные параметры персонажа и прочих структур. Основной упор сделан на это.
Вот ты будешь сейчас писать софтину свою - возьми за основу PW 2.0 и что нибудь да допишешь в структуру перса. И я тоже сейчас буду писать кой чего - тоже допишу. Выложим вместе - будет польза обоим и еще куче народу.
Алгоритмы программы - не нужны. Только структура персонажа и дочерних структур.
N00bSa1b0t
28.09.2012, 12:15
Вот ты будешь сейчас писать софтину свою - возьми за основу PW 2.0
У меня уже свой фреймворк на основе фреймворка от whoami =)
Идея была примерно такая же:
Есть класс pwProcess в нем класс pwgame а там уже hostplayer с разными функциями типа:
var party = PW.Game.HostPlayer.GetParty();
PW.Game.HostPlayer.Assist(party[0]);
...
PW.Game.HostPlayer.UseItem(found, cooldown);
..
var players = PW.Game.HostPlayer.NearestPlayers_Get();
Только у меня еще модульная структура, чтоб не всю либу сразу подключать к своим проектам. Например, для геобота не нужны функции работы с группой, игроками итп =)
krukovis
28.09.2012, 14:45
Только у меня еще модульная структура, чтоб не всю либу сразу подключать к своим проектам. Например, для геобота не нужны функции работы с группой, игроками итп =)
Что за модульная структура? Подробнее плиз.
Добавлено через 2 минуты
переделал оффсеты под руоф скачать
Так там заменить только адреса нужно было. Все остальное совпадает. Можешь просто скопировать сюда адреса для руофа - для замены.
N00bSa1b0t
28.09.2012, 15:21
Что за модульная структура? Подробнее плиз.
Я пока думаю, как ее правильно реализовать. пока остановился на таком способе.
Например, делаю я простую ингейм утилитку. Например вот как EnemyDetector. Отображает список рядом находящихся игроков и выводит инфу о них.
В этой утилите не нужны функции работы с группой, с мобами, со скиллами, с чатом, функции движения, полета итп. Нужны функции только чтения списка игроков и все.
Например в иксо-боте не нужен список игроков рядов, но нужен автопот, скан мобов, движение итп.
Чтобы каждый раз не тащить за собой всю огромную либу, я её разбил на модули: Чат, группа, игроки, мобы, движение, скиллы итп.
krukovis
28.09.2012, 21:13
Чтобы каждый раз не тащить за собой всю огромную либу, я её разбил на модули: Чат, группа, игроки, мобы, движение, скиллы итп.
Это у тебя несколько dll-ок что ли?
N00bSa1b0t
28.09.2012, 23:18
Это у тебя несколько dll-ок что ли?
Нет - одна, просто в зависимости от проекта по разному компилируется.
Kitsune
29.09.2012, 00:28
в зависимости от проекта по разному компилируется
Использовать директивы на уровне компилятора - моветон.
N00bSa1b0t
29.09.2012, 12:17
Использовать директивы на уровне компилятора - моветон.
Это первое, что пришло мне в голову и пока меня устраивает :) Хотя возможно потом данный механизм будет изменен.
krukovis
29.09.2012, 16:32
Это первое, что пришло мне в голову и пока меня устраивает Хотя возможно потом данный механизм будет изменен.
Экономить 100кБ - бред же... :) Или какую проблему ты этим решаешь?
N00bSa1b0t
29.09.2012, 17:14
какую проблему ты этим решаешь?
Скажем так, я пока не настолько щедрый, чтоб выкладывать свои наработки в паблик :) Т.к. в саму либу внедрены функции, которые активно использует мой иксобот, и я не хочу их распространять (там всякие интересные алгоритмы, типа поиска пути в иксах c учетом стен и перепада высот и все такое), то таким образом я получаю, что в тех софтинах, что идут на продажу в либе не будет содержаться тех функций, которые я не хочу никому давать.
Блин, я ща пьяный, надеюсь, что моя мысля понятна :D
half-node
02.10.2012, 00:49
Всем доброго времени суток.
У меня возникла небольшая проблема.
На поиск близлежащего лута, есть такой код, вырезка:
int c = memory.ChainReadInt32(0xA571E0, 0x1C, 0x1C, 0x28, 0x14);
string[][] names = new string[c][];
for (int i = 0; i < c; i++)
{
names[i] = new string[2]
{
memory.ChainReadString_Unicode(0xA571E0, 0x1C, 0x1C, 0x28, 0x18, (i*0x4), 0x4, 0x168, 0x0),
(memory.ChainReadInt32(0xA571E0, 0x1C, 0x1C, 0x28, 0x18, (i * 0x4), 0x4, 0x110)).ToString()
};
}
Ну вот. Кол-во лута я получаю правильное.
А вот WID и Name по каждому нет. На выходе с именем пустая строка, а с идентификатором нуль.
Офсеты брал с соответствующей темы для руофа.
Пожалуйста, помогите понять, где я ошибся.
Спасибо!
Добавлено через 27 минут
Я понял в чем была моя ошибка.
И малость изменил код.
Но в итоге, получаю в именах пустые значения, а в WID отрицательные значения:
string[][] names = new string[0][];
for (int i = 0; i < 0x300; i++)
{
if (memory.ChainReadInt16(0xA571E0, 0x1C, 0x1C, 0x28, 0x18, (i * 0x4), 0x4, 0x110) != 0)
{
Array.Resize(ref names, names.Length + 1);
names[names.Length - 1] = new string[2]
{
memory.ChainReadString_Unicode(0xA571E0, 0x1C, 0x1C, 0x28, 0x18, (i*0x4), 0x4, 0x168, 0x0),
(memory.ChainReadInt32(0xA571E0, 0x1C, 0x1C, 0x28, 0x18, (i * 0x4), 0x4, 0x110)).ToString()
};
}
}
krukovis
02.10.2012, 07:52
Но в итоге, получаю в именах пустые значения, а в WID отрицательные значения:
memory.ChainReadString_Unicode(0xA571E0, 0x1C, 0x1C, 0x28, 0x18, (i*0x4), 0x4, 0x168, 0x0),
Не правильно читаешь строку. Вторым параметром нужно указывать максимальную длину строки.
memory.ChainReadString_Unicode(0xA571E0, 32, 0x1C, 0x1C, 0x28, 0x18, (i*0x4), 0x4, 0x168, 0x0)
(memory.ChainReadInt32(0xA571E0, 0x1C, 0x1C, 0x28, 0x18, (i * 0x4), 0x4, 0x110)).ToString()
Отрицательное число на выходе - это нормально для WID лута. Либо читай в UInt, либо выводи в Hex, либо вообще не парься по поводу
"отрицательности".
Я обычно отображаю в Hex:
memory.ChainReadInt32(0xA571E0, 0x1C, 0x1C, 0x28, 0x18, (i * 0x4), 0x4, 0x110)).ToString("X")
Т.к. сами WID смысла не несут. WID нужно только для сравнения.
whoami
03.10.2012, 19:23
Я когда свой софт писал - делал упор на оптимизацию скорости. Т.к. на ТВ или тиграх и так клиент может притормаживать, а с аналогом "EnemyDetector" всё может вообще отвалиться. Поэтому, например, поля объектов максимально кэшируются, читаются не поштучно (например, MemPtr.Int32) а сразу пачками (например, с помощью структуры с explicit layout). Можно сделать всю такую ООП-шную объектную модель с классами типа PWMob, у которого были бы свойства X, Y, Z, Level, IsAggressive, IsAttacking и т.д. Было бы очень удобно писать боты, но с оптимизацией был бы полный швах... Я думаю, если добить идею инпроцессного режима, то там оптимизация была бы не нужна и такой подход был бы более уместен.
krukovis
04.10.2012, 07:22
Можно сделать всю такую ООП-шную объектную модель с классами типа PWMob, у которого были бы свойства X, Y, Z, Level, IsAggressive, IsAttacking и т.д.
Ну как видишь в этом направлении я и задал вектор развития проекта. И туда и двигаюсь. Пока наращиваю класс Персонажа. Класс пати описан. Делать софт на порядок удобнее.
но с оптимизацией был бы полный швах...
Пинг 500-600 мс средний. Время работы программы (чтение памяти и обработка данных) 20-30 мс. Ожидание в потоке 1000 мс. Получается что 90% времени программа просто ничего не делает. Так что вопрос оптимизации, как я считаю, не стои'т.
Основная задача - сделать удобный инструмент для создания софта. И в этом нам поможет ООП.
Я думаю, если добить идею инпроцессного режима, то там оптимизация была бы не нужна и такой подход был бы более уместен.
Если решить эту задачу, то готовая модель игровых структур легко ляжет на новый способ обращения к памяти. Кстати, где бы почитать по поводу работы с внедренной DLL? Как внедрить DLL код есть и сама длл для внедрения не сложная. А вот что происходит дальше - не очевидно. Как обращаться к памяти из внедренной DLL?
whoami
04.10.2012, 14:39
krukovis, ну вот пробежать по сотне персонажей (на ТВ максимум может быть 160 игроков) - получить их координаты, имя, уровень/культавацию, ID, ID клана, жив/мёртв, хирки, привязка каты, для таргета - ещё ХП/МП/бафы, плюс ещё мобов обработать - выбрать петов друлей и мистиков. Тут уже в 20 мс уложиться трудно. и обновляюсь я раз в 500 мс, а пинг чтобы на ТВ играть - лучше иметь не больше 150 мс.
Для внедрения .NET-кода в ПВ у меня код есть, часть - даже в паблик выкладывал. Смысл в том, что там есть используется альтернативная версия ProcessMemory, которая не лезет в память другого процесса, а работает с текущим, потоки создаёт не через CreateRemoteThread, а через CreateThread и т.д.
Добавлено через 22 часа 4 минуты
А должно быть
WinApi.VirtualFreeEx(memory.OpenedProcessHandle, memory.FuncAllocMemory, 0, WinApi.FreeType.Release);
А у меня вот с таким вариантом после второй отправки пакета падает клиент. Что не так?
krukovis
15.10.2012, 09:55
А у меня вот с таким вариантом после второй отправки пакета падает клиент. Что не так?
Инектится в пустую страницу видимо. А ты в каком варианте используешь? В своем FW или в FW 2.0 ?
silk
15.10.2012, 10:25
А вот что происходит дальше - не очевидно. Как обращаться к памяти из внедренной DLL?
дальше происходит все то же самое, как и со своим процессом. Поскольку dll находится в адресном пространстве клиента, то обращение к памяти клиента идет через обычную арифметику указателей. :)
krukovis
16.10.2012, 11:15
дальше происходит все то же самое, как и со своим процессом. Поскольку dll находится в адресном пространстве клиента, то обращение к памяти клиента идет через обычную арифметику указателей.
В теории я это все знаю. В музыке кода бы. В идеале - С#.
phoenixusa
25.12.2012, 12:00
krukovis, почему не хочешь хранить смещения в отдельном файле (например ini)? чтобы при выходе обновы только изменить адреса, без перекомпиляции проекта?
krukovis
26.12.2012, 08:18
krukovis, почему не хочешь хранить смещения в отдельном файле (например ini)? чтобы при выходе обновы только изменить адреса, без перекомпиляции проекта?
Почему не хочу? Хочу )), но:
Обновы бывают двух видов:
1) Большие - когда меняются адреса и структуры функций.
2) Маленькие - когда меняются только адреса.
В первом случае ini-файл не спасет, т.к. в ini не опишешь структуру функции. А во втором, ini-файл - не элегантное решение, ведь я выложил исходники, где показываю как использовать Offset Retriever и ini-файл вообще становится не нужным.
Da4Da4
11.02.2013, 14:45
krukovis, можешь если не затруднит описать принцип работы класса Offset Retriever. из кода класса было понятно, что ты производишь поиск поиск по файлу elementclient.exe или в памяти процесса. Поиск адресов и офсетов выполняешь по шаблону. вот только не понятно что они из себя представляют, и на основании чего составляются?
krukovis
15.02.2013, 20:11
вот только не понятно что они из себя представляют, и на основании чего составляются?
Шаблоны представляют с собой байт-код записанный в виде строки без пробелов и разделенных знаком ?. Знак ? - обозначает адрес или оффсет длинной DWORD = 4 байта.
Разберем поиск оффсета на примере поиска базового адреса.
Базовый адрес мы можем найти с помощью описанного на форуме мануала или посмотреть в этой теме. ([Ссылки могут видеть только зарегистрированные и активированные пользователи])
Для текущей версии RUOFF он равен 0x00B8FBCC
1. Для начала открываем elementclient.exe в OllyDbg 2.01 ([Ссылки могут видеть только зарегистрированные и активированные пользователи])
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
2. Дальше находим первое вхождение константы 0x00B8FBCC. Делается это так:
Тыкаем в свободное пространство правой кнопкой мыши
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Выбираем поиск
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Константы
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
3. Нажимаем ОК и находим первое вхождение:
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
4. Эта константа применяется в очень многих функциях, т.к. это базовый адрес. Но наша задача - найти такую функцию, которая с большой вероятностью не будет изменяться долгое время. Я потыкал дальше еще несколько раз Ctrl+L - это сочетание значит "Искать тоже самое дальше". И нашел вот такой кусок кода, который с большой вероятностью будет оставаться таким же очень долгое время. Я так думаю, потому что там используется только один базовый регистр EAX и несколько PUSH 0 в исключительной конфигурации:
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
5. Дальше мы можем использовать эту *с большой долей вероятности* постоянную часть функции и сделать из нее МАСКУ. Для этого нам нужно скопировать этот кусок кода как байт-код:
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
6. Дальше откроем блокнот и вставим туда то, что находится в буфере и увидим вот такой байт-код:
"A1 CC FB B8 00 6A 00 6A 00 6A 00 8B 48 1C 6A 00
6A 00"
Красным выделил BA.
Нам он нужен для поиска Базового адреса, поэтому мы заменяем базовый адрес на ? и удаляем пробелы.
Получаем: "A1?6A006A006A008B481C6A006A00"
Теперь мы можем использовать эту маску для поиска Базового адреса в автоматическом режиме.
По поводу поиска адресов функций я расскажу как нибудь в другой раз.
Добавлено через 8 минут
Чтобы убедиться, что это уникальное сочетание можно проверить на клиенте 1.3.4-1.3.6
С этого времени это сочетание не менялось:
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
И скорей всего уже не поменяется.
И мы можем увидеть, что на Cerera.org 1.3.4-1.3.6 базовый адрес 926FD4.
А посмотрим что нам говорит эта тема ([Ссылки могут видеть только зарегистрированные и активированные пользователи]):
Flugel PW, клиент 1.3.4 версии, сборка 2265, версия обновления 50
BaseAdress=00926FD4
GameAdress=0092764C
Da4Da4
18.02.2013, 16:58
Большое спасибо за подробное объяснение.
В принципе мои предположения были верными, но все же не было полной уверенности.
Я так предполагаю, что с адресами функций сложностей не много больше, так как они имеют большею вероятность изменения, пускай и незначительно. Стало быть в силу этого подходить к выбору шаблона для поиска нужно более ответственно.
dobik
23.04.2013, 22:59
Кто-нибудь знает адрес
//адрес gui-функции
public static int gui_function_address = 0x77F1D0;
для текущей версии клиента?
И остальные из раздела GUI?
Пробую с GUI разобраться, но не знаю адреса для него.
krukovis
24.04.2013, 08:56
Кто-нибудь знает адрес
//адрес gui-функции
public static int gui_function_address = 0x77F1D0;
для текущей версии клиента?
И остальные из раздела GUI?
Адрес для GUI можно определить с помощью Автологина из подписи для любого клиента начиная с 1.4.4 и выше.
А так же для этого есть специальная тема Адреса и оффсеты ([Ссылки могут видеть только зарегистрированные и активированные пользователи]). Там выкладываются все адреса и смещения для различных версий клиента PW.
FriendsKenny
07.09.2013, 11:15
В ф-ии public static byte[] PetUseSkill(int skillID, int targetWID)
которая формирует пакет исп-ия скилла пета, один лишний 0х0
krukovis
08.09.2013, 10:59
В ф-ии public static byte[] PetUseSkill(int skillID, int targetWID)
которая формирует пакет исп-ия скилла пета, один лишний 0х0
Очень может быть. Эти функции писались еще под 1.4.Х
FriendsKenny
08.09.2013, 20:40
Пытаюсь перевести инжект AutoPath ([Ссылки могут видеть только зарегистрированные и активированные пользователи]) на ассемблер фреймворка.
Но в таком варианте персонаж просто стоит на месте, клиент не вылетает. Где я ошибся?
krukovis
09.09.2013, 10:29
Но в таком варианте персонаж просто стоит на месте, клиент не вылетает. Где я ошибся?
Мне страшно представить как ты это пытаешься запустить. Я выкладывал пример использования. Посмотри, пожалуйста.
FriendsKenny
09.09.2013, 17:32
asm.Push6A(0x14A); заменил на asm.Push68(0x14A);
Заработало =)
krukovis
10.09.2013, 23:05
Push68
Push68 - это тот пуш, который в байт-коде выглядит как
68 00 00 0A 14 == push 0x14
Smertig
11.09.2013, 00:25
asm.Push6A(0x14A); заменил на asm.Push68(0x14A);
68 00 00 0A 14 == push 0x14
Добавлю. Push 6A не пушит числа больше 127=0x7F
A117
22.09.2013, 16:40
При отправке пакета клиент падает.
Объясните, пожалуйста, почему это происходит и как поправить.
FriendsKenny
24.09.2013, 14:48
При отправке пакета клиент падает.
Объясните, пожалуйста, почему это происходит и как поправить.
Логично предположить что дело в адресе ф-ии отправки пакета
vogel
24.09.2013, 15:18
И поправить можно изменив устаревший адрес - на новый.
A117
24.09.2013, 23:20
Адрес функции поменял первым делом - клиент все равно падает. Сперва думал что неправильный адрес, но потом сам получил то же значение.
До последнего обновления работал такой пакет (после соответствующей подстановки) "\x60\x8B\x0D\x00\x00\x00\x00\x8B\x49\x20\x68\x11\x 11\x11\x11\x68\x22\x22\x22\x22\xB8\x33\x33\x33\x33 \xFF\xD0\x61\xC3"
То что формируется фреймворком довольно сильно отличается и по длине и по содержанию.
Попутный вопрос: как найти ассемблерный код самой функции?
krukovis
25.09.2013, 08:50
То что формируется фреймворком довольно сильно отличается и по длине и по содержанию.
Попутный вопрос: как найти ассемблерный код самой функции?
В истории были случаи изменения пакета. Поправьте пакет и проверьте.
Ассемблерный код какой функции? В общем случае ассемблерный код любой функции можно увидеть в файле elementclient.exe открыв ее в деббагере.
A117
25.09.2013, 20:59
Перешел в дебаггере по адресу PackCall=006F55E0,
там обнаружился такой код:
PUSH -1
PUSH 00AD1C38
MOV EAX,DWORD PTR FS:[0]
PUSH EAX
MOV DWORD PTR FS:[0],ESP
SUB ESP,18
PUSH EBX
PUSH ESI
PUSH EDI
MOV EDI,ECX
PUSH 7
CALL 008263B0
Я так понимаю это и есть код функции отправки пакета, который нужно вставить в PacketSender.Send(byte[] packet)?
krukovis
26.09.2013, 10:27
Я так понимаю это и есть код функции отправки пакета, который нужно вставить в PacketSender.Send(byte[] packet)?
Метод .Send класса PacketSender принимает в качестве аргумента packet (переводится как пакет) типа массив байт byte[].
В фреймворк добавлена библиотека пакетов. Класс Packets скорей всего или что то в этом роде. Я выкладывал пример использования фреймворка для отправки пакетов. Посмотри, пожалуйста.
A117
27.09.2013, 21:15
Я не точно выразился. Имелось ввиду не параметр функции а сам ассемблерный код
Хочу его переписать но возникли трудности с идентификацией нужного куска кода в клиенте. Адрес функции отправки пакета нашел, а где располагается код, который заносит параметры в регистры, до перехода по этому адресу или позже, или вообще в не там ищу?
Как заставить персонажа двигаться? В фреймворке не нашел ничего похожего на перемещение.
dimonpw2
03.01.2014, 21:39
Вопрос, что я тут делаю не так?
string[] Value = new string[this.CountNPC];
for (int i = 0; i < this.CountNPC; i++)
{
Value[i] = memory.ChainReadString_Unicode(0xB8FBCC, 50, 0x1C,0x1C, 0x24, 0x18, (i * 4),0x4, 0x260, 0);
}
return Value;
Нужно сканировать область на NPC\Мобы, но в результате выводит пустые строки.
Воспользовался библиотекой PWFrameWork 2.0. Версия клиента 1.4.6, офсеты брал с этой темки. На офе получилось соответственно с офсетами под 1.5.0. А под 1.4.6 не хочет. Перепробовал множество вариантов цепочек, после цифры "50" вставлять 1 раз "0х1С", i умножать на "0x4", но все-ровно.
Заранее спасибо.
phoenixusa
12.01.2014, 21:20
см. тут [Ссылки могут видеть только зарегистрированные и активированные пользователи]
VitMitS
12.05.2014, 13:49
Народ перерыл весь форум, почему решил спросить тут - тоже пишу в Net.
Не могу понять как поставить перса на медитацию (страна грез)
Проблема в том что я относительно новичек в данной области. Перечитал много по Cheat Engine, ollydbg, мозги взрываются и не черта не пойму. По сути я пытался поймать пакет который отправляется при запуске медитации.
у меня есть функция чесно украденная с бота PW_TARAKAN (конечно переписанная), на отправку пакетов.
Public Shared Sub SendPacket(ByVal packet As Byte(), ByVal pid As Integer)
If packet.Length > 0 Then
Dim num As Integer
Dim buffer As Byte()
Dim bytes As Byte()
Dim ptr2 As IntPtr
Dim ptr As IntPtr = WinAPI.OpenProcess(ProcessAccessFlags.All, False, pid)
Dim VirtualAE = WinAPI.VirtualAllocEx(ptr, 0, &H9C4, AllocationType.Commit, MemoryProtection.ReadWrite)
Dim WritePM = (VirtualAE + &H7D0)
WinAPI.WriteProcessMemory(ptr, WritePM, packet, packet.Length, num)
buffer = New Byte() {&H60, &HB8, &HE0, &H55, &H6F, 0, &H8B, 13, &H6C, &H8B, &HC3, 0, &H8B, &H49, &H20, &HBF, 0, 0, 0, 0, &H6A, 0, &H57, &HFF, &HD0, &H61, &HC3}
bytes = BitConverter.GetBytes(Offsets.F_SEND_PACKET)
Array.Copy(bytes, 0, buffer, 2, 4)
bytes = BitConverter.GetBytes(Offsets.BA)
Array.Copy(bytes, 0, buffer, 8, 4)
bytes = BitConverter.GetBytes(WritePM)
Array.Copy(bytes, 0, buffer, 16, 4)
bytes = BitConverter.GetBytes(packet.Length)
Array.Copy(bytes, 0, buffer, 21, 1)
WinAPI.WriteProcessMemory(ptr, VirtualAE, buffer, &H1B, num)
WinAPI.CreateRemoteThread(ptr, IntPtr.Zero, 0, VirtualAE, IntPtr.Zero, 0, ptr2)
WinAPI.VirtualFreeEx(ptr, VirtualAE, &H1B, FreeType.Release)
End If
End Sub
Научился заходить на локу. выходить с локи,
полностью написал свой ГЕО, со старцем, школьным учителем, волченком, в общем со всей рутиной в мире, осталось только загнать перса на медитацию по завершению всей рутины. Научите пожалуйста. :sad:
Дыбы выявить проблему тестил инжект на ассист - проблем нет. Инжект на скил крашит клиент, реализация в дельфи рабочая. Что может быть не так?
Не юзал это фреймворк, но попробую тыкнуть пальцем в небо.
Injector.Mov_ESI_DWORD_Ptr(&H1C + &H30)
Injector.Mov_ESI_DWORD_Ptr_EDX_Add(&H30)
bestbeer
27.09.2014, 22:08
Не юзал это фреймворк, но попробую тыкнуть пальцем в небо.
Injector.Mov_ESI_DWORD_Ptr_EDX_Add(&H30)
Такого в фрейме нет.
Smertig
28.09.2014, 00:06
Injector.Mov_ECX_DWORD_Ptr(113)
?!
Это что? Аналог строки:
mov ecx,Po1 // указатель на скил
?
Если там указатель, то 113 - явно не то значение. Если именно ID скилла, то ладно.
Injector.Mov_EAX_DWORD(&H47CBF0) // можно использовать вариант и как у вас, но я сомневаюсь, что инжектор просчитывает относительную адресацию в памяти
Injector.Call_EAX()
bestbeer
28.09.2014, 02:57
?!
Это что? Аналог строки:
mov ecx,Po1 // указатель на скил
Injector.Mov_ECX_DWORD_Ptr(113)
"B971000000" (строка из фрейма)
Также я не совсем понимаю как в клиенте генерируется такие байты "683CF9FF" , они всегда одинаковы и не меняются.
Остальное сходится. (Pushad(), Injector.Popad(), Injector.Ret() я не сверял.)
Также я добавил в фрейм недостающую операцию"Mov_ESI_DWORD_Ptr_EDX_Add" думаю она необходима.
vb:
Public Sub Mov_ESI_DWORD_Ptr_EDX_Add(addre As Integer)
If (addre <= 127) AndAlso (addre >= -128) Then
Me.Asmcode = Me.Asmcode & "8B72" & intTohex(addre, 2)
Else
Me.Asmcode = Me.Asmcode & "8BB2" & intTohex(addre, 8)
End If
End Sub
krukovis
28.09.2014, 10:30
Основная цель класса ASM - генерировать опкод - массив байт, который потом инжектится. В Delphi класс ASM не нужен, т.к. там Делфи умеет воспрнимать Ассемблер и сам переводит его в опкод, который потом и инжектится. Этот опкод должен точно совпадать с функцией из клиента, меняться могут только параметры функции. Например номер скилла или координаты или еще что. Вы можете открыть OllyDbg и вписать туда функцию на Delphi - они пишутся на Ассемблере и их написать не сложно. Олька переведет эту функцию в опкод и вы сможете сравнить этот опкод с тем, что генерирует ваш класс ASM. Если все совпадает - значит функция написана правильно. Если не совпадает, значит у вас где то ошибка. И ее лекго можно обнаружить просто глазами.
bestbeer
29.09.2014, 03:19
Вобщем я сумел понять свои ошибки.(а может и не сумел :d и мне повезло.)
Вобщем нужно добавить в фрейм функцию "Mov_ESI_DWORD_Ptr_EDX_Add" и немного изменить сам инжект.
vb:
Injector.Clear()
Injector.Pushad()
Injector.Mov_ECX_DWORD_Ptr(&HC9DFAC)
Injector.Mov_EDX_DWORD_Ptr_ECX_Add(&H1C)
Injector.Mov_ESI_DWORD_Ptr_EDX_Add(&H30)
Injector.Push6A(&HFF) '-1
Injector.Push6A(0)
Injector.Push6A(0)
Injector.Mov_ECX(113)
Injector.Push_ECX()
Injector.Mov_ECX_ESI()
Injector.Mov_EDI(&H47CBF0)
Injector.Call_EDI()
Injector.Popad()
Injector.Ret()
Injector.RunAsm()
Вот так работает.
Hilling
09.01.2015, 13:27
Подскажите пожалуйста как в АСМ классе значения с типом uint использовать? Там все MOV-функции в качестве параметров тип int принимают. А мне, например, надо wid моба затолкать, который в int не поместится. Я, конечно, поменял его на uint, но сдается мне это некорректно. Мне неизвестно как в этом случае следующие функции нужно поменять (и нужно ли вообще):
public string intTohex(int value, int num)
{
string str1 = null;
string str2 = "";
str1 = "0000000" + this.hex(value);
str1 = str1.Substring(str1.Length - num, num);
for (int i = 0; i <= str1.Length / 2 - 1; i++)
{
str2 = str2 + str1.Substring(str1.Length - 2 - 2 * i, 2);
}
return str2;
}
Кто сталкивался - не оставайтесь безучастны :sceptic:
Smertig
09.01.2015, 16:24
Подскажите пожалуйста как в АСМ классе значения с типом uint использовать? Там все MOV-функции в качестве параметров тип int принимают.
Перевести это число в int (может стать отрицательным, ничего страшного) и послать в MOV. В памяти числа отличаются только размером (1, 2, 4 байта), но выглядят совершенно одинаково.
К примеру, 0xFFFFFFFF - это -1, если int, или 2^32-1, если uint. Но в памяти это один и тот же 0xFFFFFFFF
Arsen0208
30.04.2016, 23:03
Вопрос по поводу Packet. Если ввести правильный IDшник то все работает но у мобов (даже у мобов на одной поляне) разные IDшники. Не подскажете как прочитать именно имя моба?
Hilling
01.05.2016, 01:33
Так же как и ID, только считываешь строку. Так же считываешь д оструктуры моба, только вместо смещения ID подставляешь смещение имени. Раньше было +288 +0. Проверяешь по имени нужный это тебе моб или нет. Если да, то считываешь у этого же моба WID и подставляешь в пакет.
Arsen0208
01.05.2016, 02:42
Фигня в том что ID я получаю вот так:
return memory.ReadInt32(this.Structure + PWOffssAndAddrss.host_player_target_wid_offset);
Но не вкурсе существует ли оффсет Имени Таргета. Искать через СЕ тоже не варик я так понял.
Думал может сделать отдельный класс под монстра с его структурой и использовать его как и класс ХостПлэера но не понял что там со структурой Мобов.
P.S. ботовод-самоучка, могу нести бред не понимая этого./dgs
sabbaot01
21.05.2016, 20:37
простите за нубский вопрос. это на каком языке? c++ или c#
не понимаю с чего начать, если ни разу не программер, но что-нибудь создать хочется, в виде джинокача или геобота
krukovis
22.05.2016, 09:14
Это на C#. Это утилита для среднего уровня программирования. Там возможно уже все устарело, т.к. писалось несколько лет назад. А может и нет. Я давно отошел от разработок под PW. Вообще удивлен, что это кому-то еще интересно. А не проще воспользоваться уже написанным готовым софтом. Ребята же постоянно что-то выкладывают. Были раньше и платные программы достаточно хорошего уровня.
Hilling
22.05.2016, 12:54
Фрейморк хороший, понравилась структура и вообще работа с ним в целом. За что огромное спасибо автору. Однако пришлось практически отказаться от работы с ним, так как запущенные программы, после пары часов работы, крашили клиент игры. Либо я рукожоп, либо с памятью что-то. Скорее первое. Как-то так.
В целом он не устарел, оффсеты/адреса поменять и вперед.
krukovis
23.05.2016, 10:27
NoobSaibot писал про какие то проблемы при работой с памятью в самом начале обсуждения и приводил даже код исправления. Я не помню устранил я их или нет. Можете попробовать посмотреть его посты и посмотреть устранены ли проблемы.
Hilling
23.05.2016, 18:28
Я пробовал менять. Но за данным исправлением потянулась целая цепочка других исправлений. В общем, ничего у меня не вышло :)