Что происходит с оффсетами при перезапуске процесса?

Начинающий
Статус
Оффлайн
Регистрация
20 Ноя 2021
Сообщения
14
Реакции[?]
0
Поинты[?]
0
Никак не могу понять. Предположим у нас есть процесс в котором тысячи структур и переменных. Предположим я любым доступным способом нашел актуальный оффсет к переменной для текущей сессии. Но ведь после перезапуска программы данные записываются по другим адресам, разве нет? Перелопатил кучу литературы на эту тему. Все, что нашел - статьи про поиск паттерна в оперативной памяти. Но что делать, если паттерн слишком простой и встречается часто и не позволяет однозначно идентифицировать объект в памяти?
 
*BLUHGANG* vs godless braindead users 15v15 *shayd
Пользователь
Статус
Оффлайн
Регистрация
20 Мар 2020
Сообщения
100
Реакции[?]
52
Поинты[?]
0
увеличить размер паттерна до такой степени, пока совпадения не будут сведены к нулю
 
IRQL_APC_LEVEL
Пользователь
Статус
Оффлайн
Регистрация
25 Авг 2018
Сообщения
211
Реакции[?]
88
Поинты[?]
3K
Никак не могу понять. Предположим у нас есть процесс в котором тысячи структур и переменных. Предположим я любым доступным способом нашел актуальный оффсет к переменной для текущей сессии. Но ведь после перезапуска программы данные записываются по другим адресам, разве нет? Перелопатил кучу литературы на эту тему. Все, что нашел - статьи про поиск паттерна в оперативной памяти. Но что делать, если паттерн слишком простой и встречается часто и не позволяет однозначно идентифицировать объект в памяти?
Ты плохо искал. В большинстве процессов приминяется штука под названием - ASLR (address space layout randomization), эт технология заставляет распологать данные в радомном месте, в памяти. *бтв, ее может и не быть, и тогда все намного проще xD*.
Из-за этого после каждого рестарта (или выделения дин. памяти) у тебя данные находятся по разным адресам, чтобы решить эту "проблему" тебе нужно найти цепочку указателей, которые приведут тебя к значению. Приложение в любом случае как-то работает с данными, которые тебе нужны, так что поиск нужной цепочки - это лишь вопрос времени, а она, ЗА ИСКЛЮЧЕНИЯМИ, всегда есть.
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
20 Ноя 2021
Сообщения
14
Реакции[?]
0
Поинты[?]
0
Ты плохо искал. В большинстве процессов приминяется штука под названием - ASLR (address space layout randomization), эт технология заставляет распологать данные в радомном месте, в памяти. *бтв, ее может и не быть, и тогда все намного проще xD*.
Из-за этого после каждого рестарта (или выделения дин. памяти) у тебя данные находятся по разным адресам, чтобы решить эту "проблему" тебе нужно найти цепочку указателей, которые приведут тебя к значению. Приложение в любом случае как-то работает с данными, которые тебе нужны, так что поиск нужной цепочки - это лишь вопрос времени, а она, ЗА ИСКЛЮЧЕНИЯМИ, всегда есть.
Спасибо за ответ, это, думаю, то что нужно. Я уже слышал про ASLR, но не увидел, что там используются цепочки указателей. Если сможете привести какую-нибудь литературу или еще что-то, что можно покурить, то буду крайне благодарен :)
увеличить размер паттерна до такой степени, пока совпадения не будут сведены к нулю
Как вы предлагаете увеличить размер паттерна, например, вот такой структуры? :)
C++:
struct Foo {
    
    char c;
    int i;
    
}
 
vk.com/ahkcsgocheat
Пользователь
Статус
Оффлайн
Регистрация
21 Апр 2020
Сообщения
380
Реакции[?]
64
Поинты[?]
2K
Есть без патерна способ находить адресс, я правда не знаю, где информацию взять. По позиции байтов можно найти адрес, я так нахожу у себя в чите.
 
Начинающий
Статус
Оффлайн
Регистрация
20 Ноя 2021
Сообщения
14
Реакции[?]
0
Поинты[?]
0
Есть без патерна способ находить адресс, я правда не знаю, где информацию взять. По позиции байтов можно найти адрес, я так нахожу у себя в чите.
Посткодинг не интересует. Если есть конкретная теория - говорите, я удовольствием приму ответ. Размазанные же ответы или ответы в стиле "Вот сюда ткни, а зачем - не знаю" мне не нужны, извините

P.S. Если под позицией байтов вы имели ввиду определенное характерное расположение статичных байт, то это и есть паттерн. Он же шаблон
 
vk.com/ahkcsgocheat
Пользователь
Статус
Оффлайн
Регистрация
21 Апр 2020
Сообщения
380
Реакции[?]
64
Поинты[?]
2K
"Вот сюда ткни, а зачем - не знаю"
Чего не знаю, я как-бы читы создавал свои. И я определяю адрес по позиции байтов (не шаблоны). Не знаю, почему так, информацию нигде не нашел. Но все работает.
 
Последнее редактирование:
Пользователь
Статус
Оффлайн
Регистрация
21 Окт 2019
Сообщения
82
Реакции[?]
41
Поинты[?]
13K
... Но что делать, если паттерн слишком простой и встречается часто и не позволяет однозначно идентифицировать объект в памяти?
Если патерен не уникален, то можно получать нужный стат адрес по ссылке. По ссылке это то место ,где вызывается нужная тебе функция.
Допустим есть Н функция которая расположена в файле по смещению program.exe+12345; И если не получается сделать патерн на саму функцию (мало уникальных байт).

Нужно найти места где она вызвается и делать Паттерн уже на то место , где вызывается . Найти можно в ida через xref перейдя на адрес функции и нажав X.
Либо сделать самому xref, я так раньше делал , до того как понял как идой пользоваться -_-, Я искал байты начала Call'ов и проверял Смещение инструкции + ее байты куда собственно идет call ( В x64), Гет Абсолют адрес называют получение такого адреса. (мб немного ошибся как он получается ,я уже точно не помню ,так примерно)
Собственно после того ты нашел , где вызывается нужная тебе функция, то ты уже делаешь патерн на call program.exe+12345 и берешь от туда уже адрес. А если тебе потом уже нужно брать адресс из этой функции, то ты уже берешь смещение относительно нее типо вот полный пример пвсевдокода :
Код:
xrefinstructionadr = findpatter("program.exe","48 ? ? ff 25 90 90 90  ?");

Fooadr = getabsAddr(xrefinstructionadr); // там вроде надо от адреса инструкции прибавлять число, что бы не брать байты call,  а брать байты который нужны для вычилсения  адреса .

VeryCoolInstructionadr = Fooadr+0x1C;

engineadr = getAbsAddress(VeryCoolInstruction);

Programengine* engine = (Programengine*)engineadr;

std::cout <<engine->Version<<"\n" ;
// п.с само смещение от базового адресса в таком случаее не нужно, но если тебе вруг все же для чего-то надо, то то просто из Абсадресса вычитай базовый так и получишь смещение от базового, главное что бы это было смещение относительно одного модуля .
Еще можно найти vtable, я с ними особо не работал так, что хз так видел пару примеров примерно понимаю ,но мне обычно нужна 1 опр функция , а др мне не нужны так ,что я на прямую делаю.
И да так чисто на всякий Патерны на .data / динам память, ОБЫЧНО нет смысла делать , нужно патрен на код делать. (просто я одному челу пытался сказать, но мне кажется ему пофиг, он находит значение и сразу в дизасемблере открывает , а не в отладчике и не ищит инструкцию которая читает / пишит и вот на нее уже патерн надо делать. )

А и да если это C# , Java , то там свои приколы.
 
Начинающий
Статус
Оффлайн
Регистрация
20 Ноя 2021
Сообщения
14
Реакции[?]
0
Поинты[?]
0
Если патерен не уникален, то можно получать нужный стат адрес по ссылке. По ссылке это то место ,где вызывается нужная тебе функция.
Допустим есть Н функция которая расположена в файле по смещению program.exe+12345; И если не получается сделать патерн на саму функцию (мало уникальных байт).

Нужно найти места где она вызвается и делать Паттерн уже на то место , где вызывается . Найти можно в ida через xref перейдя на адрес функции и нажав X.
Либо сделать самому xref, я так раньше делал , до того как понял как идой пользоваться -_-, Я искал байты начала Call'ов и проверял Смещение инструкции + ее байты куда собственно идет call ( В x64), Гет Абсолют адрес называют получение такого адреса. (мб немного ошибся как он получается ,я уже точно не помню ,так примерно)
Собственно после того ты нашел , где вызывается нужная тебе функция, то ты уже делаешь патерн на call program.exe+12345 и берешь от туда уже адрес. А если тебе потом уже нужно брать адресс из этой функции, то ты уже берешь смещение относительно нее типо вот полный пример пвсевдокода :
Код:
xrefinstructionadr = findpatter("program.exe","48 ? ? ff 25 90 90 90  ?");

Fooadr = getabsAddr(xrefinstructionadr); // там вроде надо от адреса инструкции прибавлять число, что бы не брать байты call,  а брать байты который нужны для вычилсения  адреса .

VeryCoolInstructionadr = Fooadr+0x1C;

engineadr = getAbsAddress(VeryCoolInstruction);

Programengine* engine = (Programengine*)engineadr;

std::cout <<engine->Version<<"\n" ;
// п.с само смещение от базового адресса в таком случаее не нужно, но если тебе вруг все же для чего-то надо, то то просто из Абсадресса вычитай базовый так и получишь смещение от базового, главное что бы это было смещение относительно одного модуля .
Еще можно найти vtable, я с ними особо не работал так, что хз так видел пару примеров примерно понимаю ,но мне обычно нужна 1 опр функция , а др мне не нужны так ,что я на прямую делаю.
И да так чисто на всякий Патерны на .data / динам память, ОБЫЧНО нет смысла делать , нужно патрен на код делать. (просто я одному челу пытался сказать, но мне кажется ему пофиг, он находит значение и сразу в дизасемблере открывает , а не в отладчике и не ищит инструкцию которая читает / пишит и вот на нее уже патерн надо делать. )

А и да если это C# , Java , то там свои приколы.
Спасибо за развернутый ответ, думаю это тоже будет мне полезно
 
Сверху Снизу