eXeLab
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС
выпущен 4 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Русский / Russian English / Английский

Сейчас на форуме: (+3 невидимых)
 · Начало · Статистика · Регистрация · Поиск · ПРАВИЛА ФОРУМА · Язык · RSS · SVN ·

 eXeL@B —› Основной форум —› Неочевидные фичи иды
Посл.ответ Сообщение


Ранг: 481.4 (мудрец)
Статус: Участник
Тот самый :)

Создано: 18 января 2009 15:36 New!
Цитата · Личное сообщение · #1

В IDA есть много прикольных штук, которые добавляются втихую. И натыкаешься на них только случайно. Давайте постить всякие неочевидные фичи иды сюда. Только с пояснениями как пользоваться, а не просто названия меню.

Фича номер раз: "Create Struct from Data"

Позволяет создать структуру (в окне структур) по данным. Например были данные:
RAM:300A0E58 DCW 0x203
RAM:300A0E5A DCD 0x4050102
RAM:300A0E5E DCW 0x304
RAM:300A0E60 DCD 0x2030304

Выделяем эти данные и заходим в меню "edit" - "structs" - "Create Struct from Data".
Вуаля! Получаем структуру:
00000000 struct_0 struc ; (sizeof=0xC)
00000000 anonymous_0 DCW ?
00000002 anonymous_1 DCD ?
00000006 anonymous_2 DCW ?
00000008 anonymous_3 DCD ?
0000000C struct_0 ends

Остается только проименовать поля.

Офигенно помагает когда нужно восставливать таблицу виртуальных функций. Выделил весь массив - и готово. Не надо руками вбивать.


Ранг: 481.4 (мудрец)
Статус: Участник
Тот самый :)

Создано: 19 января 2009 15:59 · Поправил: Hexxx New!
Цитата · Личное сообщение · #2

Фича номер два: "Manual operand"

Казалось бы ну нафига нужно вбивать операнды вручную? Что это дает? Ну изменится отображение, а дальше?

А дальше оказывается что IDA анализирует manual operand'ы на предмет имен уже встречающихся в базе. То есть если сделать Manual Operand и в качестве текста вбить имя ASCII константы, имя глобальной переменной или имя функции, то IDA автоматом проставит XREF. А для ASCII проставит комент.

Как это работает:
Ставим курсор на операнд и нажимаем Alt-F1. Вылазит окно куда можно вбить текст операнда.

