eXeLab
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 2 августа!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Русский / Russian English / Английский

Сейчас на форуме: (+3 невидимых)
 · Начало · Статистика · Регистрация · Поиск · ПРАВИЛА ФОРУМА · Язык · RSS · SVN ·

 eXeL@B —› Программирование —› Перезапись кода.
Посл.ответ Сообщение


Ранг: 292.2 (наставник)
Статус: Участник

Создано: 12 октября 2016 02:14 New!
Цитата · Личное сообщение · #1

Нужен алгос/абстракция для следующей задачи.

Имеется массив областей памяти, занимаемых некоторым кодом, это блоки памяти, в которых код расположен, они соответственно могут располагаться по разным базовым адресам, иметь произвольный размер и не пересекаться.

Необходимо записать новый код поверх этих блоков, расположить его в этих областях памяти.

Проблема заключается в следующем. Записать код нужно с оптимизацией по размеру ветвлений, если возможно короткое ветвление, то не использовать длинное. Если заполнять блок инструкциями и ветвь(процедура) не поместиться, то следующие инструкции располагаются в новом блоке и оба блока связываются ветвлением. Размер его так же может быть длинным или коротким, он зависит от адреса самого ветвления в блоке и адреса следующего блока. Что бы это вычислить необходимо заполнить текущий блок до конца и определить пригодность следующего блока для записи хотя бы одной инструкции и ветвления при необходимости, опять же размер ветвления будет завесить от последующих блоков, тоесть это рекурсия и довольно запутанная задача. Если при заполнении блока он окажется не пригоден, то это может повлиять на все предыдущие блоки из за удлинения ветвлений

Ранг: 488.4 (мудрец)
Статус: Участник

Создано: 12 октября 2016 08:28 New!
Цитата · Личное сообщение · #2

difexacaw вы что курили перед сном? вцелом все что вы описали.. если я правильно понял, это код вирусняка


Ранг: 56.2 (постоянный)
Статус: Участник

Создано: 12 октября 2016 12:36 New!
Цитата · Личное сообщение · #3

лихо закручен сюжет.


Ранг: 292.2 (наставник)
Статус: Участник

Создано: 12 октября 2016 17:35 · Поправил: 12 октября 2016 17:37 difexacaw New!
Цитата · Личное сообщение · #4

VodoleY

К малваре отношения не имеет(там такое не юзается), это скорее наоборот.

Ранг: 12.0 (новичок)
Статус: Участник

Создано: 12 октября 2016 18:01 · Поправил: 12 октября 2016 18:05 neshta New!
Цитата · Личное сообщение · #5

За такое описание задачи нужно клавиатурой бить.
Что мешает завести список адресов ветвлений и при переходе на новый блок обрабатывать неправильные ветви?
Адреса предыдущего блока известны, адрес нового блока известен и стало быть вычисления тривиальны.
Вектора достаточно и нет никакой необходимости в рекурсии, достаточно цикла на размер буфера, при каждом новом блоке править старый, и так до полной записи буфера.
Можно отложить запись первого блока до нахождения второго, после нехитрых вычислений можно писать часть буфера на размер первого блока и так до финального, в этом варианте правок не нужно вносить, поскольку буфер можно формировать, как душе угодно, поскольку о предыдущем блоке известно все, можно перезаписывать, морфить или выкидывать ветви. В данном случае нет необходимости в рекурсии, достаточно записать начальный и конечный адрес блока.
Профит.
Скорее всего не осилил задачу, ибо описание удручает.
Ps. DBI тул пишите?


Ранг: 111.0 (ветеран)
Статус: Участник

Создано: 12 октября 2016 18:17 · Поправил: 12 октября 2016 18:20 Rainbow New!
Цитата · Личное сообщение · #6

VodoleY пишет:
difexacaw вы что курили перед сном? вцелом все что вы описали.. если я правильно понял, это код вирусняка


Сначала была тема - обход аверов, теперь и до вкусняшек добрались )))) Видимо кто-то во истину хочет в голове ничего не имея Дядю Женю отшлепать..

Ранг: 71.7 (постоянный)
Статус: Участник

Создано: 12 октября 2016 18:19 New!
Цитата · Личное сообщение · #7

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


Ранг: 292.2 (наставник)
Статус: Участник

