Помощь - Поиск - Пользователи - Календарь
Полная версия: Чтение из памяти
UoKit.com Форумы > Кликер > UO Pilot > UO Pilot в онлайн играх > UO Pilot в Lineage II
Страницы: 1, 2, 3
ivanTu
Приветствую всех, подскажите пожалуйста, у меня есть базовый адрес и офсеты, как правильно все написать пробовал вот так :

set #target_hp_base 0x7D47265C
set #offset1 0x72c
set #offset2 0xf8
set #offset3 0x418
set #offset4 0x3a4
set #offset5 0x204

set #target_hp #target_hp_base + #offset1 + #offset2 + #offset3 + #offset4 + #offset5

readmem #hp #target_hp d
hint Жизней мало епт = #hp

ничего не получилось возвращает либо ноль либо не верное число...
DarkMaster
У вас скорее всего есть цепочка указателей и офсеты от каждого указателя указаны. Т.е. берете адрес + офсет1, считываете значение. В значении у вас будет указатель со следующим адресом, прибавляете к нему второй офсет и т.д.
ivanTu
Цитата(DarkMaster @ 26.2.2015, 20:16) *

У вас скорее всего есть цепочка указателей и офсеты от каждого указателя указаны. Т.е. берете адрес + офсет1, считываете значение. В значении у вас будет указатель со следующим адресом, прибавляете к нему второй офсет и т.д.


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

Изображение


и кстате, тот адрес что выделен (базовый) я его вытащил из .Dll - ки процесса, и через PE tools взял его адрес, я про то что UoPilot читает адреса из dll процесса?
ivanTu
Пробовал вот так :

set #target_hp_point0 0x7D47265C
set #target_hp_point2 #target_hp_point0 + 72C
set #target_hp_point3 #target_hp_point2 + F8
set #target_hp_point4 #target_hp_point3 + 418
set #target_hp_point5 #target_hp_point4 + 3A4
set #target_hp #target_hp_point5 + 204

readmem #hp #target_hp d
hint Жизней мало епт = #hp

Возвращает 0
DarkMaster
это печальная история... Мог, но релиз не состоялся т.к. исходники были утеряны... На данный момент пилот не может запросить начальный адрес блока дллки. Вся адресация у него только общая на процесс. С PE tools дело не имел, только с артмани. Надеюсь правильно вас понял, что адресация идет от начала дллки, но что-то больно цифры тогда большие. Если адресация все-таки общая на процесс, а судя по адресам это так, то схему я уже выше описывал. В данном случае это будет выглядеть примерно так:
Код
set #a 0x2B7BAF00 + 0x204
readmem #b #a D
// В #b должен в данном случае упасть адрес 2BF033F70
// от вернувшегося адреса необходимо расчитать смещение
set #b #b + 0x3A4
readmem #c #b D
set #c #c +0x418
readmem #d #c D
и т.д.

Учтите, что значения при выводе в лог для отладки будут десятичными а не хексом. Для удобства можно использовать:
Код
log dec2hex(#b)


// Вообще очень странная лапша из адресов. Обычно вперед-назад указатели не прыгают, а идут только вперед.
ivanTu
Спасибо уважаемы Дарк , все получилось, но уж больно огромен код получается )))
Можете подсказать как оптимизировать можно, если это возможно?

Код
// Считываем базовый адрес и оффсеты HP выбранной цели
set #point0 0x7D47265C + 0x72C
readmem #point0 #point0 d
set #point1 #point0 + 0xf8
readmem #point1 #point1 d
set #point2 #point1 + 0x418
readmem #point2 #point2 d
set #point3 #point2 + 0x3A4
readmem #point3 #point3 d
set #target_hp #point3 + 0x204 // Получили адрес памяти HP выбранной цели
readmem #target_hp #target_hp d  // Обьявляем переменную для адреса #target_hp
// КОНЕЦ // Считываем базовый адрес и оффсеты HP выбранной цели

:start_script  
hint HP  =  #target_hp
goto start_script
DarkMaster
Цитата
Можете подсказать как оптимизировать можно, если это возможно?

