Сейчас на форуме: cppasm, asfa (+7 невидимых)

 eXeL@B —› Вопросы новичков —› Как отличить адрес от инструкций и разрозненных данных
Посл.ответ Сообщение

Ранг: 10.7 (новичок), 2thx
Активность: 0.060
Статус: Участник

Создано: 03 ноября 2016 09:53
· Личное сообщение · #1

Приветствую!

Данная тема является своего рода продолжением моей предыдущей.

Если вкратце, то мне необходимо написать программу, которая будет заменять в указанном PE-файле одни адреса на другие. С алгоритмами, релоками и прочей "обвязкой" в прошлой теме мы уже вроде разобрались (ещё раз спасибо тем, кто помог мне советами и напутствиями -- постарался расставить лайки, как мог). Сейчас же у меня встал новый вопрос.

Предположим, мне требуется заменить адрес 0xAABBCCDD на 0x11223344. Проблема в том, что последовательность байт 0x44 0x33 0x22 0x11, встреченная в PE-файле, вовсе не обязательно будет обозначать желаемый адрес -- вполне возможно, что это опкоды самостоятельной инструкции или даже куски отдельных команд.

Как в таком случае имеет смысл поступить?

Первое (и, возможно, самое глупое) решение, которое я вижу, это проверить, есть ли ссылка на адрес, по которому я нашёл указанную последовательность байт, в Relocations Table. Глупо? Или как раз так обычно и поступают?

Заранее благодарю.



Ранг: 488.1 (мудрец), 272thx
Активность: 0.350
Статус: Участник

Создано: 03 ноября 2016 11:09
· Личное сообщение · #2

b0r3d0m 100 проц рабочей проги не получится. потому что есть масса ньюансов. можно немного повысить стабильность, если у вас есть доп информация, КАК этот адрес используется в комманде и добавить поиск по маске комманды.. ну например call xxxx , mov [xxxx],0 - ваш адрес. 100 проц рабочий вариант, все равно ток руками/ проверкой

-----
Наша работа во тьме, Мы делаем, что умеем. Мы отдаем, что имеем, Наша работа во тьме....




Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 03 ноября 2016 11:12
· Личное сообщение · #3

Если при линковке не заказана эта опция, создавать таблицу, то в EXE-файле не будет вообще никакой RelocationTable.

А вообще, никак адреса от опкодов не отличишь, тут надо смириться и всё.



Ранг: 10.7 (новичок), 2thx
Активность: 0.060
Статус: Участник

Создано: 03 ноября 2016 11:35
· Личное сообщение · #4

VodoleY пишет:
100 проц рабочей проги не получится. потому что есть масса ньюансов

А чем плох вариант, предложенный в первом сообщении?

b0r3d0m пишет:
Первое (и, возможно, самое глупое) решение, которое я вижу, это проверить, есть ли ссылка на адрес, по которому я нашёл указанную последовательность байт, в Relocations Table. Глупо? Или как раз так обычно и поступают?


Разве что вот этим:

dosprog пишет:
Если при линковке не заказана эта опция, создавать таблицу, то в EXE-файле не будет вообще никакой RelocationTable

Но по дефолту Visual C++ генерирует EXE как раз с RelocationTable. Понимаю, что лучше было бы на подобные вещи не полагаться, но раз других гарантированных вариантов просто нет?

=======================

И ещё -- как тогда работают программы наподобие OgreGUI?



Ранг: 95.1 (постоянный), 247thx
Активность: 0.260.01
Статус: Участник

Создано: 03 ноября 2016 11:45
· Личное сообщение · #5

VodoleY пишет:
b0r3d0m 100 проц рабочей проги не получится.

Бред.Нужно просто отойти от формата PE на момент поиска.Смещение никуда не денется, ибо в своем софте мы работаем с файлом в двоичном виде(мы ведь не собираемся его запускать и высчитывать указатель на строку в памяти ?).И зачем, если мы хотим физически изменить содержимое файла, а не его память.Релоки и адреса нас не касаются.Пишем цикл и в зависимости от пре/пост-условий рубим его, определяя сигнатуру, которую хотим найти.

-----
TEST YOUR MIGHT




