Анимация
JavaScript
|
Главная Библионтека seg000:0110 loop loc 0 10C Сам же зашифрованный фрагмент начинается с адреса seg000:0x116 и продолжается вплоть до seg000:0x12E. Отсюда - цикл расшифровки на языке Си выглядит так: for (a=0x116;a<0x12E;a++) PatchByte([0x1000,a],Byte([0x1000,a])0x66); В зависимости от версии IDA для выполнения скрипта необходимо нажать либо <Enter> (версия 3.8x и старше), либо <Ctrl-Enter> в более ранних версиях. Если все сделано правильно, после выполнения скрипта экран дизассемблера должен выглядеть так (b). Возможные ошибки - несоблюдение регистра символов (IDA к этому чувствительна), синтаксические ошибки, базовый адрес вашего сегмента отличается от 0x1000 (еще раз вызовете окно «Сегменты» чтобы узнать его значение). В противном случае необходимо подвести курсор к строке "seg000:0116", нажать клавишу <U> для удаления результатов предыдущего дизассемблирования зашифрованного фрагмента и затем клавишу <C> для повторного дизассемблирования расшифрованного кода.
b) результат работы скрипта расшифровщика Цепочку символов, расположенную начиная с адреса "seg000:011E" можно преобразовать в удобочитаемый вид, подведя к ней курсор и нажав клавишу "<A>". Теперь экран дизассемблера будет выглядеть так: seg000:0116 loc 0 116: seg000:0116 seg000:0118 seg000:011B seg000:011B seg000:011D s000:011D ; - s000:011E aloSall s000:012E ; - с) создание ASCII-строки mov mov int retn ah, 9 dx, 108h 21h ; CODE XREF: seg000:013Bu DOS - PRINT STRING DS:DX -> string terminated by "$" lo,Sail,0Dh,0?ih,$ Команда "MOV AH,9" в строке :0116 подготавливает регистр AH перед вызовом прерывания 0x21, выбирая функцию вывода строки на экран, смещение которой заносится следующей командой в регистр DX. Т.е. для успешного ассемблирования листинга необходимо заменить константу 0x108 соответствующим смещением. Но ведь выводимая строка на этапе ассемблирования (до перемещения кода) расположена совсем в другом месте! Одно из возможных решений этой проблемы заключается в создании нового сегмента с последующим копированием в него расшифрованного кода - в результате чего достигается эмуляции перемещения кода работающей программы. Для создания нового сегмента можно выбрать в меню «View» пункт «Segments» и в раскрывшемся окне нажать клавишу <Insert>. Появится диалог следующего вида (см. рис. 10): Create a new segment Start address and end address should be valid. End address > Start address Segment name Start address End address Base Class MySeg 0x20100 0x20125 0x2000 [ ] 32-bit segment OK Cancel C-notation: hex is 0x... in paragraphs (class is any text) F1 - Help Рисунок 10 IDAC: Создание нового сегмента Подробнее о значении каждого из полей рассказано в главе «Сегменты и селекторы», а здесь не рассматривается. Пояснение: Базовый адрес сегмента может быть любым если при этом не происходит перекрытия сегментов seg000 и MySeg; начальный адрес сегмента задается так, чтобы смещение первого байта было равно 0x100; разница между конечным и начальным адресом равна длине сегмента, вычислить которую можно вычитанием смещения начала расшифрованного фрагмента от смещения его конца - 0x13B - 0x116 = 0x25. Скопировать требуемый фрагмент в только что созданный сегмент можно скриптом следующего содержания. auto a; for (a=0x0;a<0x25;a++) PatchByte([0x2000,a+0x100],Byte([0x1000,a+0x116] a) исходный текст скрипта - копировщика Для его ввода необходимо вновь нажать <Shift-F2>, при этом предыдущий скрипт будет утерян (IDA позволяет работать не более чем с один скриптом одновременно). После завершения его работы экран дизассемблера будет выглядеть так: MySeg:0100 MySeg MySeg:0100 MySeg:0100 MySeg:0100 MySeg:0100 MySeg:0101 MySeg:0102 MySeg:0103 MySeg:0104 MySeg:0105 MySeg:0106 MySeg:0107 MySeg:0108 MySeg:0109 segment assume ;org 10 assume db 0B4h db 9 0BAh bye public use16 s:MySeg s:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing 0CDh db 21h db 0C3h db 48h db 65h MySeg:010A MySeg:010B MySeg:010C MySeg:010D MySeg:010E MySeg:010F MySeg:0110 MySeg:0111 MySeg:0112 MySeg: MySeg: MySeg: MySeg: MySeg: 0113 0114 0115 0116 0117 db db db db db db db db db db db db db db ends 6Ch 6Ch 6Fh 2Ch 53h 61h 69h 6Ch 6Fh 72h 21h 0Dh 0Ah 24h MySeg:0117 MySeg b) результат работы скрипта-копировщика Теперь необходимо создать перекрестную ссылку "from:seg000:013B; to:MySeg:0x100", преобразовать цепочку символов в удобочитаемую строку, подведя курсор к строке MySeg:0108 и нажав клавишу <A>. Экран дизассемблера должен выглядеть так: MySeg:0100 loc: 1000 100: MySeg:0100 MySeg:0102 MySeg:0105 MySeg:0105 MySeg:0107 MySeg:0107 ; - MySeg:0108 aHelloSailorS MySeg:0108 mov mov int retn ah, 9 dx, 108h ; CODE XREF: seg000:013Bu DOS - PRINT STRING EB:EX -> string terminated by "$" db Hello,Sailor!,0Dh,0Ah db $ ends MySeg:0118 MySeg с) результат дизассемблирования скопированного фрагмента Результатом всех этих операций стало совпадение смещения строки со значением, загружаемым в регистр DX (в тексте они выделены жирным шрифтом). Если подвести курсор к константе "108h" и нажать клавишу <Ctrl-O> она будет преобразована в смещение: dx, fs aHelloSailorS MySeg:0102 MySeg:0105 MySeg:0105 MySeg:0107 MySeg:0107 ; - MySeg:0108 aHelloSailorS db Hello,Sailor!,0Dh,0Ah d) преобразование константы в смещение "Hello,Sailor!\r\n$ш" DOS - PRINT STRING DS:DX -> string terminated by "$" retn DATA XREF: MySeg:0102o Полученный листинг удобен для анализа, но все еще не готов к ассемблированию, хотя бы уже потому, что никакой ассемблер не в состоянии зашифровать требуемый код. Конечно, эту операцию можно выполнить вручную, после компиляции, но IDA позволит проделать то же самое не выходя из нее и не прибегая к помощи стороннего инструментария. Демонстрация получится намного нагляднее, если в исследуемый файл внести некоторые изменения, например, добавить ожидание клавиши на выходе. Для этого можно прибегнуть к интегрированному в IDA ассемблеру, но прежде, разумеется, необходимо несколько «раздвинуть» границы сегмента MySeg, дабы было к чему дописывать новый код. Выберете в меню "View" пункт "Segments" и в открывшемся окне подведите курсор к стоке "MySeg". Нажатие <Ctrl-E> открывает диалог свойств сегмента, содержащий среди прочих полей конечный адрес, который и требуется изменить. Не обязательно указывать точное значение - можно «растянуть» сегмент с небольшим запасом от предполагаемых изменений. Если попытаться добавить к программе код "XOR AX,AX; INT 16h" он неминуемо 0 1 2 3 4 [ 5 ] 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |