Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ida.final.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
6 Mб
Скачать

Success DelFunction(long ea);

Вызов DelFunction позволяет удалять функцию, указав любой, принадлежащий ей адрес. Вместе с функцией уничтожаются все локальные переменные, и аргументы, если они есть. Все остальное (инструкции, перекрестные ссылки, метки) остается нетронутым.

Например:

.text:00400FFF ; _____________ S U B R O U T I N E ____________________________________

.text:00400FFF

.text:00400FFF ; Attributes: library function

.text:00400FFF

.text:00400FFF __amsg_exit proc near ; CODE XREF: __setenvp+4Ep

.text:00400FFF ; __setenvp+7Dp ...

.text:00400FFF

.text:00400FFF arg_0 = dword ptr 4

.text:00400FFF

.text:00400FFF cmp dword_0_408758, 2

.text:00401006 jz short loc_10_40100D

.text:00401008 call __FF_MSGBANNER

.text:0040100D

.text:0040100D loc_10_40100D: ; CODE XREF: __amsg_exit+7j

.text:0040100D push [esp+arg_0]

.text:00401011 call __NMSG_WRITE

.text:00401016 push 0FFh

.text:0040101B call off_0_408050

.text:00401021 pop ecx

.text:00401022 pop ecx

.text:00401023 retn

.text:00401023 __amsg_exit endp

DelFuncton(0x400FFF);

.text:00400FFF __amsg_exit: ; CODE XREF: __setenvp+4Ep

.text:00400FFF ; __setenvp+7Dp ...

.text:00400FFF cmp dword_0_408758, 2

.text:00401006 jz short loc_10_40100D

.text:00401008 call __FF_MSGBANNER

.text:0040100D

.text:0040100D loc_10_40100D: ; CODE XREF: .text:00401006j

.text:0040100D push dword ptr [esp+4]

.text:00401011 call __NMSG_WRITE

.text:00401016 push 0FFh

.text:0040101B call off_0_408050

.text:00401021 pop ecx

.text:00401022 pop ecx

.text:00401023 retn

Операнд

Пояснения

ea

Любой линейный адрес, принадлежащий функции

Return

Завершение

Пояснения

0

Вызов завершился не успешно. Функция не была создана

1

Вызов завершился Успешно

Success SetFunctionEnd(long ea,long end);

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

Например:

seg000:22C0 start proc near

seg000:22C0 call sub_0_22DD

seg000:22C3 call sub_0_2325

seg000:22C6 call sub_0_235B

seg000:22C9 call sub_0_2374

seg000:22CC call sub_0_23B6

seg000:22CF call sub_0_23F8

seg000:22D2 jnz loc_0_22DA

seg000:22D4 nop

seg000:22D5 nop

seg000:22D6 nop

seg000:22D7 call sub_0_2412

seg000:22DA

seg000:22DA loc_0_22DA:

seg000:22DA call sub_0_2305

seg000:22DA start endp

SetFunctionEnd(0x122C3,0x122СF);

seg000:22C0 start proc near

seg000:22C0 call sub_0_22DD

seg000:22C3 call sub_0_2325

seg000:22C6 call sub_0_235B

seg000:22C9 call sub_0_2374

seg000:22CC call sub_0_23B6

seg000:22CF call sub_0_23F8 ;  источник

seg000:22CF start endp

seg000:22D2 jnz loc_0_22DA ;  приемник

seg000:22D4 nop

seg000:22D5 nop

seg000:22D6 nop

seg000:22D7 call sub_0_2412

seg000:22DA

seg000:22DA loc_0_22DA:

seg000:22DA call sub_0_2305

Однако при этом не удаляется перекрестная ссылка на следующую команду, что может иметь неприятные последствия, например, при попытке пометить функцию как undefined, что и видно на следующем примере:

MakeUnkn(0x122C0,1);

seg000:22C0 start db 0E8h ; ш

seg000:22C1 db 1Ah ;

seg000:22C2 db 0 ;

seg000:22C3 db 0E8h ; ш

seg000:22C4 db 5Fh ; _

seg000:22C5 db 0 ;

seg000:22C6 db 0E8h ; ш

seg000:22C7 db 92h ; Т

seg000:22C8 db 0 ;

seg000:22C9 db 0E8h ; ш

seg000:22CA db 0A8h ; и

seg000:22CB db 0 ;

seg000:22CC db 0E8h ; ш

seg000:22CD db 0E7h ; ч

seg000:22CE db 0 ;

seg000:22CF db 0E8h ; ш

seg000:22D0 db 26h ; &

seg000:22D1 db 1 ;

seg000:22D2 db 75h ; u

seg000:22D3 db 6 ;

seg000:22D4 db 90h ; Р

seg000:22D5 db 90h ; Р

seg000:22D6 db 90h ; Р