Пример.
Есть вот такой код:
Code:
  1. LDR     R0, =aSmErr_allocfreeunitNlunDN ; 0x102DD6F4
  2. LDRH    R2, [R4,#4]     ; nVun
  3. LDR     R1, [SP,#0x30+Id1] ; nLun
  4. ADD     R0, #0x3C       ; pString
  5. BLX     OAM_Debug_thunk_TA


Здесь через R0 передают указатель на текст дебажного сообщения, но адрес текста вычисляется относительно адреса какой-то строковой константы. В нашем случае идет обращение к строке по адресу 0x102DD6F4 + 0x3C = 0x102DD730
Вот собственно строка:
102DD730 aSmErr_allocfreeunitNlun_0 DCB "[SM :ERR] _AllocFreeUnit(nLun:%d, nVun:%d) : Erase fail!",0xD

Имя у этой константы = aSmErr_allocfreeunitNlun_0
Теперь сделаем Manual Operand вот такой:
ADD R0, aSmErr_allocfreeunitNlun_0

На выходе получаем:
Code:
  1. LDR     R0, =aSmErr_allocfreeunitNlunDN
  2. LDRH    R2, [R4,#4]     ; nVun
  3. LDR     R1, [SP,#0x30+Id1] ; nLun
  4. ADD     R0, aSmErr_allocfreeunitNlun_0 ; "[SM :ERR] _AllocFreeUnit(nLun:%d, nVun:"...
  5. BLX     OAM_Debug_thunk_TA


+ автоматом был проставлен xref на адрес 102DD730 с 11308BDA


Ранг: 196.3 (ветеран)
Статус: Участник

Создано: 19 января 2009 22:43 New!
Цитата · Личное сообщение · #3

как сделать настройку Options/Demangled names.../(о) Names, [x] Assume GCC v3.x names - настройкой по умолчанию?


Ранг: 481.4 (мудрец)
Статус: Участник
Тот самый :)

Создано: 19 января 2009 23:38 New!
Цитата · Личное сообщение · #4

[wl] пишет:
как сделать настройку Options/Demangled names.../(о) Names, [x] Assume GCC v3.x names - настройкой по умолчанию?

В ida.cfg сделай вот так:
ShortNameForm = 0x0EA3BE6F
LongNameForm = 0x0640000F
DemangleNames = DEMNAM_NAME


Ранг: 209.5 (наставник)
Статус: Участник
WinCE ARM M@sTeR

Создано: 20 января 2009 01:34 New!
Цитата · Личное сообщение · #5

Потому что я аццкий флудер, и постю всякую херню ради рейтинга.
Жжошь ваще

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

P.S. Тебе кстати ваще уже пора книгу по IDA писать типа "IDA Unleashed" или "ПоIDAние бинарников"...

Ранг: 1045.7 (!!!!)
Статус: Участник

Создано: 20 января 2009 05:27 New!
Цитата · Личное сообщение · #6

не в тему немного
January 20, 2009
IDA v5.4 release is not that far away

I'm happy to inform you that we are entering the beta stage of IDA v5.4!

In addition to numerous small and not that small improvements, the new version will have hree debugger modules: bochs, gdb, and windbg, selectable on the fly (the active debugger session will be closed, though ;))

With the bochs debugger, we offer three different worlds: run-any-code-snippet facility, windows-like-environment for PE files, and any-bochs-image bare-bone machine emulation mode. You can read more about this module in our blog: hexblog.com/2008/11/bochs_plugin_goes_alpha.html
With gdb, x86 and arm targets are supported. Among other things, it is possible to connect IDA to QEMU or debug a virtual machine inside VMWare. We tried it iPhone as well. However, while it works in some curcimstances, there were some problems on the gdbserver side.
With windbg, user and kernel mode debugging is available. The debugger engine from Microsoft, which is currently the only choice for driver and kernel mode debugging, can be used from IDA. It can automatically load required PDB files and populate the listing with meaningful names, types, etc. Speaking of PDB files, IDA imports more information from them: local function variables and types are retrieved too, c++ base classes are handled, etc.

The gdb and windbg debugger modules support local and remote debugging. We tried to make the debugger modules as open as possible: target-specific commands can be sent to all backend engines in a very easy and user-friendly way.

As usual, better analysis and many minor changes have been made. If you spend plenty of time analyzing gcc generated binaries, you'll certainly appreciate that IDA handles its weird way of preparing outgoing function arguments. Now it can trace and find arguments copies to the stack with mov statements.

The new IDA will support Python out of box, thanks to Gergely Erdelyi, who kindly agreed the Python plugin to be included in the official distribution. In fact, the main IDA window will have a command line to enter any python (or other language) expressions and immediately get a result in the message window.

We will prepare the detailed list of improvements later this week.

Posted by Ilfak Guilfanov at 01:29 AM


Ранг: 481.4 (мудрец)
Статус: Участник
Тот самый :)

Создано: 20 января 2009 15:56 · Поправил: Hexxx New!
Цитата · Личное сообщение · #7

Фича номер три: "Bitfield и маски"

Полезная штука, только очень криво реализована, потому почти никто ей непользуется
Битовое поле в IDA сделать очень просто, надо при создании enum'a просто указать птичку "Bitfield". Дальше IDA будет следить за тем, чтобы каждое поле такого энума было степенью двойки. Т.е. возможнные значения для полей будут 1, 2, 4, 8, 16, 32 и т.д.

Например есть код:
Code:
  1. lea     ecx, [ebp+pDEVICE_OBJECT]
  2. mov     [eax+IO_STACK_LOCATION.CompletionRoutine], offset BrbpIrpSyncCompletionRoutine(x,x,x)
  3. mov     [eax+IO_STACK_LOCATION.Context], ecx
  4. mov     [eax+IO_STACK_LOCATION.Control], 0E0h
  5. mov     eax, [ebp+pDeviceExtension]
  6. mov     ecx, [eax+34h]
  7. mov     edx, ebx
  8. call    ds:__declspec(dllimport) IofCallDriver(x,x)



поле IO_STACK_LOCATION.Control - это битовое поле. Если загрузить соответствующий энум:
Code:
  1. 00000001 ; enum MACRO_SL (bitfield)
  2. 00000001 SL_PENDING_RETURNED  = 1
  3. 00000020 SL_INVOKE_ON_CANCEL  = 20h
  4. 00000040 SL_INVOKE_ON_SUCCESS  = 40h
  5. 00000080 SL_INVOKE_ON_ERROR  = 80h


То можем наблюдать отображение вот в таком виде:
Code:
  1. mov     [eax+IO_STACK_LOCATION.Control], SL_INVOKE_ON_CANCEL or SL_INVOKE_ON_SUCCESS or SL_INVOKE_ON_ERROR


Мне например такое отображение не нравится. Я хочу чтобы вместо трех значений было одно.
Хочу чтобы была маска SL_INVOKE_ALWAYS = SL_INVOKE_ON_CANCEL or SL_INVOKE_ON_SUCCESS or SL_INVOKE_ON_ERROR.

Как сделать такую маску?
Для существующего enum'a сделать такую маску уже не получится. Потому что маску надо создавать первой, до создания самих элементов которые в нее входят. Вот такое ограничение в IDA. Поэтому придетcя делать новый битфилд.

Создавать битфилд надо начинать с создания маски.
Создаем новый энум и добавлем поле самой маски. Делается это вот так:

Code:
  1. Name: SL_INVOKE_ALWAYS
  2. Value: 0xE0
  3. Mask: 0xE0
  4. Mask Name: SL_INVOKE_ALWAYS_MASK

Если не ясно см скриншот:


Получится вот такой битфилд:
Code:
  1. 000000E0 ; enum MACRO_SL_MY (bitfield)
  2. 000000E0 SL_INVOKE_ALWAYS_MASK      = 0E0h
  3. 000000E0 SL_INVOKE_ALWAYS  = 0E0h


Дальше добиваем остальные части битфилда. Для каждого из полей которые входят в маску надо указывать:
Mask: 0xE0
Mask Name: SL_INVOKE_ALWAYS_MASK
Если не ясно см скриншот:


Какие поля попадают в маску? В нашем случае это SL_INVOKE_ON_CANCEL, SL_INVOKE_ON_SUCCESS и SL_INVOKE_ON_ERROR.
Поле SL_PENDING_RETURNED не входит в маску 0xE0. Потому что 1 & 0xE0 = 0. В маску входят долько поля для которых
"логическое и" с 0xE0 = само значение поля.
То есть:
0x20 & 0xE0 = 0x20
0x40 & 0xE0 = 0x40
0x80 & 0xE0 = 0x80

Я все это к тому, что для поля SL_PENDING_RETURNED маску не ставим.

Получается вот такой enum:
Code:
  1. 00000001 ; enum MACRO_SL_MY (bitfield)
  2. 00000001 SL_PENDING_RETURNED_MY  = 1
  3. 000000E0 SL_INVOKE_ALWAYS_MASK      = 0E0h
  4. 000000E0 SL_INVOKE_ON_CANCEL_MY  = 20h
  5. 000000E0 SL_INVOKE_ON_SUCCESS_MY  = 40h
  6. 000000E0 SL_INVOKE_ON_ERROR_MY  = 80h
  7. 000000E0 SL_INVOKE_ALWAYS  = 0E0h



Применяем:
Code:
  1. lea     ecx, [ebp+pDEVICE_OBJECT]
  2. mov     [eax+IO_STACK_LOCATION.CompletionRoutine], offset BrbpIrpSyncCompletionRoutine(x,x,x)
  3. mov     [eax+IO_STACK_LOCATION.Context], ecx
  4. mov     [eax+IO_STACK_LOCATION.Control], SL_INVOKE_ALWAYS
  5. mov     eax, [ebp+pDeviceExtension]
  6. mov     ecx, [eax+34h]
  7. mov     edx, ebx
  8. call    ds:__declspec(dllimport) IofCallDriver(x,x)


проверяем, как работают другие части энума. Если применить наш энум на значении 0xE1, то IDA отобразит его вот так:
Code:
  1. SL_PENDING_RETURNED_MY or SL_INVOKE_ALWAYS


Но что будет если попытаться применить энум на значении 0xA0?
Поидее должно бы показать:
Code:
  1. SL_INVOKE_ON_CANCEL_MY or SL_INVOKE_ON_ERROR_MY

Но фиг вам! Просто пометит красным, как будто мы применили энум на значении, которого нет в энуме.
Так и есть, когда мы указали маску, IDA перестает совмещать значения, которые находятся в пределах маски SL_INVOKE_ALWAYS_MASK.
Значение 0xA0 - как раз входит в маску 0xE0. И чтобы 0xA0 хоть как-то отображалось придется создать еще одно поле в энуме:

Code:
  1. Name: SL_INVOKE_ON_CANCEL_OR_ERROR
  2. Value: 0xA0
  3. Mask: 0xE0
  4. Mask Name: SL_INVOKE_ALWAYS_MASK


p.s. Судя по IDA 5.4 Ильфака подменили. Я думал что все фишки в 5.3 - это редкое озарение. А тут снова столько всяких полезных вещей добавил 0_o. Даже купить захотелось Но я крепкий и сдержусь

Ранг: 115.1 (ветеран)
Статус: Участник

Создано: 20 января 2009 18:00 New!
Цитата · Личное сообщение · #8

Hexxx пишет:
Судя по IDA 5.4 Ильфака подменили.


судя по всему и по некоторым сообщениям Ильфака на форуме он сейчас координирует проект
а разработкой занимается команда, аля Солодовников )