Создано: 12 октября 2016 18:23 New!
Цитата · Личное сообщение · #8

neshta

> Что мешает завести список адресов ветвлений и при переходе на новый блок обрабатывать неправильные ветви?
...

Между блоками есть ссылки, это обычные ветвления не для связывания блоков. При записи какой то инструции, на которую такое ветвление есть и удлиняется сместится всё, как и последующие блоки, так и предыдущие.

> Ps. DBI тул пишите?

Ага.

Ранг: 12.0 (новичок)
Статус: Участник

Создано: 12 октября 2016 18:23 New!
Цитата · Личное сообщение · #9

Rainbow пишет: Сначала была тема - обход аверов, теперь и до вкусняшек добрались

Задача к аверам не имеет отношения, здесь более фундаментальные вещи CFI\CFG, а это можно использовать и в вполне светлых целях, например защита от ROP.


Ранг: 292.2 (наставник)
Статус: Участник

Создано: 12 октября 2016 18:26 · Поправил: 12 октября 2016 18:32 difexacaw New!
Цитата · Личное сообщение · #10

hash87szf

> Тот же код что пишет новые инстракшн будет проверять длину блоков?

Да.

> Влазит мой блок в старый блок?

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

Ранг: 12.0 (новичок)
Статус: Участник

Создано: 12 октября 2016 18:33 New!
Цитата · Личное сообщение · #11

difexacaw пишет: Нужно не такое, а последовательно заполнить

В первом цикле пройтись по всем блокам, записать адреса в массив, а вторым циклом записать блоки.
Читаем блоки с учетом размера буфера, когда получаем достаточное количество блоков (с учетом ссылок), то вторым циклом пишем все блоки. На размер памяти нет ограничений?


Ранг: 292.2 (наставник)
Статус: Участник

Создано: 12 октября 2016 18:46 New!
Цитата · Личное сообщение · #12

neshta

Покажите плз на примере, а то не понятно

На буфер ограничений нет.

Ранг: 12.0 (новичок)
Статус: Участник

Создано: 12 октября 2016 20:44 New!
Цитата · Личное сообщение · #13

difexacaw пишет:Покажите плз на примере, а то не понятно

Уже года три как забросил кодинг и на машине нет компиля, поэтому псевдокод.
Для удобства буду использовать dict.

vec = [] наш вектор для сохранения промежуточных данных.
буду исходить из предположения, что у вас уже есть трейсер\читалка памяти.
x,y,z = 0 переменные для хранения промежуточного результата
крутим цикл до нахождения необходимого места, если оно конечно есть
for инструкция in листинг[начало, конец] je 0x000, call 0x000, etc
{
сохраняем промежуточные данные, начало блока, размер блока
if инструкция == ссылка // проверяем на ребро je\jmp\jnz\etc
{
vec.add( { начало=x, конеч=y, длина=z } )
обнуляем переменные
}
}
for v in vec
{
листинг[v.x, v.y].write(buffer[v.z]) не забываем учитывать длину инструкций, можно проверить влезет ли данный размер в данный блок, сложение длин инструкций.
pos+= v.z сохраняем размер записанного блока, ибо незачем усложнять описание с позицией массива -1. Далее смещаем начальную позицию буфера на pos, хотя это и так очевидно.
}
собственно все, думаю промежуточные данные незачем описывать, ибо все очевидно.

| Сообщение посчитали полезным: difexacaw



Ранг: 292.2 (наставник)
Статус: Участник

Создано: 13 октября 2016 00:08 New!
Цитата · Личное сообщение · #14

neshta

