Секреты ассемблирования дизассемблерных листингов

         

Обычно дизассемблер используется для реконструкции


Обычно дизассемблер используется для реконструкции алгоритма подопытной программы, который после этого переписывается на Си/Си++ или в двоичном файле правится тот нехороший jx, который не дает приложению работать, если не найден ключевой файл или демонстрационный период давно истек.
Значительно реже дизассемблированную программу требуется оттранслировать заново. Например, хочется исправить множественные ошибки разработчиков, нарастить функционал или внести другие изменения… Конечно, все это можно сделать непосредственно в двоичном коде, наложив на программу "заплатку", присобаченную с помощью jump'ов. В большинстве случаев это самый короткий и самый _надежный_ пусть. Нет никаких гарантий, что программа дизассемблирована правильно. Существует по меньшей мере три фундаментальные проблемы дизассемблирования: а) синтаксическая неразличимость смещений от констант; б) неоднозначность соответствия ассемблерных мнемоник машинным командам; в) код ошибочно принятый за данные и данные, ошибочно принятые за код.
Как следствие, откомпилированный дизассемблерный листинг в лучшем случае вообще не работает, зависая при запуске, в худшем же — периодически падать в разных местах. Но до этих проблем нам — как до Луны, а, может, еще и дальше. Для начала необходимо протащить дизассемблерный листинг сквозь ассемблер, устранив явные ошибки трансляции, а со всем остальным мы разберемся как ни будь потом (быть может, даже в следующей статье).

Содержание раздела