Ранг: 1013.7 (!!!!)
Статус: Участник

Создано: 20 января 2009 22:39 New!
Цитата · Личное сообщение · #9

>То можем наблюдать отображение вот в таком виде:
и дальше невидная форма
то глюк или у меня екплоер так показывает?


Ранг: 481.4 (мудрец)
Статус: Участник
Тот самый :)

Создано: 20 января 2009 23:02 New!
Цитата · Личное сообщение · #10

reversecode пишет:
и дальше невидная форма

Там было:
mov [eax+IO_STACK_LOCATION.Control], SL_INVOKE_ON_CANCEL or SL_INVOKE_ON_SUCCESS or SL_INVOKE_ON_ERROR

В опере нормально все видно.


Ранг: 481.4 (мудрец)
Статус: Участник
Тот самый :)

Создано: 3 февраля 2009 14:54 · Поправил: Hexxx New!
Цитата · Личное сообщение · #11

Фича №4. Русские символы.

Поумолчанию IDA заточена для буржуинов. Поэтому вместо русского языка, можно наблюдать вот такое:
Code:
  1. .rdata:0041573C unk_41573C      db 0CFh ; ¦ ; DATA XREF: _wmain+20o
  2. .rdata:0041573D                 db 0F0h ; ¨
  3. .rdata:0041573E                 db 0E5h ; õ
  4. .rdata:0041573F                 db 0E2h ; ò
  5. .rdata:00415740                 db 0E5h ; õ
  6. .rdata:00415741                 db 0E4h ; ô
  7. .rdata:00415742                 db  21h ; !


Не весело вообще. Исправляется через правку таблицы перекодирования в файле ida.cfg:
По умолчанию там стоит вот эта:
Code:
  1. // (trivial translation - no changes)
  2. XlatAsciiOutput =
  3. /*00..0F*/ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
  4. /*10..1F*/ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
  5. /*20..2F*/ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
  6. ...

ее надо всю закоментить, т.е. добавить // вначале каждой строки.
И раскоментить следующую таблицу:
Code:
  1. // translation table for win1251 encoding
  2.  XlatAsciiOutput =
  3.   /*00..0F*/ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
  4.  /*10..1F*/ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
  5.  /*20..2F*/ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
  6.  /*30..3F*/ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
  7.  /*40..5F*/ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
  8.  /*50..5F*/ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
  9.  /*60..6F*/ "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
  10.  /*70..7F*/ "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
  11.  /*80..8F*/ "\x3f\x3f\x27\x3f\x22\x3a\xc5\xd8\x3f\x25\x3f\x3c\x3f\x3f\x3f\x3f"
  12.  /*90..9F*/ "\x3f\x27\x27\x22\x22\x07\x2d\x2d\x3f\x54\x3f\x3e\x3f\x3f\x3f\x3f"
  13.  /*A0..AF*/ "\xff\xf6\xf7\x3f\xfd\x3f\xb3\x15\xf0\x63\xf2\x3c\xbf\x2d\x52\xf4"
  14.  /*B0..BF*/ "\xf8\x2b\x49\x69\x3f\xe7\x14\xfa\xf1\xfc\xf3\x3e\x3f\x3f\x3f\xf5"
  15.  /*C0..CF*/ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
  16.  /*D0..DF*/ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
  17.  /*E0..EF*/ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
  18.  /*F0..FF*/ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef";


После этого можно будет видеть русские символы:
Code:
  1. .rdata:0041573C unk_41573C      db 0CFh ; П ; DATA XREF: _wmain+20o
  2. .rdata:0041573D                 db 0F0h ; р
  3. .rdata:0041573E                 db 0E5h ; е
  4. .rdata:0041573F                 db 0E2h ; в
  5. .rdata:00415740                 db 0E5h ; е
  6. .rdata:00415741                 db 0E4h ; д
  7. .rdata:00415742                 db  21h ; !

Ранг: 56.1 (постоянный)
Статус: Участник

Создано: 27 января 2010 01:35 · Поправил: vptrlx New!
Цитата · Личное сообщение · #12

>>Фича номер два: "Manual operand"

(Может я конечно расскажу о велосипеде, но) есть ещё одна похожая фича:
пусть есть кодес типа такого:

Code:
  1. xor     edx, edx
  2. mov     [eax+10h], edx
  3. mov     [eax+0Ch], edx
  4. push    edx
  5. lea     edx, [eax+10h]
  6. push    edx
  7. push    dword ptr [eax+8]
  8. push    dword ptr [eax+14h]
  9. push    dword ptr [eax]
  10. call    sub_12345


Но мы знаем, что функция sub_12345 - это jmp ReadFile, хотя как такая не определяется например из-за того, что код - это нерабочий дамп какого-нибудь прота без восстановленного импорта и тп.
Если теперь выделить sub_12345, нажать "n" и написать название ReadFile, а затем, когда ида спросит, не хотим ли мы добавить к столь необычному названию "a numerical suffix", согласиться с предложением, то (в данном случае) она автоматом добавит комментарии, а если бы я выбрал пример поудачнее, то и переменные бы переименовала и функцию бы подправила:
Code:
  1. xor     edx, edx
  2. mov     [eax+10h], edx
  3. mov     [eax+0Ch], edx
  4. push    edx             ; lpOverlapped
  5. lea     edx, [eax+10h]
  6. push    edx             ; lpNumberOfBytesRead
  7. push    dword ptr [eax+8] ; nNumberOfBytesToRead
  8. push    dword ptr [eax+14h] ; lpBuffer
  9. push    dword ptr [eax] ; hFile
  10. call    ReadFile_0

Ранг: 60.6 (постоянный)
Статус: Участник

Создано: 27 января 2010 05:32 New!
Цитата · Личное сообщение · #13

Такой вопрос к Вам, о гуру ИДЫ:
Допустим есть такой участок кода:
Code:
  1. 004300C2    F0:04 14        LOCK ADD AL,14                           ; LOCK prefix is not allowed
  2. 004300C5    50              PUSH EAX
  3. 004300C6    880C54          MOV BYTE PTR SS:[ESP+EDX*2],CL
  4. 004300C9    DFDE            FISTP ESI                                ; Illegal use of register
  5. 004300CB    BE BD0814FF     MOV ESI,FF1408BD
  6. 004300D0    D319            RCR DWORD PTR DS:[ECX],CL
  7. 004300D2    E8 04397D71     CALL 71C039DB
  8. 004300D7    8C77 FF         MOV WORD PTR DS:[EDI-1],SEG?             ; Undefined segment register
  9. 004300DA    0083 7E58FF14   ADD BYTE PTR DS:[EBX+14FF587E],AL
  10. 004300E0    BA 9DFB7465     MOV EDX,6574FB9D
  11. 004300E5    FF76 34         PUSH DWORD PTR DS:[ESI+34]
  12. 004300E8    BD 3585C033     MOV EBP,33C08535

Можно ли при создании асм-файла(File->Produce file...->asm file) заставить иду захватывать и функции которые вызываются из выделенного участка. В данном случае это 004300D2 E8 04397D71 CALL 71C039DB. А то уж очень не приятно по кусочкам (:


Ранг: 481.4 (мудрец)
Статус: Участник
Тот самый :)

Создано: 27 января 2010 11:43 New!
Цитата · Личное сообщение · #14

s0l пишет:
Можно ли при создании асм-файла(File->Produce file...->asm file) заставить иду захватывать и функции которые вызываются из выделенного участка.

Только если сделать скрипт, который будет рекурсивно это(вывод асма в файл) делать. Я когда-то такой делал, он по инету разошелся.


Ранг: 481.4 (мудрец)
Статус: Участник
Тот самый :)

Создано: 12 мая 2010 21:28 New!
Цитата · Личное сообщение · #15

