Анимация
JavaScript
|
Главная Библионтека <ida.cfg>, а размер страницы значением поля NPAGESSIZE. По умолчанию IDA резервирует 64 страницы, объемом 1024 байт (1 КБ). Каждый указатель занимает 4 байта страничной памяти, следовательно, 64-кб буфер вмещает свыше 16 тысяч имен. Следует отметить, при дизассемблировании программ, написанных на Delphi, IDA генерирует огромное количество имен и увеличение значение поля NPAGES может существенно улучшить производительность. При загрузке файла в окне сообщений выдается отчет о выделении страничной памяти под нужды IDA: окно виртуальной памяти (allocating memory for virtual array), буфер двоичного дерева ("allocating memory for b-tree") и буфер указателей на имена (""allocating memory for name pointers"). Например, выделение памяти при загрузке файла "first.exe" в IDA 3.84 происходит следующим образом: bytes pages size description 262144 32 8192 allocating memory for b-tree... 65536 16 4096 allocating memory for virtual array... 65536 64 1024 allocating memory for name pointers... Рисунок 15 "Отчет о выделении памяти при загрузке IDA" Взаимодействие с физической памятью Взаимодействие с физической памятью становится возможным благодаря наличию четырех недокументированных функций peek, poke, lpoke и call, прототипы которых приведены ниже: • long poke(long ea, long value) • long lpoke(long ea, long value) • long peek(long ea, long value) • long call(long ea) Функции poke и lpoke записывают байт и длинное целое value по линейному адресу ea физической памяти соответственно, возвращая прежнее значение ячейки. Функция peek читает байт по линейному адресу ea физической памяти, а функция call передает управление на машинный код, расположенный по линейному адресу ea физической памяти. Следует отметить, указанные функции по-разному функционируют в различных версиях IDA и результат их выполнения может быть непредсказуем, поэтому, их использование не рекомендуется. Пример, приведенный ниже, демонстрирует копирование содержимое ПЗУ компьютера в виртуальную память дизассемблера, с последующим анализом обработчика прерывания INT 0x13. Ввиду различной реализации функций низкоуровневой работы с памятью, его успешная работа гарантируется лишь при запуске из MS-DOS-версии IDA Pro. Операционная система Windows 9x эмулирует наличие ПЗУ и позволяет функции peek обращаться к нему даже из 32-разрядных версий IDA Pro. auto a; SegCreate(0xF0000,0xFFFFF,0x0F000,0,0,0); Message("Ждите... читаю BIOS..."); for (a=0;a<0xFFFF;a++) PatchByte(0xF0000+a, peek(0xF0000+a)); Message("CK \n Дизассемблирую обработчик Int 0x13"); MakeCode(0xFEC59); Message("OK \n"); Jump(0xFEC59); По окончании работы скрипта экран дизассемблера должен выглядеть так: seg001: seg001: seg001: seg001: seg001: seg001: seg001: seg001: seg001 seg001 seg001 seg001 seg001 seg001 EC59 EC59 EC59 EC5C EC5C EC5E EC61 EC63 EC63 EC66 EC66 EC66 EC69 EC6B loc E000 EC59: ; CCDE XREF: seg001:01881J ; seg001:019BtJ loc E000 EE3B mov al, 0C0h ; L call sl E000 EC8E jmp short loc E000 EC66 call loc E000 EC8A loc E000 EC66: ; CODE XRE: seg001:EC61tj call sl E000 EC6C cmp al, ah retn Навигатор по функциям Начать изучение виртуальной памяти лучше всего с загрузки двоичного (бинарного) файла. Сначала необходимо создать сам файл - это можно сделать командной "echo Hello, IDA Pro! > tutor.bin". [] Load Binary or User-Defined Format file File name: F:\IDAN\SRC\1\tutor.bin (•) Binary file Loading segment 0x1000 Loading offset 0x666 Processor: metapc [ ] Create segments OK Cancel i (in paragraphs) F1 - Help Рисунок 16 Диалог загрузки бинарного файла Дождавшись появления диалога загрузки консольной версии IDA Pro, запомните базовый адрес сегмента, записанный в поле "Loading segment... (in paragraphs)", измените адрес загрузки на любой отличный от нуля (нулевое смещение крайне ненаглядно для иллюстрации), скажем, на 0x666, и сбросьте флажок "Create segment - для предотвращения автоматического создания сегмента (работа с сегментами будет рассмотрена позже, в главе «Сегменты и селекторы»). Замечание: доступные автору графические версии IDA Pro содержат ошибку реализации, всегда создавая новый сегмент при загрузке файла, независимо от установленных настроек. После окончания загрузки файла экран дизассемблера должен выглядеть следующим образом:
Слева каждой строки указывается ее линейный адрес, причем адрес первого байта равен 0x1000*0x10+0x666, т.е. сумме базового адреса, указанного при загрузке, умноженного на шестнадцать и адреса смещения. Чтение ячеек виртуальной памяти осуществляется функциями - Byte(long ea), Word(long ea) и Dword(long ea) - возвращающими байт, слово и двойное слово соответственно. Если запрошенная ячейка не существует или не инициализирована, функция возвращает 0xFF (при этом следует быть особенно осторожным с функциями Word и Dword, некорректно сигнализирующих об ошибке - подробнее об этом можно прочитать в под главах Word и Dword соответственно). Поэтому, перед чтением ячейки памяти следует убедиться, что она есть и содержит какое-то значение. Это можно осуществить анализом младшего бита поля атрибутов -если он сброшен - ячейка отсутствует или не инициализирована. Получить содержимое поля атрибутов можно вызовом функции GetFlags (см. описание функции GetFlags) следующим образом: if(MS VAL & GetFlags(ea)) значение ячейки определенно, можно читать; else значение ячейки не определено либо ячейка не существует или же воспользоваться макросом hasValue(F), определенным в <idc.idc>, который следует вызывать так: if(hasValue(GetFlags(ea))) значение ячейки определенно, можно читать; else значение ячейки не определено либо ячейка не существует Более короткий путь предоставляет макрос isLoaded(ea), определенный там же с аналогичным назначением: 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 |