Blog. Just Blog

Управление дизассемблером IDA Pro из своего приложения

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Управление дизассемблером IDA Pro из своего приложения
Управление дизассемблером IDA Pro из своего приложения

В одной из предыдущих статей я приводил пример скрипта для запуска hex-редактора HIEW из дизассемблера IDA. Это действительно удобно и экономит кучу времени. Но при ковырянии очередной программы у меня возникла мысль, а можно ли управлять дизассемблером IDA из другого приложения? Конкретно было бы очень полезно реализовать возможность быстрого перехода в листинге дизассемблера на заданный адрес. Например, в HIEW или File Location Calculator нашли нужный адрес и какой-нибудь командой синхронизировали его с результатами работы дизассемблера. Из скриптов или плагинов IDA управляется через обширное по функционалу и неплохо документированное API, но вот никаких штатных инструментов или методов для взаимодействия сторонних приложений напрямую с дизассемблером я не нашел.

После непродолжительных раздумий я решил просто эмулировать действия пользователя, то есть нажатие на горячую клавишу для вызова окна перехода на адрес, копирование и вставка адреса перехода и, собственно, сам переход. Сказано - сделано. Также эта статья может считаться продолжением материала про управление другим приложением из своей программы. Методы, описанные здесь, могут быть использованы не только при работе с IDA, но и для взаимодействия с другими приложениями.
  1. ;----------------------------------------------------------------------
  2. ; Процедура перехода на выбранный адрес в IDA Pro
  3. ;----------------------------------------------------------------------
  4. ; Параметры:
  5. ;   szAddr - указатель на строку адреса
  6. ;----------------------------------------------------------------------
  7. proc ida_jump_to_address szAddr:DWORD
  8.         pusha
  9.  
  10.         ; Адрес пустой, ничего не делать
  11.         mov     esi,[szAddr]
  12.         cmp     byte [esi],0
  13.         je      .loc_ret
  14.  
  15.         ; Найти главное окно IDA
  16.         invoke  FindWindow,.ida_class,NULL
  17.         or      eax,eax
  18.         jz      .loc_ret
  19.  
  20.         mov     ebx,eax
  21.  
  22.         ; Какой-то диалог уже открыт?
  23.         invoke  FindWindow,.dlg_class,NULL
  24.         or      eax,eax
  25.         jnz     .loc_ret
  26.  
  27.         ; Активировать окно IDA
  28.         invoke  SetForegroundWindow,ebx
  29.         invoke  SendMessage,ebx,WM_ACTIVATE,0,WA_CLICKACTIVE
  30.  
  31.         ; Послать хоткей Jump to address
  32.         invoke  keybd_event,'G',0,0,0
  33.         invoke  keybd_event,'G',0,KEYEVENTF_KEYUP,0
  34.  
  35.         ; Ожидать окно Jump to address в течение 1 секунды
  36.         xor     ebx,ebx
  37. @@:
  38.         invoke  FindWindow,.dlg_class,.jump_title
  39.         or      eax,eax
  40.         jnz     @f
  41.  
  42.         invoke  Sleep,5
  43.         inc     ebx
  44.         cmp     ebx,200
  45.         jne     @b
  46.         ; Окно так и не появилось
  47.         jmp     .loc_ret
  48. @@:
  49.         ; Активировать окно Jump to address
  50.         invoke  SetForegroundWindow,eax
  51.  
  52.         ; Записать в буфер обмена адрес перехода
  53.         invoke  OpenClipboard,0
  54.         invoke  EmptyClipboard
  55.         invoke  GlobalAlloc,GMEM_MOVEABLE+GMEM_DDESHARE,10
  56.         mov     ebx,eax
  57.         invoke  GlobalLock,ebx
  58.         mov     esi,[szAddr]
  59.         mov     edi,eax
  60.         mov     ecx,10
  61.         repnz   movsb
  62.         invoke  GlobalUnlock,ebx
  63.         invoke  SetClipboardData,CF_OEMTEXT,ebx
  64.         invoke  CloseClipboard
  65.         invoke  GlobalFree,ebx
  66.  
  67.         ; Эмулировать нажатие Ctrl+V
  68.         invoke  keybd_event,VK_LCONTROL,0,0,0
  69.         invoke  keybd_event,'V',0,0,0
  70.         invoke  keybd_event,'V',0,KEYEVENTF_KEYUP,0
  71.         invoke  keybd_event,VK_LCONTROL,0,KEYEVENTF_KEYUP,0
  72.  
  73.         ; Эмулировать нажатие Enter
  74.         invoke  keybd_event,VK_RETURN,0,0,0
  75.         invoke  keybd_event,VK_RETURN,0,KEYEVENTF_KEYUP,0
  76. .loc_ret:
  77.         popa
  78.         ret
  79.  
  80. .ida_class   db 'TIdaWindow',0      ; Название класса окна IDA
  81. .dlg_class   db 'TMyDialog',0       ; Название класса окна диалога
  82. .jump_title  db 'Jump to address',0 ; Заголовок окна перехода
  83.  
  84. endp
В качестве единственного параметра функции передается строка в формате ASCIIZ с адресом перехода. Никаких дополнительных проверок на корректность адреса не производится, все ошибки в написании адреса обрабатываются самим дизассемблером IDA.
  1. ; Сегмент данных
  2. section '.data' data readable writeable
  3. address db '0042BDEE',0
  4.  
  5. ; Сегмент кода
  6. section '.code' code readable executable
  7.         ...
  8.         ; Перейти на нужный адрес в листинге дизассемблера
  9.         stdcall ida_jump_to_address,address
  10.         ...
Код получился более-менее рабочий, но не лишенный целого ряда критических недостатков. Так, если одновременно запущены несколько разных процессов IDA, то команда перехода будет отправлена первому из найденных окон. Можно, конечно, дополнительно проверить заголовок окна на предмет наличия в нем имени обрабатываемого файла и отправить запрос на переход именно нужному процессу. Еще этот код подменяет содержимое буфера обмена на адрес перехода, что, в принципе, может оказаться полезным, но точно так же может быть ненужным, если в буфере хранились какие-нибудь ценные данные. Если главное окно IDA было свернуто, то диалог перехода на адрес появится, но вот сам переход выполняться не будет. Ну и напоследок, приведенный код подразумевает, что команда "Jump to address" забиндена на хоткей "G", тогда как никто не запрещает в конфиге IDA поменять ее на любую другую комбинацию клавиш.

По результатам тестирования и из-за выявленных недостатков я решил пока оставить эту разработку в состоянии "полуфабриката", без практического применения в своих программах. Примеров использования также не будет.

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 2064 | Комментариев: 3

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Fast (05.03.2016 в 14:47):
ильФак жадный и зажравшийся. Одно не пойму: зачем юзеры ему помогают в отладке, если он болт давно положил на исправление багов?!
ManHunter (08.02.2016 в 12:02):
Тихий запуск нужен только если используется скрипт, который сам все делает и не требует взаимодействия с пользователем.

Для решения этой задачи вообще ничем не поможет.
brute (08.02.2016 в 09:40):
в IDA есть интересные параметры командной строки - раздел справки "Command line switches":
-A  -тихий  запуск нужной проги без всяких диалоговых окон (у меня работает:)
-b#### -"loading address, a hexadecimal number, in paragraphs". Я написал ильфаку с просьбой пояснить, как сие использовать. Он затребовал номер моей лицензии. Я сказал, что юзаю IdaFree_5.0. Он ответил, что техподдержка только для купивших иду..

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2017
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.06 сек. / MySQL: 2 (0.0038 сек.) / Память: 4.5 Mb
Наверх