Ранг: 10.7 (новичок), 2thx
Активность: 0.060
Статус: Участник

Создано: 03 ноября 2016 11:53
· Личное сообщение · #6

unknownproject пишет:
Пишем цикл и в зависимости от пре/пост-условий рубим его, определяя сигнатуру, которую хотим найти

Не понял мысль. Можете перефразировать?



Ранг: 488.1 (мудрец), 272thx
Активность: 0.350
Статус: Участник

Создано: 03 ноября 2016 11:54 · Поправил: VodoleY
· Личное сообщение · #7

b0r3d0m пишет:
А чем плох вариант, предложенный в первом сообщении?

да потому что ища ссылки вам надо фактически карту экзешника строить, задача усложнится в разы а результата не даст, ибо ссылка на этот адрес может быть относительная.. ну типа call eax .. вобще это не сильно хорошая идея пытаться сделать универсальный патчер в том виде в котором вы хотите. по человечески это делается только ручным анализом, сбором адресов (смещений в файле) где что, и на что надо патчить. остальное будет полурабочее

Добавлено спустя 1 минуту
b0r3d0m пишет:
Не понял мысль. Можете перефразировать?

это тоже что я вам первым ответом дал. т.е искать адресс.. и потом пытаться отсеивать данные от кода.

-----
Наша работа во тьме, Мы делаем, что умеем. Мы отдаем, что имеем, Наша работа во тьме....




Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 03 ноября 2016 12:06 · Поправил: dosprog
· Личное сообщение · #8

VodoleY пишет:
вобще это не сильно хорошая идея пытаться сделать универсальный патчер в том виде в котором вы хотите.


Абсолютно.



Ранг: 10.7 (новичок), 2thx
Активность: 0.060
Статус: Участник

Создано: 03 ноября 2016 12:18
· Личное сообщение · #9

VodoleY пишет:
да потому что ища ссылки вам надо фактически карту экзешника строить

Зачем? Мне весь алгоритм видится следующим образом:

1. Ищем необходимую строку в PE-файле. Переводим file offset в VA.
2. Ищем байты в нашем PE-файле, которые равны вычисленному в первом шаге VA.
3. Проверяем, присутствует ли найденный во втором шаге адрес в RelocationTable. Если да, то это действительно обращение к нашей строке. Если нет, то это ложное срабатывание.
4. Повторяем пункты 2-3 до полного обхода PE-файла.

Тут уже справедливо заметили, что такой алгоритм не будет работать, если в PE-файле не будет RelocationTable. Ну, что поделаешь

VodoleY пишет:
ибо ссылка на этот адрес может быть относительная

Это да, согласен.




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 03 ноября 2016 18:51 · Поправил: difexacaw
· Личное сообщение · #10

b0r3d0m

Любая ссылка описана в релоках. Если она не описана там, то её обычно нет. На x64 есть RIP - адресация и в целом вычисление ссылки не на основе базы модуля(как релоки), а к примеру от начала какого то адреса, начала процедуры или текущей инструкции.

Алго ваш выше не эффективный. Нужно просто проенумить все релоки и найти ссылку, а не по ссылке искать релок.

Если в общем подходить к задаче, она сведётся к отличию данных от кода в конце концов, а это тупик. Так даже зная все начала ветвей(процедур) не получится конструктором(графом) покрыть весь код, не зная его логику работы. Так например может загружаться ссылка на код в какую то структуру, имея только эту ссылку и не зная механизм дальнейшего использования этой ссылки невозможно узнать, строка(данные) это или код. Аналитически по самим данным определить что это код можно только с некоторой вероятностью, которая увеличивается с размером кода(данных), но для это необходим уже не просто дизасм, а полноценный декомпилер, так что задачу даже можно и не рассматривать, это не разрешимо.

Но эта задача разрешима в динамике.

Добавлено спустя 6 минут
unknownproject

> Нужно просто отойти от формата PE на момент поиска.Смещение никуда не денется, ибо в своем софте мы работаем с файлом в двоичном виде

Именно формат пе и даёт дополнительные данные для анализа(как например релоки или экспорт), так к примеру CFG таблица позволяет выделить весь код, который имеется в модуле.

-----
vx




Ранг: 10.7 (новичок), 2thx
Активность: 0.060
Статус: Участник

