Анимация
JavaScript


Главная  Библионтека 

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

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> для повторного дизассемблирования расшифрованного кода.

seg000:

0116 loc 0 116:

; CODE XREF: seg000:013Bu

seg000:

0116

ah, 9

seg000:

0118

dx, 108h

seg000:

011B

; DOS - PRINT STRING

seg000:

011B

; DS:DX -> string terminated by "$"

seg000:

011D

retn

seg000:

seg000:

011E

seg000:

011F

seg000:

0120

seg000:

0121

seg000:

0122

seg000:

0123

; ,

seg000:

0124

seg000:

0125

seg000:

0126

seg000:

0127

seg000:

0128

seg000:

0129

seg000:

012A

; !

seg000:

012B

seg000:012C

seg000:012D

seg000:012E ; -

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