Обратная инженерия Антон Hex Кукоба (xtin@ua.fm) Спецвыпуск: Хакер, номер #057, стр. 057-012-5 При анализе кода помни, что программисты - тоже люди, они тоже пытаются писать красивый и понятный код. И если где-то выделяется память, это значит, что где-то она очищается. Если создается объект, значит, он где-то используется и где-то уничтожается. Используя информацию о жизненном цикле, можно сначала отследить и отреверсить какой-то один несложный объект/структуру, а далее, основываясь на этом объекте, реверсить более сложные объекты, которые взаимодействуют с ним. Это намного эффективнее, чем охватывать все целиком. Анализ любой функции тоже производится с учетом известных данных. Если в функции есть вызовы API, нужно поименовать все переменные и аргументы, исходя из прототипов функций. Старайся подписывать все, что только можешь: регистры, переменные, функции, точки переходов, пиши комментарии. Обязательно находи и именуй циклы: переменную-счетчик, точку возврата и точку выхода. Я обычно даю имена @Loop, @Break, @Continue. Очень сильно помогает именование точек переходов - мест, куда совершается переход при ошибке и при нормальном выполнении кода. Я называю их @Ok и @Error. Если в коде есть вызовы виртуальных функций (регистровые вызовы), обязательно проверь стек - IDA не умеет анализировать его после вызова виртуальной функции. Что делать дальше Когда уровни выделены и есть представление о классах и нужных API, уже можно извлекать код из программы и пытаться использовать его. Есть два подхода: декомпиляция вручную и переассемблирование ассемблерного листинга. Первый способ более трудоемкий, но при его использовании ты чист перед законом, поскольку не используешь чужой код, а пишешь свой. Второй способ дает очень быстрый результат. Ты сразу получаешь obj, который и линкуешь к программе. Этот кусок кода в твоей программе будет совпадать с оригиналом байт в байт, и для гневного заявления "Это плагиат!" будет много оснований :(. Мнение эксперта Крис Касперски aka мыщъх: В дизассемблировании намного больше искусства, чем науки. Хотя машинный анализ делает огромные успехи (достаточно взглянуть на последние версии IDA Pro), сердцем любого декомпилятора по-прежнему является человек. Отличие констант от смещений до сих пор остается фундаментальной проблемой дизассемблирования (так называемая "проблема offset'а"). В двоичном виде их представление идентично, но интерпретируются они по-разному. Нераспознанные смещения в свою очередь не позволяют отличать данные от команд, и это вторая фундаментальная проблема дизассемблирования. Наконец, дизассемблеры не справляются (точнее, практически не справляются) с анализом виртуальных функций, зашифрованного и самомодифицирующегося кода, поэтому приходится запрягать дизассемблер и отладчик в одну связку - дизассемблер реконструирует скелет алгоритма, а отладчик расшифровывает запакованные фрагменты кода и уточняет значение регистров ЦП и ячеек памяти в данной точке. |