Сейчас на форуме: jinoweb (+6 невидимых)

 eXeL@B —› Программирование —› Трансляция асм кода (от меток к реальным адресам)
Посл.ответ Сообщение

Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 03 января 2018 15:11
· Личное сообщение · #1

С Наступившим!
Вообщем попытаюсь объяснить на пальцах - есть код примерно такого вида (утрирую):
Code:
  1. NOP
  2. NOP
  3. NOP
  4. CMP RDX, R15
  5. JL $1
  6. CMP RDX, R15
  7. JG $1
  8. NOP
  9. NOP
  10. TEST R15B, R15B
  11. JE $1
  12. NOP
  13. NOP
  14. NOP
  15. NOP
  16. MOVABS R15, #CONST
  17. %1 MOV EAX, [R13]

изобретаю велосипед - условным переходам JE/JG/JL... используя операнд назначения $1 (это указатель на метку) нужно прыгнуть на собственно саму метку
Code:
  1. %1
. Как это сделать БЫСТРО и КОРРЕКТНО?
Мыслю так - минимум требуется три итерации:
1. Черновая (draft) - берем адрес метки %1 и адрес первой инструкции от фонаря. Строим таблицу размеров инструкций - что сколько примерно занимает места, ибо ВООБЩЕ НЕ ЗНАЕМ, ГДЕ ЭТА МЕТКА и куда точно прыгать. Плевать, сколько условные переходы могут занимать байт в этом случае.
2. Чистовая (precision) - зная примерное количество занимаемых байт каждой инструкции, ребилдим таблицу. Взводим флаг повтора для следующей итерации, когда размеры draft != precision (если условный переход был 6 байт, а превратился в short. безусловный 5 байт - в 2 байта).
3. Чистовая-повторная (precision repeat) - если в предыдущем шаге флаг повтора взведен (draft != precision), то требуется с самого начала скорректировать операнды ВСЕХ условных переходов. Но, опять-же, далеко не факт, что здесь-м размеры инструкций совпадут с предыдущим шагом.

Может это как-то по другому делается?




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 03 января 2018 15:18
· Личное сообщение · #2

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

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


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

Создано: 03 января 2018 18:26
· Личное сообщение · #3

ELF_7719116

Главная проблема в рекурсивной функции, если смещение удлиниться, то это сместит остальные ветвления. Эта же проблема имеется и при изменении кода.

Решение зависит от модели графа. В самом простом случае следует начинать пересчёт размера всех ветвлений, если хоть одно удлинится.

-----
vx




Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 03 января 2018 19:44
· Личное сообщение · #4

Archer пишет:
Закладывай все переходы длинные

Да я тоже об этому думал, но как объяснить XEDParse/asmjit, чтобы они автоматом long переходы ставили, а не short?
difexacaw пишет:
Главная проблема в рекурсивной функции, если смещение удлиниться, то это сместит остальные ветвления.

Так я жэ про ето - пересчитывать можно бесконечно




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

Создано: 03 января 2018 20:17 · Поправил: difexacaw
· Личное сообщение · #5

ELF_7719116

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

-----
vx





Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 03 января 2018 20:23
· Личное сообщение · #6

Да и не надо асмам объяснять, тыкай на 1 проходе 6 нопов. А на 2 проходе тыкай переходы. Воткнёт длинный-как раз на 6 байт. Воткнёт короткий-да и фиг с ним, будет 4 нопа ещё.

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


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

Создано: 03 января 2018 20:27
· Личное сообщение · #7

Archer

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

-----
vx





Ранг: 337.6 (мудрец), 224thx
Активность: 0.210.1
Статус: Участник
born to be evil

Создано: 03 января 2018 21:15
· Личное сообщение · #8

difexacaw
постпроцессор сделать?

-----
От многой мудрости много скорби, и умножающий знание умножает печаль




Ранг: 173.8 (ветеран), 208thx
Активность: 0.120.36
Статус: Участник

Создано: 03 января 2018 21:17
· Личное сообщение · #9

difexacaw пишет:
не есть общее решение