Всё равно не понимаю. Vec[] будет содержать массив блоков, на которые есть ссылки или текущих. Но ветвление же не обязательно на начало массива, тоесть ветви(рёбра") расположены не в начале блоков, они могут быть где угодно.

Ранг: 12.0 (новичок)
Статус: Участник

Создано: 13 октября 2016 00:16 New!
Цитата · Личное сообщение · #15

difexacaw пишет: Vec[] будет содержать массив блоков, на которые есть ссылки или текущих

Vec[] будет содержать адрес начала блока и адрес конца блока пригодного для записи.
Лучше скину в ЛС пример с линком на описание графа.


Ранг: 292.2 (наставник)
Статус: Участник

Создано: 13 октября 2016 00:31 · Поправил: 13 октября 2016 00:33 difexacaw New!
Цитата · Личное сообщение · #16

neshta

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

Ранг: 12.0 (новичок)
Статус: Участник

Создано: 13 октября 2016 00:40 New!
Цитата · Личное сообщение · #17

difexacaw пишет: Вот проходим мы по графу, обнаружили что на инструкцию есть ветвление. Как дальше поступить

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


Ранг: 292.2 (наставник)
Статус: Участник

Создано: 13 октября 2016 00:44 New!
Цитата · Личное сообщение · #18

neshta

Так граф у меня есть, там есть для каждой инструкции список ссылок на ветвления. Просто не хотел упоминать термин графы, что бы не усложнять

> удлинить ветвь, но опять же, зависит от того, что там идет дальше

Именно про это и вопрос, а заполнить абы как блоки куда что влезет это не проблема.

Ранг: 12.0 (новичок)
Статус: Участник

Создано: 13 октября 2016 00:54 New!
Цитата · Личное сообщение · #19

difexacaw пишет: Именно про это и вопрос

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


Ранг: 292.2 (наставник)
Статус: Участник

Создано: 13 октября 2016 01:12 New!
Цитата · Личное сообщение · #20

neshta

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

Добавлено спустя 3 минуты
На счёт рекурсии - я описал в первом посте, мы не можем знать заранее, сколько инструкций влезет в текущий блок, для этого нужно его заполнить и заполнить последующие. Если какой то блок окажется не достаточного размера, то это может удлинить ветвления всех предыдущих блоков.

Ранг: 12.0 (новичок)
Статус: Участник

Создано: 13 октября 2016 01:35 New!
Цитата · Личное сообщение · #21

difexacaw пишет: Если при этом длина удлиниться, то придётся выполнять повторное заполнение блоков, но не ясно с каких начать.

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

difexacaw пишет: На счёт рекурсии - я описал в первом посте, мы не можем знать заранее, сколько инструкций влезет в текущий блок

завести еще один буфер на адреса смещений и в третьем цикле уже точно будем знать что где и что куда может влезть.


Ранг: 292.2 (наставник)
Статус: Участник

Создано: 15 октября 2016 22:14 New!
Цитата · Личное сообщение · #22

Накидали бесполезных ссылок на теорию графов в лк, эта матчасть всегда оторвана от реала и не пригодна. Вопрос открыт.


Ранг: 292.2 (наставник)
Статус: Участник

Создано: 17 октября 2016 11:44 New!
Цитата · Личное сообщение · #23

Найдено следующее решение в общем виде:

Code:
  1. Fix:
  2.          Fix(J)  ; Записываем инструкцию J.
  3.             J.Fixed = 1
  4.          if Overflow      ; Переполнение блока.
  5.                  J.Fixed = 0
  6.                  J = J.Back      ; Предыдущая инструкция.
  7.                  if BlockIsEmpty ; Нет места для записи инструкции.
  8.                         FreeBlock()
  9.                         B = AllocNewBloc()
  10.                         FixRefs(B)     ; Изменяем все ссылки в ветвлениях на новый блок.
  11.                         > Walk                 ; Пересчитываем размер ветвлений.
  12.                  else
  13.                         > Fix
  14.                  fi
  15.          fi
  16.          Очищаем маркер Fixed для перетираемых инструкций.
  17.          if J.Refs        ; Имеются ветвления на текущую инструкцию.
  18.          Walk:
  19.                  ; Проходим по списку ветвлений(R):
  20.                  if R.Fixed
  21.                         Если размер ветвления увеличился:
  22.                               Push(J)       ; Сохраняем описатель в стеке.
  23.                               J = J.Refs{}  ; Выбираем ветвление.
  24.                               > Fix         ; Начинаем переписывать блок.
  25.                         fi
  26.                  fi
  27.          fi
  28.          if J.Last        ; Последняя инструкция в блоке.
  29.                  Pop(J)
  30.                  > Walk
  31.          else
  32.                  J = J.Next      ; Выбираем следующую инструкцию для заполнения.
  33.                  > Fix
  34.          fi

| Сообщение посчитали полезным: neshta

 eXeL@B —› Программирование —› Перезапись кода.

Оригинальный DVD-ROM: eXeL@B DVD !

Вы находитесь на форуме сайта EXELAB.RU
Проект ReactOS