демонстрация техники "перекрытия" машинных команд, используемой обфускаторами
Обратите внимание на команду "043401Dh:jmp short loc_434013+2" (выделена полужирным), прыгающую по адресу 434013h+2h == 434015h, то есть в середину инструкции 434013h:seto bl (так же выделена полужирным). Именно, что в середину! С точки зрения дизассемблера (даже такого продвинутого как IDA Pro), команда является "атомарной" структурной единицей, то есть неделимой. На самом же деле, всякая машинная инструкция состоит из последовательности байт и может быть выполнена с любого места! Во всяком случае x86 процессоры не требуют выравнивания кода. Другими словами, у нас нет "команд" у нас есть только байты! Если начать выполнение инструкции не с первого байта мы получим совсем другую команду! К сожалению, IDA Pro не позволяет узнать какую. Чтобы выполнить переход "043401Dh:jmp short loc_434013+2" мы должны подвести курсор к метке loc_434013 и нажать <U>
, чтобы "раскрошить" дизассемблерный код на байты, а после перейти по адресу 434015h и нажать <C>
, чтобы превратить байты в дизассемблерный код, в результате чего получится следующее:
.adata:0043400E unk_43400E db 0B8h ; ¬ ; CODE XREF: .adata:loc_434023j
.adata:0043400F db 0EBh ; ы
.adata:00434010 db 7
.adata:00434011 db 0B9h ; ¦
.adata:00434012 loc_434012: ; CODE XREF: .adata:loc_43401Aj
.adata:00434012 jmp short loc_434023
.adata:00434014
.adata:00434014 nop
.adata:00434015
.adata:00434015 loc_434015: ; CODE XREF: .adata:loc_43401Dj
.adata:00434015 jmp short loc_43401F ; ß прыжок сюда
.adata:00434017
.adata:00434017 std
.adata:00434018 jmp short loc_434025
.adata:0043401A
.adata:0043401A loc_43401A: ; CODE XREF: .adata:00434009j
.adata:0043401A repne jmp short loc_434012