Создано: 04 ноября 2016 11:32
· Личное сообщение · #11

difexacaw пишет:
Алго ваш выше не эффективный. Нужно просто проенумить все релоки и найти ссылку, а не по ссылке искать релок

Что вы понимаете под "проенумить все релоки"?

Мой вариант:
ищем строку -> смотрим, по какому адресу она расположена -> ищем последовательность байт, которая обозначает этот адрес -> проверяем, есть ли адрес, по которому мы нашли эту последовательность байт, в RelocationTable -> повторяем процесс.

Ваш вариант -- ???




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 07 ноября 2016 22:26
· Личное сообщение · #12

b0r3d0m

> Что вы понимаете под "проенумить все релоки"?

Enumeration"

Нет смысла два прохода для поиска делать, указатель существует только если описан как фиксап - перечислим их и проверим что по адресу искомая строка, посмотрите семпл --> Link <--.

-----
vx




Ранг: 58.3 (постоянный), 50thx
Активность: 0.040.08
Статус: Участник

Создано: 08 ноября 2016 09:29
· Личное сообщение · #13

difexacaw пишет:
указатель существует только если описан как фиксап


А Вам никогда не встречались массивы строк, где нужная может быть не первой. Ссылок на нее может и не быть вовсе. Можно ещё придумать ситуации и не одну. Так что хоть "проенумьте", хоть "переенумте" может оказаться мало толку!




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 08 ноября 2016 10:10 · Поправил: difexacaw
· Личное сообщение · #14

DrVB_5_6

Строка может быть к пример в ресурсах. Но это уже не рабочие переменные/константы, а база данных фактически. А рабочие переменные почти всегда адресуются напрямую или индексируются в массивах ссылок.

Если же используется смещение от начала какого то адреса(инструкции), то тогда релок не нужен, но норм код никакие дельтаоффсеты не юзает, стандартной релокации достаточно.

Как пример выполнялись тесты разных апликух в следующем виде - секции данных/кода блокировались полностью(N/A в памяти). Выборка данных отслеживалась и перенаправлялась в буфер, в который депакались данные из хранилища, причём через изменение непосредственно смещения в инструкции - через изменение соответствующего релока. Это даже на больших апликухах работало, типо гуглохрома. Хотя использовались и прочие механизмы, но с релоками успешно всё работало.

-----
vx




Ранг: 58.3 (постоянный), 50thx
Активность: 0.040.08
Статус: Участник

Создано: 08 ноября 2016 14:01 · Поправил: DrVB_5_6
· Личное сообщение · #15

difexacaw пишет:
Это даже на больших апликухах работало, типо гуглохрома.


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

А то, что где-то что-то когда-то срабатывало, вообще ни о чем не говорит.
Впрочем во втором посте
VodoleY пишет:
100 проц рабочей проги не получится. потому что есть масса ньюансов.

Тут добавить абсолютно нечего.
И надо четко формулировать задачу, ограничивать условия. При определённых ограничениях задача может иметь решение, но в такой постановке, как сформулировано в названии темы, задача просто неразрешима.
Хоть статический анализ будете пользовать, хоть динамический.
difexacaw пишет:
норм код никакие дельтаоффсеты не юзает

Странное утверждение. Постоянно сталкиваюсь. Не знал, что это не "норм код"! Вроде как на VC или GCC скомпилировано.




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 08 ноября 2016 14:12
· Личное сообщение · #16

DrVB_5_6

> Не знал, что это не норм код!

Это не нормальный код, потому что нельзя никак узнать что по ссылке находится, код или данные. Вот пример:



Такое в разных комбинациях бывает - сразу данные за процедурным ветвлением, или вычисление смещения от него(дельтаоффсет). Такие конструкции усложняют разбор кода, можно обнаружить это по шаблону call/pop, но дальше в общем сложно что то обработать, либо вообще невозможно.

> Условия могут быть необходимые, могут быть достаточные, ну а высший писк - необходимые и достаточные.

Могут быть достаточными в локальной области, но в общем не достаточными

-----
vx



 eXeL@B —› Вопросы новичков —› Как отличить адрес от инструкций и разрозненных данных
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати