HimeraSearchDB
Carding_EbayThief
triada
CrackerTuch
d-shop
HimeraSearchDB

НОВОСТИ IDA Pro: 11 советов, которые вы (может быть) не знали

Bonnie
Оффлайн
Регистрация
12.04.17
Сообщения
19.095
Реакции
107
Репутация
0
Как скопировать псевдокод в ассемблерный листинг? Как правильно выровнять структуры? Как лучше всего сделать экспорт куска данных для использования в скрипте? В этой статье я покажу компиляцию полезных, как мне кажется, советов для IDA Pro, честно украденных позаимствованных из разных источников и своего опыта.
mo8cxfgld4b-twf07cwk9z7i8vq.png



Выравнивание структур



В изучаемой программе могут использоваться структуры, которые используют "нестандартное" выравнивание, скажем, по одному байту. Такие структуры можно без проблем создать в виде структур (Shift + F9), а в случае использования вида локальных типов нужно воспользоваться директивой pragma, а точнее pragma pack. pragma pack (n) задает выравнивание членов структур (чаще всего по умолчанию используется выравнивание 4 или 8 байт).


Например, если мы имеем дело с такой структурой


struct test_s
{
char ch1;
QWORD qword;
};


и знаем, что ее члены идут один за другим (т.е. сам экземпляр структуры занимает 5 байт), то при ее наложении на данные получим такую картину:


mp74al9nkprcsv7leihgqun6x3m.png



Видно, что между ch1 и qword образовалось неиспользуемое пространство, на месте которого по задумке должен был быть сам qword. Но если перепишем структуру следующим образом:


#pragma pack(1)
struct test_s
{
char ch1;
QWORD qword;
};


то получим корректный результат:


8lits68hs1glqr0g4iatqacxl9a.png


Текстовый поиск



В декомпиляторе нет Ctrl+F, но оказывается, что Alt+T, работающий в окне дизассемблера, точно также работает и в окне декомпилятора.


-gf55icmkkhcnsqx1mx4kjgpjxg.png



qg5bczp6gu-uo0tl1rbiu7vitxq.png


Segments → Rebase



Если вы с первого раза не угадали правильный адрес загрузки прошивки, то можете воспользоваться функцией переноса idb на другой адрес.


Например, мы загрузили прошивку в IDA по нулевому адресу. По адресу 0x04 находится указатель на функцию, который сейчас указывает в область памяти, которой не сопоставлено ни одного сегмента в idb.


mjn7bvxnomvd0ylscpm11hsusva.png



Зайдем в Edit→Segments→Rebase и перенесем нашу прошивку на адрес 0x8000000.


ix0smcqxdoe_o3egkdmefl34dna.png



В результате у нас появился нормальный xref:


iy-lrhiqnzt7qfotqyo2iysssgi.png


Бряки



В IDA, как и в большинстве отладчиков, можно ставить условные бряки, т.е. они будут срабатывать только если выполняется определенное условие. Условие представляет собой конструкцию на языке IDC или Python, в которой во время отладки доступны глобальные переменные с соответствующими именами для доступа к каждому из регистров.


Также во время отладки таким образом можно менять значения регистров и содержимое памяти.

Выделение участков данных и экспорт (Alt+L — Shift+E)



Для выделения большого сегмента данных можно воспользоваться сочетанием клавиш Alt+L, чтобы начать выделение региона и управлять границами выделяемого региона с помощью мыши или клавиш управления курсором. Выделенные данные можно экспортировать в один их удобных форматов (строка, hex-последовательность, массив байт C) и помощью сочетания клавиш Shift+E.


t2-puwang6_xb3qpoqkg7deoxhy.gif


Удаленная отладка



IDA поддерживает удаленные GDB и Windbg-сервера, но также в ней есть возможность удаленной отладки с помощью своих собственных серверов (находятся в каталоге IDADIR\dbgsrv).


6s1hmhcrc_icisa4viun1owbrz0.png


Строковые литералы в декомпиляторе



Часто может встречаться ситуация, когда read-only данные перемешаны в одном сегменте с read-write данными (например, при использовании старых компиляторов, компиляторов для RTOS и др.). При этом при использовании декомпилятора можно наблюдать следующее:


4lymkg17d3yo6l1rroveip3xkvm.png