Если каждый раз пилить "общее решение" за всю жизнь можно не написать ни одной работающей софтины

Тут вроде вполне применимо. Я в приблизительно* похожей ситуации делал "вторую итерацию" в виде патчера, который проходился по скомпилированному файлу и по маске перезаписывал нужные адреса.
Прошли годы, сабж работает без проблем до сих пор на всех ОС (да и почему бы ему не работать?).



Ранг: 262.5 (наставник), 337thx
Активность: 0.340.25
Статус: Участник

Создано: 03 января 2018 21:48 · Поправил: TryAga1n
· Личное сообщение · #10

Парни, не накидывайтесь на Клерка. Я долго думал над эпитетом, который ярче всего охарктеризовал бы его и понял, что это - идеалист. Человек стремится написать идеальный код и рассмотреть все возможные и невозможные ситуации, в которых этот самый код побывает. Каждый мыслит по-своему, но это не повод для гнобления. Мир всем!




Ранг: 312.0 (мудрец), 349thx
Активность: 0.460.65
Статус: Участник
Advisor

Создано: 03 января 2018 22:41
· Личное сообщение · #11

упс ...задачка то на самом деле довольно простая, дистанция прыгов определяется максимум за 2 прохода по меткам, и то при условии, что изначально все прыги намеренно длинные.

-----
Чтобы юзер в нэте не делал,его всё равно жалко..





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

Создано: 03 января 2018 22:43
· Личное сообщение · #12

ELF_7719116 пишет:
Да я тоже об этому думал, но как объяснить XEDParse/asmjit, чтобы они автоматом long переходы ставили, а не short?

Пиши просто jxx long addr, если асм нормальный он сделает все длинные как указано, при условии что отключена оптимизация по размеру

-----
Everything is relative...




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

Создано: 04 января 2018 00:00 · Поправил: dosprog
· Личное сообщение · #13

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

..Помнится такое:
даже TASM в режиме USE32 генерировал такой "разбавленный" код - например, <74h,25h,90,90,90,90>.
Если не был дан ключ трансляции "/mX" , где X=2,3.. проходов трансляции.
Это емнип.

ELF_7719116 пишет:
как объяснить XEDParse/asmjit, чтобы они автоматом long переходы ставили, а не short?


Вспомним, как оно было в TINY модели, MASM (.8086) синтаксис -
- Jx переходы всегда генерировались длиной в 2 байта.
- Jmp переходы (ближние) всегда генерировались длиной в три байта (по умолчанию).
Если же нужен был короткий двухбайтовый jmp переход (0EB,{BYTE}), тогда следовало явно написать - <jmp short>.
Но тогда, если метка, после добавления кода между нею и инструкцией <jmp short> на неё, оказывалась дальше 127 (или -128) байт, то выходил затык.


difexacaw пишет:
На чём именно затыка

На том, что просто выдавалась ошибка трансляции
"**Error** - Relative jump out of range".

--Добавлено--
Это при ".8086" (по умолчанию),
если же было указать ".386", тогда никаких ошибок не выдавалось,
и по JZ, например, генерировалось 4 байта <0F,84,xx,xx>
Code:
  1. .386p  ;; Если это убрать, то будет ошибка
  2. SEG_A  SEGMENT USE16
  3.        ASSUME CS:SEG_A, DS:SEG_A
  4.        ORG     100H
  5. START:
  6.         xor ax,ax
  7.         jz @next
  8.  
  9.         or ax,ax
  10.         jnz $+3
  11.         jmp @next
  12.  
  13.         db 200h dup(90h)
  14. @next:
  15.         ret
  16.  
  17. SEG_A   ENDS
  18. END     START
--Конец Добавленного--


В TASM'e этот логический тупик обходили собственной директивой JUMPS.
тогда вместо

Jx @label

- макросредствами автоматически генерировалось:

JNx $+5 ; всегда 2 байта
JMP @label ; всегда 3 байта
; $+5 - это здесь (2+3=5)

Можно попытаться воспользоваться этим решением, концептуально. ( через <DB> ?..)
.. - хотя, это всё лишнее, если имеется в явном виде модификатор <LARGE>. (Или <LONG>, как написал Vamit).






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

Создано: 04 января 2018 00:41
· Личное сообщение · #14

dosprog

На чём именно затыка, на каждом проходе пересчитать ветвления не проблема и в таком простом случае исключаются возможные алгоритмические ошибки, каким бы запутанным не был код :

Code:
  1. L0:
  2.          jmp near ptr $+5
  3.          jb near ptr L4
  4.          jne near ptr L3
  5.          nop
  6. L2:
  7.          jz near ptr L1
  8.          nop
  9. L1:
  10.          jc near ptr L2
  11. L3:
  12.          nop
  13.          jb near ptr L0
  14. L4:
  15.          jmp near ptr L5
  16.          nop
  17. L5:
  18.          Call L0
  19.          Call L2
  20.          Loop L0


-->
Code:
  1. 00020000   72 0B           jb short 0002000D
  2. 00020002   75 06           jne short 0002000A
  3. 00020004    90              nop
  4. 00020005   74 01           je short 00020008
  5. 00020007    90              nop
  6. 00020008   72 FB           jb short 00020005
  7. 0002000A    90              nop
  8. 0002000B   72 F3           jb short 00020000
  9. 0002000D    E8 EEFFFFFF     call 00020000
  10. 00020012    E8 EEFFFFFF     call 00020005
  11. 00020017    9C              pushfd
  12. 00020018    49              dec ecx
  13. 00020019   74 03           je short 0002001E
  14. 0002001B    9D              popfd
  15. 0002001C   EB E2           jmp short 00020000
  16. 0002001E    9D              popfd
  17. 0002001F    C3              ret


7434_04.01.2018_EXELAB.rU.tgz - Build.zip

-----
vx




Ранг: -0.7 (гость), 170thx
Активность: 0.540
Статус: Участник

Создано: 04 января 2018 01:08
· Личное сообщение · #15

ELF_7719116 пишет: Да я тоже об этому думал, но как объяснить XEDParse/asmjit

Первый своей жизнью живет, а у второго long jmp address



Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 04 января 2018 12:26
· Личное сообщение · #16

Archer пишет:
Да и не надо асмам объяснять, тыкай на 1 проходе 6 нопов

Да знаю за нопы, но этож не красиво как-то
Vamit пишет:
Пиши просто jxx long addr

shellstorm пишет:
Первый своей жизнью живет

Они long-large не знают. FAR, NEAR, SHORT. В любом случае, короткий будет если достает по операнду
Короче я пока просто подгоню под свой случай, когда в 90% - будет short-переход. Начиная с draft. А так на будущее может форсированно ставить самому LONG и считать всё за две итерации. Действительно головняка и тактов CPU меньше в разы.
thx всем!



Ранг: 315.1 (мудрец), 631thx
Активность: 0.30.33
Статус: Модератор
CrackLab

Создано: 04 января 2018 15:06
· Личное сообщение · #17

ELF_7719116 посмотри этот https://github.com/herumi/xbyak тут long jmp

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


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

Создано: 04 января 2018 18:23 · Поправил: difexacaw
· Личное сообщение · #18

ELF_7719116

> Действительно головняка и тактов CPU меньше в разы.

Просадка будет и не малая при стандартной структуре графа и повторным проходам по нему. В данный момент для сборки графа я бы использовал супер эффективный механизм - бинарных деревьев, нт экспортит два вида этих алгоритмов, причём высокоэффективных. Маркером(описателем) одной связанной структуры AVL может быть виртуальный адрес. Проход по данному списку невероятно быстрый, элементы списка двусвязаны(в две стороны можно листать). Более эффективные структуры придумать врядле возможно.

-----
vx




Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 04 января 2018 19:15
· Личное сообщение · #19

difexacaw пишет:
Просадка будет и не малая при стандартной структуре графа

эм? В смысле jmp short выполняется быстрее, чем jmp long(far)?


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


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