Анимация
JavaScript
|
Главная Библионтека 7E5B:010F 46 inc 7E5B:0110 E2 FA 7E5B:0112 FF E6 7E5B:114 18 00 sbb 7E5B:116 D2 6F DC 7E5B:119 6E 67 AB 47 A5 2E 7E5B:11F 03 0A 0A 09 4A 35 7E5B:125 07 0F 0A 09 14 47 7E5B:12B 6B 6C 42 E8 00 00 7E5B:131 59 5E BF 00 01 57 7E5B:137 2B CE F3 A4 C3 loop [bx+si shr db 6Eh db 03h db 07h db 6Bh db 5 9h db 2Bh ],al byte , 67h, , 0Ah, , 0Fh, , 6Ch, , 5Eh, , CEh, ; Loop if cx > 0 ptr [bx-24h],cl ; 0ABh, 47h,0A5h, 2Eh 0Ah, 09h, 4Ah, 35h 0Ah, 09h, 14h, 47h 42h, E8h, 00h, 00h BFh, 00h, 01h, 57h F3h, A4h, C3h No entry point to code Shift w/zeros fill Crypt endp SOURCER половину кода вообще не смог дизассемблировать, оставив ее в виде дампа, а другую половину дизассемблировал неправильно! Команда "JMP SI" в строке :0x103 осуществляет переход по адресу :0x106 (значение регистра SI после загрузки com файла равно 0x100, поэтому после команды "ADD SI,6" регистр SI равен 0x106). Но следующая за "JMP" команда расположена по адресу 0x105! В исходном тексте в это место вставлен байт-пустышка, сбивающий дизассемблер с толку. Start: SI,6 0B9h SI, end ; На начало зашифрованного фрагмента SOURCER не обладает способностью предсказывать регистровые переходы и, встретив команду "JMP SI" продолжает дизассемблирование, молчаливо предполагая, что команды последовательно расположены вплотную друг к другу. Существует возможность создать файл определений, указывающий, что по адресу:0x105 расположен байт данных, но подобное взаимодействие с пользователем очень неудобно. Напротив, IDA изначально проектировалась как дружественная к пользователю интерактивная среда. В отличие от SURCER-подобных дизассемблеров, IDA не делает никаких молчаливых предположений, и при возникновении затруднений обращается за помощью к человеку. Поэтому, встретив регистровый переход по неизвестному адресу, она прекращает дальнейший анализ, и результат анализа файла "Crypt.com" выглядит так: seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 100 start 100 103 0103 start 0103 0103 ; ----0105 106 107 108 109 010A proc near add si jmp si endp
Необходимо помочь дизассемблеру, указав адрес перехода. Начинающие пользователи в этой ситуации обычно подводят курсор к соответствующей строке и нажимают клавишу <C>, заставляя IDA дизассемблировать код с текущей позиции до конца функции. Несмотря на кажущуюся очевидность, такое решение ошибочно, ибо по-прежнему остается неизвестным куда указывает условный переход в строке :0x103 и откуда код, расположенный по адресу :0x106 получает управление. Правильное решение - добавить перекрестную ссылку, связывающую строку :0x103, со строкой :0x106. Для этого необходимо в меню "View" выбрать пункт "Cross references" и в появившемся окне диалога заполнить поля "from" и "to" значениями seg000:0103 и seg000:0106 соответственно. После этого экран дизассемблера должен выглядеть следующим образом (в IDA версии 4.01.300 содержится ошибка, и добавление новой перекрестной ссылки не всегда приводит к автоматическому дизассемблированию):
Поскольку IDA Pro не отображает адреса-приемника перекрестной ссылки, то рекомендуется выполнить это самостоятельно. Такой примем улучшит наглядность текста и упростит навигацию. Если повести курсор к строке :0x103 нажать клавишу <:>, введя в появившемся диалоговом окне любой осмысленный комментарий (например "переход по адресу 0106"), то экран примет следующий вид: seg000:0103 ; Переход по адресу 0106 Ценность такого приема заключается в возможности быстрого перехода по адресу, на который ссылается "JMP SI", - достаточно лишь подвести курсор к числу "0106" и нажать <Enter>. Важно соблюдать правильность написания - IDA Pro не распознает шестнадцатеричный формат ни в стиле Си (0x106), ни в стиле MASM\TASM (0106h). Что представляет собой число "114h" в строке :0x106 - константу или смещение? Чтобы узнать это, необходимо проанализировать следующую команду - "LODSW, поскольку ее выполнение приводит к загрузке в регистр AX слова, расположенного по адресу DS:SI, очевидно, в регистр SI заносится смещение. seg000:0106 seg000:0109 mov si, 114h lodsw Однократное нажатие клавиши <O> преобразует константу в смещение и дизассемблируемый текст станет выглядеть так: seg000:0106 mov seg000:0109 lodsw seg000:0114 unk 0 114 db 18h seg000:0115 db 0 seg000:0116 db 0D2h seg000:0117 db 6Fh si, offset unk 0 114 ; DATA XREF: seg000:0106to IDA Pro автоматически создала новое имя "unk 0 114", ссылающееся на переменную неопределенного типа размером в байт, но команда "LODSW" загружает в регистр AX слово, поэтому необходимо перейти к строке :0144 и дважды нажать <D> пока экран не станет выглядеть так: eg000:0114 word 0 114 eg000:0116 dw 18h db 0D2h ; T ; DATA XREF: seg000:0106to Но что именно содержится в ячейке "word 0 144"? Понять это позволит изучение следующего кода: seg000:0106 seg000:0109 seg000:010A seg000:010B seg000:010C seg000:010C loc 0 10C: seg000:010C seg000:010F seg000:0110 lodsw xchg push xor inc loop si, offset word 0 114 ax, cx ; CODE XREF: seg000:0110j byte ptr [si], 66h si loc 0 10C В строке :0x10A значение регистра AX помещается в регистр CX, и затем он используется командой "LOOP LOC 010C" как счетчик цикла. Тело цикла представляет собой простейший расшифровщик - команда "XOR" расшифровывает один байт, на который указывает регистр SI, а команда "INC SI" перемещает указатель на следующий байт. Следовательно, в ячейке "word 0 144" содержится количество байт, которые необходимо расшифровать. Подведя к ней курсор, нажатием клавиши <N> можно дать ей осмысленное имя, например "BytesToDecrypt". После завершения цикла расшифровщика встречается еще один безусловный регистровый переход. seg000:0112 Чтобы узнать куда именно он передает управление, необходимо проанализировать код и определить содержимое регистра SI. Часто для этой цели прибегают к помощи отладчика - устанавливают точку останова в строке 0x112 и дождавшись его «всплытия» просматривают значения регистров. Специально для этой цели, IDA Pro поддерживает генерацию map-файлов, содержащих символьную информацию для отладчика. В частности, чтобы не заучивать численные значения всех «подопытных» адресов, каждому из них можно присвоить легко запоминаемое символьное имя. Например, если подвести курсор к строке "seg000:0112", нажать <N> и ввести "BreakHere", отладчик сможет автоматически вычислить обратный адрес по его имени. Для создания map-файла в меню "File" необходимо кликнуть по «Produce output file» и в развернувшемся подменю выбрать «Produce MAP file» или вместо всего этого нажать на клавиатуре «горячую» комбинацию «Shift-F10». Независимо от способа вызова на экран должно появится диалоговое окно следующего вида. Оно позволяет выбрать какого рода данные будут включены в map-файл - информация о сегментах, имена автоматически сгенерированные IDA Pro (такие как, например, "loc 0 106", "sub 0x110" и т.д.) и «размангленные» (т.е. приведенные в читабельный вид) имена. Подробнее о сегментах рассказывается в главе «Сегменты и селекторы», об авто генерируемых и замангленных именах - в главе «Настойки IDA Pro". Содержимое полученного map-файла должно быть следующим: Start Stop Length Name 00100H 0013BH 0003CH seg000 Address Publics by Value Class CODE 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 |