Как мы видим, вместо строковых литералов подставляются названия переменных. Это отрицательно сказывается на читабельности псевдокода. Для исправления этой неурядицы можем изменить тип строковых переменных с char на const char.


3ajrxkyryuysmj53nvxqtlrvpvq.png



В результате строковая переменная с исправленным типом будет действительно отображаться в псевдокоде как строковый литерал.


m4cngrc0vszp73tlckgs0h4tl3o.png



Второй вариант — это настроить декомпилятор на отображение всех строк как литералов (а не только неизменяемых). Для этого убираем галку "Print only constant strings literals" в настройках декомпилятора.


jdlxhpi1qmefh3os2l1nt5ydn6s.png



В результате получаем красивый вывод:


s9wvtz7ikqwckerwdj_6le7yeps.png


Код little endian, а данные big endian



Иногда встречается Little Endian код для ARM, в то время, как данные имеют формат Big Endian. В этом случае для корректного отображения данных надо зайти в General options → Analysis → Processor specific analysis options → Edit ARM architecture options и поставить галку "BE-8 code (ARMB)".


dfxoi9veebjsl8zd9byyhlsmfh0.png


Бряки и gdbserver



То ли я работаю с такими версиями gdbserver, то ли лыжи не едут, но включенная по умолчанию в IDA "single stepping support" у меня не работает, и из-за этого при отладке не срабатывают вообще никакие бряки, кроме самой первой. В этом случае я захожу в настройки отладчика, выбираю "Set specific options" и убираю галку "Use stepping support".


i320uwvjbdjls7htlsntwap9vta.png



Эта настройка не сохраняется в idb, и для того, чтобы не делать этого каждый раз, в конфигурационном файле dbg_gdb.cfg необходимо исправить параметр SINGLE_STEP.


iuftfn9rgj1bbo9yerlfggyjx8q.png


И еще про gdbserver



И еще поворчу про работу с gdbserver (в этот раз — в случае присоединения к удаленному процессу). Если на целевой машине включен ASLR, то у IDA может не получиться понять реальное расположение образа отлаживаемого файла в памяти. В результате IDA будет пытаться работать с адресами, которые указывают в какое-то невалидное пространство памяти. Для борьбы с этим можно еще до присоединения к удаленному процессу сделать rebase idb на актуальный адрес, и только потом присоединяться к процессу.

Сбор мусора в IDAPython



Интерпретатор Python, встроенный в IDA работает всегда и не закрывается до закрытия самой IDA. Поэтому сущности вашего Python-скрипта или плагина не будут автоматически удаляться. Кроме очевидных последствий вроде внезапных для автора утечек памяти, это может привести и к более забавным побочным эффектам, как, например, во время использования модуля logging.


Если написать такой скрипт


import logging

def main():
logger = logging.getLogger('test1-script')
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('[TEST 1] %(name)s - %(message)s')
ch = logging.StreamHandler()
ch.setFormatter(formatter)
logger.addHandler(ch)
logger.debug("Log message!")

if __name__ == "__main__":
main()


и запустить его два раза подряд, увидим такой вывод:


cqmjamal8rb0l5cfeit8tll53wu.png



Происходит это потому, что функция getLogger либо создает, либо получает из глобального кэша уже существующий объект класса Logger. Далее к полученному инстансу логгера (одинаковому при каждом запуске скрипта) добавляется еще один хэндлер. Проверить это можно просто: выводим кэш (словарь) логгеров и список хэндлеров:


kf4tnigeguq6rnaga8n7v4tnoig.png



Есть как минимум два способа бороться с этим:


logging.Logger.manager.loggerDict.clear()


или


reload(logging)

И последнее



Минутка внимания еще нескольким трюкам:

  1. Начиная с версии 7.4, объявления локальных переменных в декомпиляторе могут быть "слохпнуты" по умолчанию — это настраивается в файле hexrays.cfg.
  2. Также в этой версии можно "прыгать" между фигурными скобками в псевдокоде по клавише "%" (Shift+5).
  3. С помощью горячей клавиши "/" можно скопировать псевдокод в ассемблерный листинг в виде комментариев.

Источники


  1. Друзья-коллеги
  2. IDA Pro Book
  3. Release Notes
  4. И другие.
 
Сверху Снизу