Пишу свой декомпилятор, как быть с функциями к которым у меня нет заголовков?

Тема в разделе "WASM.RESEARCH", создана пользователем Shooshpanchik, 24 июн 2026 в 10:42.

  1. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    128
    Это пока, дальше будет больше. Когда начну разбирать тестовые файлы, тогда будет круче. А пока хватает разбора функций, хотел их параметры сразу в вызов пихать и именовать по нормальному, но пока не вышло. Тогда пока строго поддерживаю обратную компиляцию.
     
  2. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    2.226
    Если ты изначально не выбрал стратегию транслировать машинный код в промежуточный упрощенный псевдокод, который в последствии будешь оптимизировать, вычищать мусорные операции и уже тогда транслировать в высокоуровневый псевдокод, как все декомпиляторы обычно и делаются, то дальше ты утонешь просто. У меня как бы по поводу этого есть сомнения, когда смотрю на выхлопы.
     
    Ahimov нравится это.
  3. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    513
    Что-то никогда не интересовался темой разработки декомпилятора, но стало интересно. Хотел спросить у тех кто в теме: а, вообще, реально разработать/запрограммировать декомпилятор, который хоть немного будет превосходить Хексрей ? Говорят, что такое желание и стремление к этому - что-то из области фантастики. Ильфак уже, вроде как, сделал всё возможное и невозможное на этом поприще...
     
  4. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    687
    f13nd,

    А причем декомпиль ?

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

    Минимальная операция декомпиляции(общей) это выделение условной конструкции(обнаружить схождение условий).
     
  5. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    128
    Не, ну почему же, это просто нелинейный код на скриншоты не попал. Там правильно разбираются условные переходы и создаются метки. Для jmp метка создается, но после этой инструкции код не разбирается. Как и для всех видов ret,
    И вот еще для этих функции:

    if not ((Name='ExitProcess') or
    (Name='TerminateProcess') or
    (Name='ExitThread') or
    (Name='TerminateThread') or
    (Name='RtlExitUserProcess') or
    (Name='NtTerminateProcess') or
    (Name='exit') or
    (Name='_exit') or
    (Name='abort'))
    then Tasks.Add(Pointer(Uint64(Tasks.First)+Instr2.size));

    Все вызовы функций обрабатываются и добавляются в общий список.

    Вот счас сам вижу что адреса для меток у меня не правильные, вот это и буду сейчас фиксить.
    Decomp6.jpg
     
  6. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    2.226
    Декомпилятором обычно называют дурундуль, которая в высокоуровневом псевдокоде представляет машинный код. На скриншотах скорей дизассемблер, чем декомпилятор. Если ты делаешь ставку на возможность реассемблирования, советую ввести префиксы (или суффиксы), описывающие формат конкретной инструкции, чтобы по ним можно было один в один реассемблировать. Это единственный надежный способ контроля.
     
  7. _edge

    _edge Well-Known Member

    Публикаций:
    1
    Регистрация:
    29 окт 2004
    Сообщения:
    655
    Адрес:
    Russia
    На https://dogbolt.org/ есть попытки декомпиляции. Выглядят достаточно уныло. Это чтобы сложность оценить.
     
  8. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    128
    Для моего тестового бинарника только angr нашел строки.
    Зато все правильно отработали ExitProcess. Все вставляют приведение типов. У них есть чему поучится. Странно но на моем Ростелекоме этот сайт без VPN не открывается :dntknw: РТ вообще зверствует Total Comander без VPN ито не скачать.


    upload_2026-6-25_6-33-55.png
    --- Сообщение объединено, 25 июн 2026 в 06:00 ---
    Angr определяет параметры для функций, и даже определяет их тип и восстанавливает структуры. Вот это вот очень хорошо. Когда разберусь с функциями, можно будет делить код на блоки и декомпилировать внутри этих блоков, сворачивая дизасм инструкции в С-- код. Я декомпилил когда-то в Ida, надо рекурсивно разбирать код снизу вверх.
    decompile7.jpg decomp8.jpg
     
  9. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    687
    - для диза с произвольного адреса нужен обратный дизасм.

    - для каждой произвольной(не в cfg) инструкции необходима проверка на валидность + эвристика. Более точная проверка делается через наследование(далее).

    - базовая функция обрабртки диза это наследование(taint analysis) и необходимо для определения схождений(условий), что тащит довольно сложную матчасть.

    - определение строк это эвристика, тут тема не сохранилась. В любом случае необходимо наследование, чтобы узнать что происходит со ссылкой: push p... msgbox(p) => p: P.
    T = taint(p); mm_fetch(T) => p: P и тд.

    - анализ case-ветвлений требует всего описанного выше.

    В текущем виде это примитивный парсер графа(дизасм): простейший обход ветвей(через ксед?)
     
    Последнее редактирование: 25 июн 2026 в 08:41
  10. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    128
    Через WorkList.

    Вобщем качнул тестовых файлов, Счас пойдет жара.
     
  11. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    687
    Shooshpanchik,

    Для начала дизу нужны входы(EP). Так как эвристики нет(код от данных, тоесть тип ссылки) то откуда начинается проход, с общей EP ?

    Если попытаться парсить экспорт будут крэши - в нем есть ссылки на строки, а не только на код. Короче так просто нельзя обеспечить покрытие. Валиться будет на всем: call reg/data; int3/data; return()/data etc.