germanshnayder Опубликовано 24 июня, 2021 Поделиться Опубликовано 24 июня, 2021 (изменено) Всем привет. Делаю скрипт на автомат. поиск структуры с координатами, вопросы изначально задавал отсюда (тема закрыта за постинг в неправильный раздел), исправил регистр с 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 совпадений по АОБскану соответственно. Все бы было полностью сломано, если б не один нюанс... Клиент кладет фуфлыжные "слепки" памяти всегда ДО истинных рабочих структур. Использовав этот скрипт покажу по скрину: Следовательно, последний результат сканирования будет правильным при любых раскладах. Но как это реализовать и записывать в метку именно его? (Главный вопрос темы) Покурил гугл и внятной инфы по этому поводу шаром покати. В качестве реализации взял вышеприведенный скрипт и попробовал добавить доп. функцию 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 для записи адреса. Изменено 24 июня, 2021 пользователем germanshnayder Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 24 июня, 2021 Поделиться Опубликовано 24 июня, 2021 Ты немного неправильно понимаешь работу твоей игры. На самом деле, она не делает слепки и не кладет их ДО действующей структуры. Наоборот, при перезагрузке локации старая память копируется в новое место и становится истинным именно новое место. А старые места подметает сборщик мусора, когда придется. Именно поэтому у тебя действующая структура всегда последняя. По скрипту - тебе не нужно перебирать циклом всю эту хрень, тебе нужен только последний элемент. Спойлер [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, и только после этого записать байты в нужную тебе метку. Но вектор я тебе дал, дальше давай сам. И еще один момент. Почитай, как из луа работать с зарегистрированными метками. А то у тебя сама метка объявлена с маленькой буквы, а в скрипте ты ее достаешь с большой буквы. Это может быть неправильно. Ссылка на комментарий Поделиться на другие сайты Поделиться
germanshnayder Опубликовано 24 июня, 2021 Автор Поделиться Опубликовано 24 июня, 2021 (изменено) 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-функции не компилятся. Работает - не трогай))) Можно закрывать. Изменено 24 июня, 2021 пользователем germanshnayder Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 25 июня, 2021 Поделиться Опубликовано 25 июня, 2021 7 часов назад, germanshnayder сказал: Тогда почему игра сразу не убирает мусор в виде большого пака неиспользующихся структур, а кладет их в свою память на час-два? Еще раз, она не кладет их в память. Она их там оставляет. То есть, загрузил ты уровень, подгрузились актуальные данные, память стала помечена, как занятая. Перезагрузил ты уровень, актуальные данные загрузились в другой участок памяти, который ранее был помечен, как свободный. А старый участок памяти, где раньше были данные, был помечен, как неиспользуемый. Когда сборщик мусора пойдет чистить память, он будет чистить именно неиспользуемые участки. А насколько часто этот сборщик мусора срабатывает - это уже от разработчиков зависит. Еще возможен вариант, что никакого сборщика мусора нет, а просто старая память помечается как неиспользуемая. Игра просто-напросто не тратит время на затирание памяти перед ее освобождением. Это ведь совершенно необязательно. Затирание произойдет, когда участок памяти снова начнет использоваться, и будет перетёрт свежими данными. И это вовсе необязательно снова будет та же самая структура. Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 27 июня, 2021 Поделиться Опубликовано 27 июня, 2021 В 25.06.2021 в 01:09, germanshnayder сказал: Удивительно, как это заработало сразу и без правок Боюсь, что проблема до конца не решена. копию структур создает не игра, а твой поток, который ты не уничтожаешь. если ты сутки поиграешь со своим скриптом - боюсь памяти у тебя не останется. Проверь тем же методом что ты описал, также 9 раз перейди в другую локу, свой последний скрипт, у тебя также будет находится 9 адресов. и 9 раз перейди в другую локу но отключая свой скрипт перед переходом. Убедишься. что виноват твой скрипт. Ссылка на комментарий Поделиться на другие сайты Поделиться
germanshnayder Опубликовано 3 июля, 2021 Автор Поделиться Опубликовано 3 июля, 2021 В 28.06.2021 в 00:17, Garik66 сказал: копию структур создает не игра, а твой поток, который ты не уничтожаешь. Нет, именно игра. Уже давно проверил, попробовав перейти по локам n-ное количество раз, а уже после запустить скрипт с добавлением строчки вывода о числе найденных сигнатур Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения