Перейти к содержанию

Использование строго последнего результата AOBscan в LUA скрипте


Рекомендуемые сообщения

Всем привет. Делаю скрипт на автомат. поиск  структуры с координатами, вопросы изначально задавал отсюда (тема закрыта за постинг в неправильный раздел), исправил регистр с eax на rcx и максимально упростил код (сделав другую часть работы через систему поинтеров CE), в итоге он заработал правильно, вот, если кто хочет взглянуть: 

Спойлер

[ENABLE]


aobscan(INJECT,05 00 00 00 00 00 00 00 6A 43 06 F8 00 00 00 00 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX 05 00 00 00 00 00 00 00 XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8) // should be unique
alloc(adresspl,50)
label(value)
registersymbol(adresspl)
registersymbol(value)

adresspl:
mov rcx,INJECT
mov dword [value],rcx
ret

value:
db 0 0 0 0 0 0 0 0

createthread(adresspl)
[DISABLE]
dealloc(adresspl)
unregistersymbol(adresspl)
unregistersymbol(value)

 

 

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

 

Все бы было полностью сломано, если б не один нюанс... Клиент кладет фуфлыжные "слепки" памяти всегда ДО истинных рабочих структур.

 

Использовав этот скрипт покажу по скрину:

unknown.png

 

Следовательно, последний результат сканирования будет правильным при любых раскладах. Но как это реализовать и записывать в метку именно его? (Главный вопрос темы)

 

Покурил гугл и внятной инфы по этому поводу шаром покати.

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

Спойлер

[ENABLE]
{$LUA}
t = getAddress( "Value" )
sl = AOBScan("05 00 00 00 00 00 00 00 6A 43 06 F8 00 00 00 00 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX 05 00 00 00 00 00 00 00 XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8");
if(sl == nil) then
	print("No code found!");
else
  j = stringlist_getCount(sl);
   print("Found:",j);
   for i = 1, j do
   print(stringlist_getString(sl,i-1));
   writeBytes(t, sl);
   end
   object_destroy(sl);
end

[DISABLE]

 

 

А также простецкий АА скрипт под создание метки value и отведение под нее памяти (сделал эти скрипты отдельно т к при совмещении компилятор ругается):

Спойлер

[ENABLE]
{$ASM}
alloc(adresspl,1)
label(value)
registersymbol(value)
registersymbol(adresspl)

adresspl:

value:
db 0 0 0 0 0 0 0 0 0

[DISABLE]
{$ASM}
dealloc(adresspl)
unregistersymbol(value)
unregistersymbol(adresspl)

 

 

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

Изменено пользователем germanshnayder
Ссылка на комментарий
Поделиться на другие сайты

Ты немного неправильно понимаешь работу твоей игры. На самом деле, она не делает слепки и не кладет их ДО действующей структуры. Наоборот, при перезагрузке локации старая память копируется в новое место и становится истинным именно новое место. А старые места подметает сборщик мусора, когда придется. Именно поэтому у тебя действующая структура всегда последняя.

 

По скрипту - тебе не нужно перебирать циклом всю эту хрень, тебе нужен только последний элемент.

Спойлер

[ENABLE]
{$LUA}
t = getAddress( "Value" )
sl = AOBScan("05 00 00 00 00 00 00 00 6A 43 06 F8 00 00 00 00 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX 05 00 00 00 00 00 00 00 XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8");
if(sl == nil) then
	print("No code found!");
else
  j = stringlist_getCount(sl); // получаем количество найденных элементов
  print("Found:",j);
  str = stringlist_getString(sl,j-1) // читаем строку из последнего элемента (индекс его равен длине всего списка минус единица, так как в списках индексация идет с нуля)
  print("Working address: ", str)
  writeBytes(t, str); // насчет этого не уверен, с Lua в СЕ очень мало работал
  object_destroy(sl);
end

[DISABLE]

 

 

str = stringlist_getString(sl,j-1) - скорее всего, после этого тебе нужно будет полученную строку перевести в число средствами Lua CE, и только после этого записать байты в нужную тебе метку. Но вектор я тебе дал, дальше давай сам.

 

И еще один момент. Почитай, как из луа работать с зарегистрированными метками. А то у тебя сама метка объявлена с маленькой буквы, а в скрипте ты ее достаешь с большой буквы. Это может быть неправильно.

Ссылка на комментарий
Поделиться на другие сайты

16 часов назад, Xipho сказал:

Ты немного неправильно понимаешь работу твоей игры. На самом деле, она не делает слепки и не кладет их ДО действующей структуры. Наоборот, при перезагрузке локации старая память копируется в новое место и становится истинным именно новое место. А старые места подметает сборщик мусора, когда придется. Именно поэтому у тебя действующая структура всегда последняя.

Тогда почему игра сразу не убирает мусор в виде большого пака неиспользующихся структур, а кладет их в свою память на час-два? Нет, это не упрек, мне просто интересно.

 

16 часов назад, Xipho сказал:

По скрипту - тебе не нужно перебирать циклом всю эту хрень, тебе нужен только последний элемент.

Я знаю, просто при начале работы не понимал как в луа назначаются переменные, поэтому ляпнул максимально костыльным способом)

 

 

Так или иначе - вопрос решен.

Долго гуглил как успешно запихнуть это в метку, перебирал StringToByteTable и прочие write функции (которые не дали результата)

В итоге случайно наткнулся на это

Ранее не знал про фичу AutoAssemble, и попробовал таким махом склепать солянку из своего первого скрипта и скрипта вышеприведенного на луа:

Спойлер

[ENABLE]
{$LUA}
sl = AOBScan("05 00 00 00 00 00 00 00 6A 43 06 F8 00 00 00 00 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX 05 00 00 00 00 00 00 00 XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX F8");
if(sl == nil) then
	print("No code found!");
else
  j = stringlist_getCount(sl);
  str = stringlist_getString(sl,j-1)
  registerSymbol("bytes",str)

  autoAssemble([[

alloc(write, 1)
registersymbol(write)
CreateThread(write)

write:

mov rcx, bytes
mov dword [value],rcx
ret

]])

  unregisterSymbol("bytes")
  object_destroy(sl);
end

[DISABLE]

 

 

Удивительно, как это заработало сразу и без правок, теперь он кладет в метку истинный адрес. Спасибо)

P.S. Создание value оставил также отдельным скриптом, т к dealloc и unregistersymbol в aa-функции не компилятся. Работает - не трогай)))

unknown.png

Можно закрывать.

 

Изменено пользователем germanshnayder
Ссылка на комментарий
Поделиться на другие сайты

  • Xipho закрыл тема
7 часов назад, germanshnayder сказал:

Тогда почему игра сразу не убирает мусор в виде большого пака неиспользующихся структур, а кладет их в свою память на час-два?

Еще раз, она не кладет их в память. Она их там оставляет. То есть, загрузил ты уровень, подгрузились актуальные данные, память стала помечена, как занятая. Перезагрузил ты уровень, актуальные данные загрузились в другой участок памяти, который ранее был помечен, как свободный. А старый участок памяти, где раньше были данные, был помечен, как неиспользуемый. Когда сборщик мусора пойдет чистить память, он будет чистить именно неиспользуемые участки. А насколько часто этот сборщик мусора срабатывает - это уже от разработчиков зависит.

 

Еще возможен вариант, что никакого сборщика мусора нет, а просто старая память помечается как неиспользуемая. Игра просто-напросто не тратит время на затирание памяти перед ее освобождением. Это ведь совершенно необязательно. Затирание произойдет, когда участок памяти снова начнет использоваться, и будет перетёрт свежими данными. И это вовсе необязательно снова будет та же самая структура.

Ссылка на комментарий
Поделиться на другие сайты

В 25.06.2021 в 01:09, germanshnayder сказал:

Удивительно, как это заработало сразу и без правок

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

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

Ссылка на комментарий
Поделиться на другие сайты

  • Xipho открыл тема
В 28.06.2021 в 00:17, Garik66 сказал:

копию структур создает не игра, а твой поток, который ты не уничтожаешь.

Нет, именно игра. Уже давно проверил, попробовав перейти по локам n-ное количество раз, а уже после запустить скрипт с добавлением строчки вывода о числе найденных сигнатур

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.