По сути никак. Можно создать массив с офсетами, потом засунуть все это в цикл for, но меньше оно вряд ли станет, только при этом еще и станет черт ногу сломит. Было бы оно длинее раза в 2, то был бы смысл хоть какой-то. Можно вынести в подпрограмму и загнать в хвост, чтобы глаза не мозолило. Посмотрите gosub.
ivanTu
Теперь другая проблема, тестил скрипт на 64х битной системе, принес домой адреса не читаются на 32х битной такое возможно? Есть ли решение?

включаю этот же скрипт на домашнем компе

Код
// Считываем базовый адрес и оффсеты HP выбранной цели
set #point0 0x7D47265C + 0x72C
readmem #point0 #point0 d
set #point1 #point0 + 0xf8
readmem #point1 #point1 d
set #point2 #point1 + 0x418
readmem #point2 #point2 d
set #point3 #point2 + 0x3A4
readmem #point3 #point3 d
set #target_hp #point3 + 0x204 // Получили адрес памяти HP выбранной цели
readmem #target_hp #target_hp d  // Обьявляем переменную для адреса #target_hp
// КОНЕЦ // Считываем базовый адрес и оффсеты HP выбранной цели

hint #target_hp


выдает вместо того , что нужно -1

беда.... (
DarkMaster
Цитата
Теперь другая проблема, тестил скрипт на 64х битной системе, принес домой адреса не читаются на 32х битной такое возможно? Есть ли решение?

изменилась цепочка указателей. ищите новую для 64 бит.

тут кстати возможна большая трагедия. Если будет приложение 64 битным с 64 битной адресацией, то пилот ее не поймет - данный апдейт был потерян вместе с теми же исходниками на адресацию по длл.
ivanTu
Уважаемый Дарк, а возможно как то проверить в начале скрипта битность системы, а затем запускать требуемые куски скрипта?
про запуск нужного куска я так понимаю gosub мне поможет, а вот как проверить битность? Через реестр есть мысль, но тут опять вопрос на разных типах систем XP Vista и т.д адрес так же разный наверное... может есть какое то универсальное решение...
DarkMaster
Самый тупой способ - проверить существование папок. Например, wow64. Вообще в пилоте прямого вытягивания битности и работы с реестром нет. Данная методика из костылей батников. Там проверяют зарезервированную системную переменную.
ivanTu
Уважаемый Дарк подскажите , как можно работать с значением в формате Float выдает 0 всегда, если можите с примером пожалуйста.
DarkMaster
используйте строковую переменную, а не числовую. В числовую не может быть помещено значение с точкой.
Цитата
добавил в команды 'readmem' и 'writemem' операции с числами с плавающей запятой
B:byte = 1b; W:word = 2b; D:dWord = 4b; C:char = 1b; S:String = 1-255b;
DO:double = 8b; F:float = 4b; R:real = 6b;


Либо вот так:
https://forum.uokit.com/index.php?s=&sh...st&p=161352 (шутка)
Я кстати минут на 15 опоздал(( писал тот же самый функционал...
ivanTu
Если ставлю строку "S" то выдает так же 0 не понимаю в чем дело

readmem #a 0x0F2999BC s 10
hint #a

хотя на тот момент я точно знаю, что значение 9.024896622
DarkMaster
Цитата
Если ставлю строку "S" то выдает так же 0 не понимаю в чем дело

Ну причем тут S? Откуда она вообще взялась?
Цитата
используйте строковую переменную, а не числовую.

Цитата
добавил в команды 'readmem' и 'writemem' операции с числами с плавающей запятой

Цитата
F:float = 4b
ivanTu
S это string тобиш строка, яподумал что про строковую переменную вы имели ввиду это, просто F ноль возвращает, покажите пожалуйста пример кода, не могу никак понять что да как...

Все разобрался )

теперь я знаю что переменная с $ - это строковая )))

Даже в последующем найденом значении делаю проверку на целое число все работает.

$a 8.98880291

If $a > 6
hint
end_if

короче говоря все получилось! Спасибо большое Дарк! )


то есть я так понимаю число проверяется до точки?
DarkMaster
Не совсем так. Если я правильно понимаю логику пилота, а здесь она не совсем адекватная, то все сравнение идет посимвольно кодами символов.
Т.е. берем строку, лезем в ascii таблицу, переводим все символы в коды. http://www.cdrummond.qc.ca/cegep/informat/...ages/ASCII1.GIF

Т.е. у нас получится вместо:
8.98880291
56 46 56 56 56 48 50 57 49
Далее из этого числа по одной цифре идет сравнение. Символ точки меньше значения цифры и это видимо как-то обрабатывается. Вообще трогать страшно.

В общем и целом делать так крайне не рекомендую, это ну уж очень не корректно. Используйте trunc или round для приведения к целочисленному типу.

Код
if 9.0 > 9
    log +
else
    log -
end_if

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

set $a 5.98880291
set $b 6
if a < b
hint // В данном случае хинт выведется
end_if
cirus
Может так: if $a < $b
DarkMaster
Цитата
все сравнивается правильно

Цитата
Код

if 9.0 > 9
log +
else
log -
end_if


Уже косяк.

Не может 9.0 быть больше, чем 9. Это ошибка.
cirus
Сравнение работает если сравнивать целые числа с целыми и нецелые с нецелыми.
Т. е. если надо сравнивать нецелое число, скажем 5.98880291, то и сравнивать его надо не с 6, а с 6.0.
WKnight
if strtoint() then f:= a < b
else CompareStr ()
DarkMaster
Как именно работает сравнение строк? Все что я понял, то вернет 0, если они равны. Точнее я не понял, что есть "строка больше/меньше". По Ascii, как я и написал?

Цитата
Т. е. если надо сравнивать нецелое число, скажем 5.98880291, то и сравнивать его надо не с 6, а с 6.0.

Код
if 9.80 > 9.8
    log +
else
    log -
end_if
stop_script
cirus
Видимо все-таки не работает.
DarkMaster
Если по порядку по ascii сравнивает, то все логично. Код символа '0' будет больше, чем код окончания строки.
cirus
А где-то вообще пишется 9.80 или везде 9.8? Если не пишется то смысл что-то выдумывать.
DarkMaster
А эти десятые вообще нужны? почему не делать trunc или round?
ivanTu
я сейчас подбираю, нужную ячейку памяти, не могу подобрать дистанцию до моба в La2 геморрой сплошной, нашел вроде бы float , но улетаю в другую локацию, значение принимает отрицательный вид... тобиш с минусом впереди... пока кароче ничего не получается с дистанцией...
DarkMaster
минус можно убрать через
Код
set #var abs(значение)

Как с флоатом работать будет не уверен, возможно сначала необходимо будет отбросить дробную чать или округлить.

А как дистанцию до моба нашел?
ivanTu
брал в цель мобов, НПС, отбегал, подбегал, и искал соответственно что уменьшилось или увеличилось значение, (Cheat Engine)
P/S Искал по всем значениям кроме строк от байта до Double , вроде второе правильно написал.
DarkMaster
какой диапазон значений? Скажем при ренче 600 и 900 какие значения будут?
При каких ситуациях значение становится отрицательным?
ivanTu
рейндж не могу проверить, а в минус уходят не понятно по каким причинам, сам пока не пойму.
DarkMaster
если несложно, уточните ренч и значения, когда сможете. Есть кстати подозрение, что там используется unsigned (безнаковая) перемененная, а пилот вроде считывает их как знаковые. Но тут опять же должны быть очень большие значения, чтобы знак менялся.

Поискал диапазоны значений... А походу не существует беззанокового float...
ivanTu
Т.Е. нет возможности вычеслить дистанцию до моба?
DarkMaster
Т.е. моя догадка про появление минуса ошибочна.

При минусе само число по модулю остается корректным? Если да, то можно просто использовать abs, как я писал выше.
ivanTu
Цитата(DarkMaster @ 10.3.2015, 11:52) *

Т.е. моя догадка про появление минуса ошибочна.

При минусе само число по модулю остается корректным? Если да, то можно просто использовать abs, как я писал выше.


Оно то верно, то нет.
DarkMaster
возможно адрес смещен на 1 байт.
DarkMaster
Могу порекомендовать открыть страницу памяти и глазками посмотреть на изменение значений. Может все очень быстро проясниться.
ivanTu
сейчас папробую
ОТкрыл, и Заморгал, ничего не понимаю только это понял )))
ivanTu
Вродеб нашел , но есть один косяк, если я с переди одно значение, если сзади или с боку другое... но оба правильно увеличиваются ли уменьшаются если я отбегаю или подбегаю к мобу. цифры разные но увеличиваются либо уменьшаются правильно относительно моба, единственно, что они разные и меняются относительно моего положения в пространстве и то где расположен моб, вот скрин с значениями может яснее будет.

Изображение
cirus
Цитата
вот скрин с значениями может яснее будет.

Нет скрина. Прикрепите к форуму его.
ivanTu
вот скрин еще разок.
и Еще я хоть и обозначил числа не измененными но это немного не так, дело в том что при близком расстоянии к мобу 16 меняется на 15 896 к примеру, а 49 на 48 954 к примеру.

Теперь понятно мне что Float (значение с точкой) менялся на отрицательное значение так же из за положения персонажа относительно моба в мире и имело значение то положительное то отрицательное.

Сейчас нужно покумекать и сделать значение первых двух чисел не измененным, тогда б и вопрос решился.
DarkMaster
Можно поискать какие-нибудь флаги. Посмотри память - оно может быть рядом. Не знаю как в чит инжи, но в артмани это достаточно удобно делать: открываешь область памяти и у тебя все значения на глазах в виде таблицы.

Вообще можно пойти еще и сложным путем. Можно вытащить координаты чара и координаты цели. Координаты чара точно вытаскиваются. С координатами цели сложнее - их может не существовать. Т.е. есть просто некая таблица(далеко не факт, что таблица, возможно список разбросанный по памяти) мобов с координатами, именами т.д. Когда ты берешь моба в цель, то есть неплохая вероятность, что некоторый набор значений моба копируется в структуру цели. Если так происходит, то может получится вытащить координаты цели. Если вытащишь, то найти дистанцию проблемой не будет.
ivanTu
А можно по подробнее что такое флаги , как искать , и что с ними делать?
DarkMaster
Обычные переменные, принимающие значения 1 или 0. Пример:
https://forum.uokit.com/index.php?s=&sh...st&p=209321

Искать соответственно 1 и 0 при изменении отсчета.

Цитата
15 896 к примеру, а 49 на 48 954

16к ну очень сильно смущают. Прямо-таки на разряды похоже. Открой память, посмотри, что происходит при перемещении. Мне все чутье кричит, что неправильный адрес на 1-2 байта и/или тип данных. Может и ошибаюсь, но прямо покоя не дает.
ivanTu
Нашел я байт , который скачет,
вот скрин наглядный, что можно имея эти данные с этим сделать?
DarkMaster
этот байт, надеюсь не является частью того float'а? От него можно отталкиваться и проводить коррекцию значения.

А вообще значения до и после скачка хоть как-то пересекаются? Может проще вообще просто сделать некоторый алгоритм коррекции основываясь только на изначальном значении?
ivanTu
Это не тот Float, это уже я нашел значение (2b) ,
P/S Для меня все не просто )))
а вопрос про пересечение, есть кое какие цифры но я в них не уверен на 100% не получается точно найти
примерно 15700 - 48700
DarkMaster
А число изменяется при удалении линейно на отрезаках 0-15700 и 48700-много?
Идентично ли изменение значений на этих отрезках при идентичном изменении реального ренча?

Т.е. я хочу все это дело подвести примерно под такой код:
Код
set #rangeMultipler // Некоторый множитель для приведения ренча к стандарту л2
if  #memRange < 15700
    set #range #memRange / #rangeMultipler
else
    set #range (#memRange - ( 48700 - ( 48700 - 15700 ) ) )/ #rangeMultipler
end_if
log #range

( 48700 - ( 48700 - 15700 ) - естественно превратить в константу. Написано таким образом, чтобы было понятно, что это за занчение.
ivanTu
Блин не совсем понял про что ты спрашиваешь...

Цитата
А число изменяется при удалении линейно на отрезаках 0-15700 и 48700-много?
Идентично ли изменение значений на этих отрезках при идентичном изменении реального ренча?


Я выделяю моба к примеру значение 15700, если моб дальше 16000 если еще дальше 16300 и т.д, забегаю за моба с другой стороны с противо положной, значение 48700 если выделяю моба дальше этого 48900 и т.д

Значения 15700 (не может быть меньше) как и значение 48700 это так сказать старт значений

Про идентичность, сейчас проверю
Проверил разные разные, не идентичные.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Русская версия Invision Power Board © 2001-2024 Invision Power Services, Inc.