Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #66, МАЙ 2006 г.

ОБФУСКАЦИЯ И ЕЕ ПРЕОДОЛЕНИЕ

КРИС КАСПЕРСКИ АКА МЫЩЪХ

Спецвыпуск: Хакер, номер #066, стр. 066-008-6


Если писать трассер лень, можно использовать Soft-Ice, просто отключив окно кода командой WC. Тогда результат трассировки командой T будет «вываливать» в нижнее окно, откуда его можно добыть сохранив историю команд в Symbol Loader’е: File> Save Soft-Ice History As.

протокол трассера

001B:00434001 E800000000 CALL 00434006

001B:00434006 5D POP EBP

001B:00434007 50 PUSH EAX

001B:00434008 51 PUSH ECX

001B:00434009 EB0F JMP 0043401A

001B:0043401A F2EBF5 REPNZ JMP 00434012

001B:00434012* EB0F JMP 00434023

001B:00434023 EBE9 JMP 0043400E

001B:0043400E B8EB07B9EB MOV EAX,EBB907EB

001B:00434013* 0F90EB SETO BL

001B:00434016* 08FD OR CH,BH

001B:00434018 EB0B JMP 00434025

001B:00434025 F3EBE4 REPZ JMP 0043400C

001B:0043400C EB0F JMP 0043401D

001B:0043401D EBF6 JMP 00434015

001B:00434015 EB08 JMP 0043401F

001B:0043401F F2EB08 REPNZ JMP 0043402A

001B:0043402A 59 POP ECX

001B:0043402B 58 POP EAX

001B:0043402C 50 PUSH EAX

001B:0043402D 51 PUSH ECX

001B:0043402E EB0F JMP 0043403F

001B:0043403F F2EBF5 REPNZ JMP 00434037

001B:00434037 EB0F JMP 00434048

001B:00434048 EBE9 JMP 00434033

001B:00434033 B8EB07B9EB MOV EAX,EBB907EB

001B:00434038 0F90EB SETO BL

001B:0043403B 08FD OR CH,BH

001B:0043403D EB0B JMP 0043404A

001B:0043404A F3EBE4 REPZ JMP 00434031

001B:00434031 EB0F JMP 00434042

001B:00434042 EBF6 JMP 0043403A

001B:0043403A EB08 JMP 00434044

001B:00434044 F2EB08 REPNZ JMP 0043404F

001B:0043404F 59 POP ECX

001B:00434050 58 POP EAX

Намного нагляднее дизассемблерного листинга. Теперь не нужно прыгать по условным переходам, гадая, какие из них выполняются, а какие нет. К тому же естественным образом исчезает проблема перекрытия машинных команд. Обрати внимание на адреса 434012h, 00434013h и 00434016h — это наши «перекрытые» команды. То, что дизассемблеру удавалось показать с таким трудом, трассер отдает нам задаром! Это реальный поток выполнения программы, в котором много мусора, но, по крайней мере, нет скрытых команд, с которыми приходится сталкиваться в дизассемблере.

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

«вычищено» вручную

001B:00434001 E800000000 CALL 00434006

001B:00434006 5D POP EBP

001B:00434077 33C9 XOR ECX,ECX

001B:004340C3 33C0 XOR EAX,EAX

001B:004340D3 8B0424 MOV EAX,[ESP]

001B:004340DB C60090 MOV BYTE PTR [EAX],90

001B:00434105 83ED06 SUB EBP,06

[основную проблему] создают циклы. Трассер разворачивает их в длинный многокилометровый, многократно повторяющийся код. Запаришься пролистывать его. Так что не обойтись без фильтра, распознающего и «сворачивающего» повторяющие конструкции.

Хорошая идея — пропустить протокол трассера через оптимизирующий компилятор, использующий системы графов для устранения лишних операций присвоения (пропускать именно протокол трассера, а не дизассемблерный листинг, поскольку последний неверен, неполон и вообще никуда не годится). Конечно же, он не сможет распознать математические преобразования в стиле sin(x)2+cos(x)2, но выбросит значительную часть «инструкций с нулевым эффектом», а тебе не придется реализовывать систему графов и писать то, что было написано задолго до нас.

Назад на стр. 066-008-5  Содержание  Вперед на стр. 066-008-7