Кроме того, если в качестве нового конца указать адрес, уже принадлежащий какой-нибудь функции (разумеется, кроме текущей), то вызов провалиться.

seg000:2305 sub_0_2305 proc near

seg000:2305 sti

seg000:2306 call sub_0_1CA

seg000:2309 mov ah, 4Ch

seg000:230B int 21h

seg000:230B sub_0_2305 endp

seg000:230B

seg000:230D

seg000:230D ; _______________ S U B R O U T I N E

seg000:230D

seg000:230D

seg000:230D sub_0_230D proc near

seg000:230D mov si, 2C51h

seg000:2310 call sub_0_DD

seg000:2313 mov si, 2C4Dh

seg000:2316 call sub_0_2E2

seg000:2319 jnb loc_0_2321

seg000:231B nop

seg000:231C nop

seg000:231D nop

seg000:231E mov si, 2A2Dh

seg000:2321

seg000:2321 loc_0_2321:

seg000:2321 call sub_0_DD

seg000:2324 retn

seg000:2324 sub_0_230D endp

Message(“0x%X \n”,

SetFunctiinEnd(0x12305,0x12310)

);

1

Если функция возвращает отличное от нуля число, то это признак не успешности завершения операции. Следовательно, адрес конца не был изменен. (Повторный дамп для экономии не приводится)

Напротив, если за концом функции расположены данные (можно даже массив), то новый адрес конца будет успешно установлен.

seg000:292F sub_0_292F proc near

seg000:292F inc bx

seg000:2930 loop loc_0_292F

seg000:2932 nop

seg000:2933 retn

seg000:2933 sub_0_292F endp

seg000:2933

seg000:2933 ; ----------------------------------

seg000:2934*word_0_2934 dw 0

seg000:2934*

seg000:2936*byte_0_2936 db 0

SetFuctionEnd(0x12930,0x12934);

seg000:292F sub_0_292F proc near

seg000:292F inc bx

seg000:2930 loop loc_0_292F

seg000:2932 nop

seg000:2933 retn

seg000:2933

seg000:2933 ; ----------------------------------

seg000:2934*word_0_2934 dw 0

seg000:2934*

seg000:2934 sub_0_292F endp

seg000:2936*byte_0_2936 db 0

Можно даже указать на середину массива или ячейки. Функция завершиться успешно, адрес будет изменен, но он перестанет отображаться на экране, поскольку IDA забыла его округлить или проверить на корректность!

Это подтверждает следующий пример, проделанный над куском кода, приведенном выше.

Message(“0x%X \n”,

SetFuctionEnd(0x12930,0x12935)

);

0

seg000:292F sub_0_292F proc near

seg000:292F inc bx

seg000:2930 loop loc_0_292F

seg000:2932 nop

seg000:2933 retn

seg000:2933

seg000:2933 ; ----------------------------------

seg000:2934*word_0_2934 dw 0

seg000:2934*

seg000:2936*byte_0_2936 db 0

Однако, в действительности, то, что конец функции не отображается на экране, еще ничего не значит. Попробуем убедиться, что IDA действительно не выполнила округления, и адрес 0x12936 не принадлежит функции.

Message(“0x%X \n”,

SetFuctionEnd(0x12936,0x12933)

);

1

Ага, вызов SetFunctionEnd возвратил ошибку, следовательно, адрес 0x12936 действительно не принадлежит функции. Попробуем теперь уменьшить его на единицу:

Message(“0x%X \n”,

SetFuctionEnd(0x12935,0x12933)

);

0

seg000:292F sub_0_292F proc near

seg000:292F inc bx

seg000:2930 loop loc_0_292F

seg000:2932 nop

seg000:2933 retn

seg000:2933

seg000:2933 ; ----------------------------------

seg000:2934*word_0_2934 dw 0

seg000:2934*sub_0_292F endp

seg000:2936*byte_0_2936 db 0

Выходит, что как это ни парадоксально, но линейный адрес конца функции лежал посередине ячейки word_02934, где он, разумеется, не мог быть отображен. Описание этой ошибки IDA (которая должна быть устранена в последующих версиях), вероятно, не стоил бы такого пристального внимания, если бы эти таинственные исчезновения конца функций не случались так часто.

Это не нарушает работоспособности дизассемблера, но сбивает с толку пользователя и вызывает в нем мнимое подозрение, что в базе IDA серьезные сбои или ошибки, и что лучше ее удалить и начать проект заново, чем работать с ошибками, которые еще не известно чем могут обернуться в будущем.

На самом деле никаких поводов для беспокойства нет. Необходимо поправить адрес конца функции и можно продолжить работать дальше.

Операнд

Пояснения

ea

Любой линейный адрес, принадлежащий функции

end

Новый линейный адрес конца функции.

Return

Завершение

Пояснения

0

Вызов завершился не успешно. Функция не была создана

1

Вызов завершился Успешно

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]