теперь не найти. Но в общем там ничего сложного: идешь по функции, собираешь все ее ветвления и xref'ы на данные, и дальше через GenerateFile(OFILE_ASM,...) выписываешь по порядку все подфункции и данные. Чтобы не было повторов ставишь на пройденой функции коммент, например "1". Когда заходишь в функцию, проверяешь есть ли у нее комент "1", если есть - скипаешь, если нет - выписываешь в файл.

Еще я делал чтобы код писался в один файл, а данные в другой. А потом их соединял. Так проще, чтобы не трахаться с объявлениями.


Статус: Пришелец

Создано: 13 мая 2010 06:54 New!
Цитата #16

Тема почищена, зачинщик (VodoleY) отбанен на три дня.


Ранг: 481.4 (мудрец)
Статус: Участник
Тот самый :)

Создано: 9 марта 2011 02:00 · Поправил: Hexxx New!
Цитата · Личное сообщение · #17

Фича номер пять: "местное переименование регистра"

Если выбрать регистр в пределах фунции и нажать на нем 'N', то можно его переименовать. И в пределах всей функции вместо привычного esi будет This:
Code:
  1. sub_443F70      proc near              
  2.  
  3. var_C           = dword ptr -0Ch
  4. var_4           = dword ptr -4
  5. arg_8           = dword ptr  0Ch
  6. arg_C           = dword ptr  10h
  7. arg_10          = dword ptr  14h
  8.  
  9. This = esi
  10.                 push    0FFFFFFFFh
  11.                 push    offset loc_466D18
  12.                 mov     eax, large fs:0
  13.                 push    eax
  14.                 push    ebx
  15.                 push    This
  16.                 push    edi
  17.                 mov     eax, dword_487050
  18.                 xor     eax, esp
  19.                 push    eax
  20.                 lea     eax, [esp+1Ch+var_C]
  21.                 mov     large fs:0, eax
  22.                 mov     This, ecx
  23.                 mov     edi, [esp+1Ch+arg_8]
  24.                 test    edi, edi
  25.                 jz      short loc_443FD7
  26.                 cmp     byte ptr [This+0D20h],

Про это знают все. И это вообще никак не помогает в случае, когда сначала регистр используется для хранения указателя на одну структуру, а потом на другую, и все в пределах одной функции.
Для этого используется фича "местного переименования":
1) выделяем нужный кусок кода
2) нажимаем 'V', вылазит окно "Rename Register"
3) в поле Old Name - пишем имя регистра, который надо переименовать
4) в поле New Name - новое имя
получаем:
Code:
  1.                 mov     edi, [ebp+context]
  2.                 mov     eax, 0FFFFFFCEh
  3.                 test    edi, edi
  4.                 jz      short @@end
  5. AppleKeychainExtra = edi
  6.                 mov     eax, ds: (alloc - 1461h)[ebx]
  7.                 mov     [esp+4], eax
  8.                 mov     eax, ds: (NSAutoreleasePool - 1461h)[ebx]
  9.                 mov     [esp], eax
  10.                 call    _objc_msgSend
  11.                 mov     edx, ds: (init - 1461h)[ebx]
  12.                 mov     [esp+4], edx
  13.                 mov     [esp], eax
  14.                 call    _objc_msgSend
  15.                 mov     esi, eax
  16.                 mov     eax, ds: (updateMenuState - 1461h)[ebx]
  17.                 mov     [esp+4], eax
  18.                 mov     [esp], AppleKeychainExtra
  19.                 call    _objc_msgSend
  20.                 mov     eax, ds: (release - 1461h)[ebx]
  21.                 mov     [esp+4], eax
  22.                 mov     [esp], esi
  23.                 call    _objc_msgSend
  24.                 xor     eax, eax
  25.  
  26. @@end:                                  
  27.                 mov     ebx, [ebp+var_C]
  28.                 mov     esi, [ebp+var_8]
  29.                 mov     edi, [ebp+var_4]

edi был переименован в AppleKeychainExtra после jz short @@end, и переименование актуально до @@end

| Сообщение посчитали полезным: Vintersorg, Fallout, rr222, mak, int 26h, V0ldemAr, _ruzmaz_, kp0m



Ранг: 481.4 (мудрец)
Статус: Участник
Тот самый :)

Создано: 16 марта 2011 02:11 · Поправил: Hexxx New!
Цитата · Личное сообщение · #18

Фича номер шесть: "событие срабатывания брейкпоинта под свои нужды"

Думаю все видели в окошке, которое вылазит при установке брейкпоинта, есть поле Condition. В нем предлагается писать условие срабатывания брейкпоинта, типа "EAX==0xDEAD". Ну и в Help'e есть такая приписочка, что эта строчка может быть любым IDC выражением. Вот и хорошо

Есть в IDA\idc файл ida.idc, в который можно дописывать свои функции, или инклюдить из других idc, и они будут доступны из редактора скриптов, а кроме того из того самого поля Condition. Или вообще их можно поставить на hotkey, гуглите "Associating IDC Scripts with Hotkeys" и вам откроется истина.

Короче, пишем в ida.idc свою функцию вида:
Code:
  1. static PrintArgs()
  2. {
  3.          auto esp;
  4.          esp=GetRegValue("ESP");
  5.          Message("Hello arg1 is %08X\n", Dword(esp));
  6.          Message("Hello arg2 is %08X\n", Dword(esp+4));
  7.          Message("Hello arg3 is %08X\n", Dword(esp+8));
  8.  
  9.          return 1;
  10. }

"return 1" нужно для того, чтобы брейкпоинт срабатывал всегда.

Ставим брейк поинт на инструкцию call в коде:
Code:
  1. push    edx             ; RawDataSize
  2. push    eax             ; RawData
  3. push    ecx             ; int
  4. call    CryptEncrypt

В поле condition пишем:
Code:
  1. PrintArgs()

убираем у брейк поинта птичку "Break" и получаем самый настоящий логгер аргументов:
Code:
  1. Hello arg1 is 123DCEF0
  2. Hello arg2 is 48AD12A0
  3. Hello arg3 is 00000008
  4. Hello arg1 is 123DCEF0
  5. Hello arg2 is 48AD12D0
  6. Hello arg3 is 0000001C

Можно пойти дальше, и дописать дамп данных:
Code:
  1. static PrintDump(addr, len)
  2. {
  3.          auto i,end;
  4.          end=addr+len;
  5.          for (i=addr; i< end ; i++)
  6.          {
  7.                  Message("%02X ", Byte(i));
  8.          }
  9.          Message("\n");
  10. }
  11.  
  12. static PrintArgs()
  13. {
  14.          auto esp;
  15.          esp=GetRegValue("ESP");
  16.          PrintDump(Dword(esp+4), Dword(esp+8));
  17. }

И получаем полноценный API логгер

| Сообщение посчитали полезным: NikolayD, r_e, OKOB, mak, Getorix, _ruzmaz_, Bad_guy, ximerus


Ранг: 33.4 (посетитель)
Статус: Участник

Создано: 16 марта 2011 12:19 New!
Цитата · Личное сообщение · #19

Hexxx
Hexxx пишет:
esp=GetRegValue("ESP");


имена регистров разве не зарезервированы?
можно и так:
auto r_esp;
r_esp = esp;


Ранг: 481.4 (мудрец)
Статус: Участник
Тот самый :)

Создано: 16 марта 2011 12:42 New!
Цитата · Личное сообщение · #20

redlord пишет:
имена регистров разве не зарезервированы?

не знаю, на "auto esp;" не возмутилось.


Статус: Пришелец

Создано: 16 марта 2011 23:27 New!
Цитата #21

Hexxx пишет:
Code:
  1. static PrintArgs()
  2. {
  3.          auto esp;
  4.          esp=GetRegValue("ESP");
  5.          Message("Hello arg1 is %08X\n", Dword(esp));
  6.          Message("Hello arg2 is %08X\n", Dword(esp+4));
  7.          Message("Hello arg3 is %08X\n", Dword(esp+8));
  8.  
  9.          return 1;
  10. }

Лучше так:
Code:
  1. static PrintArgs()
  2. {
  3.          Message("Hello arg1 is %08X\n", Dword(esp));
  4.          Message("Hello arg2 is %08X\n", Dword(esp+4));
  5.          Message("Hello arg3 is %08X\n", Dword(esp+8));
  6.  
  7.          return 1;
  8. }


Ранг: 481.4 (мудрец)
Статус: Участник
Тот самый :)

Создано: 16 марта 2011 23:31 New!
Цитата · Личное сообщение · #22

как скажете
 eXeL@B —› Основной форум —› Неочевидные фичи иды

Оригинальный DVD-ROM: eXeL@B DVD !

Вы находитесь на форуме сайта EXELAB.RU
Проект ReactOS