Анимация
JavaScript
|
Главная Библионтека dseg:000B dseg:000D dseg:000E dseg:0010 dseg:0010 dseg:0013 dseg:0016 dseg:0018 dseg:0018 mov inc mov ax, ds ds, ax assume ds:nothing dx, 2Fh ; WriteLn ah, 4Ch start call mov int endp dseg:0020 aHelloSailor dseg:002F dseg:003F aHelloIda dseg:003F dseg dseg:003F dseg:003F dseg:003F db Hello,Sailor,0Dh,0Ah,$ db $$$$$$$$$$$$$$$$ db Hello,IDA!,0Dh,0Ah,$ ends end start Смещение 0x2F в строке dseg:0x10 на самом деле указывает на строку dseg:0x3F, т. к. перед этим значение DS было увеличено на единицу (один параграф равен шестнадцати байтам) Как «объяснить» это дизассемблеру? Переведем курсор на строку dseg:0x10 и используем следующую команду: SetReg (SreenEA (),"DS", 0x1001); Теперь если преобразовать операнд в смещение получиться следующее: dseg:0010 loc 0 10: ; DATA XREF: start+10o dseg:0010 mov dx, offset aHellolda - offset loc 0 10 ; "Hello,IDA!\r\n$" Заметим по комментарию, что теперь IDA правильно определила ссылку. Однако, сгенерировала неверный код. «offset aHelloida - offset loc 0 10» будет работать только до тех пор, пока метка loc o 10 будет расположена по смещению 0x10, и нам необходимо заменить ее константой 0x10. Для этого воспользуется, например, функций OpAlt. SetReg изменяет значение сегментного регистра в каждой точке до следующего ASSUME или конца сегмента.
Функция SetReg эквивалентна команде меню «~EDIT\Segments\Change segment register value». long GetReg (long ea,char reg); Возвращает значение сегментных регистров в произвольной точке программы. Подробнее об этом можно прочитать в описании функции SetReg.
Функция возвращает 16-битное целое, содержащие значение сегментного регистра в параграфах. В 32-битных программах функция обычно возвращает не непосредственное значение, а селектор. Для получения искомого адреса необходимо воспользоваться функцией AskSelector. Поскольку селекторы «визуально» неотличимы от адресов сегментов, то для уверенности необходимо вызывать AskSelector всякий раз для проверки на принадлежность возвращаемого значения к селекторам. Если селектор с указанным номером не существует, то это непосредственное значение. Если регистр не существует (например "MS") или не определен, то функция и в том и другом случае вернет ошибку 0xFFFF, а не BADADDR, как утверждает прилагаемая к IDA документация. Пример использования: seg000:0000 seg000 seg000:0000 segment byte public assume cs:seg000 CODE use16 Message ("%x \n", GetReg (0x10000,"CS") 1000 .text:00401000 text .text:00401000 segment para public CODE use32 assume cs: text Message ("%x \n", GetReg (ScreenEA (),"CS") Message ("%x \n", AskSelector (1) ПЕРЕКРЕСТНЫЕ ССЫЛКИ ЧТО ТАКОЕ ПЕРЕКРЕСТНЫЕ ССЫЛКИ? Долгое время SOURCER лидировал среди других дизассемблеров в умении находить и восстанавливать перекрестные ссылки. На этом, правда, его основные достоинства и оканчивались, но все равно он активно использовался для исследования программного обеспечения. Что же такое перекрестные ссылки и почему они так важны для популярности дизассемблера? Покажем это на следующем примере. Рассмотрим простейший случай. Допустим, исходный файл выглядел так: .MODEL TINY .CODE ORG 100h Start: MOV AH,9 LEA DX,s0 INT 21h s0 DB "Hello, Sailor!",0Dh,0Ah,$ END Start После ассемблирования он будет выглядеть следующим образом: seg000:0100 start proc near seg000:0100 mov ah, 9 seg000:0102 mov dx, offset aHelloSailor ; "Hello, Sailor!\r\n$" seg000:0105 int 21h seg000:0105 seg000:0107 retn seg000:0107 start endp seg000:0107 seg000:0107 ; --------------------------------------------------- seg000:0108 aHelloSailor db Hello, Sailor!,0Dh,0Ah,$ seg000:0108 seg000 ends Допустим, мы хотим узнать, какой код выводит эту строку на экран. Когда-то для этого приходилось кропотливо изучать весь листинг, и то не было шансов, что с первого раза выводящий строку код удастся рассмотреть. Поэтому, эту задачу возложили на плечи дизассемблера. Так, что бы машина сама анализировала выполнение программы и восстанавливала все связи. Это невероятно упростило анализ программ, как впрочем, и взлом защит. Стало достаточно только найти в строку, которая защита выводит в случае неудачного завершения проверки (ключевой дискеты ли, или пароля - совершенно не важно), как дизассемблер поможет мгновенно найти, вводящий ее код, а значит, и локализовать защиту каким бы длинной программа не оказалась. Как правило, где-то неподалеку расположен условный переход, передающий управление этой ветви. Стоит только изменить его на противоположный, как защиту можно считать взломанной. Но ведь же не для хакерства же были придуманы перекрестные ссылки! Разумеется, нет! Помощь хакерам это только побочный эффект (хотя и очень приятный для них). Значительно важнее поддержка перекрестных ссылок чтобы правильно дизассемблировать код! Покажем это на следующем примере: 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 |