Возвращает линейный адрес начала следующей функции
long PrevFunction(long ea)
Возвращает линейный адрес начала предыдущей функции
long GetFunctionFlags(long ea);
Возвращает атрибуты функции
success SetFunctionFlags(long ea,long flags);
Устанавливает атрибуты функции
char GetFunctionName(long ea);
Возвращает имя функции
void SetFunctionCmt(long ea, char cmt, long repeatable);
Устанавливает комментарий функции (постоянный и повторянымый)
char GetFunctionCmt(long ea, long repeatable);
Возвращает комментарий функции
long ChooseFunction(char title);
Открывает диалоговое окно со списком всех функций
char GetFuncOffset(long ea);
Преобразует линейный адрес к строковому смещению от начала функции
long GetFrame(long ea);
Возвращает ID фрейма функции
long GetFrameLvarSize(long ea);
Возвращает размер фрейма функции
long GetFrameLvarSize(long ea);
Возвращает размер локальных переменных функции в байтах
long GetFrameArgsSize(long ea)
Возвращает размер аргументов функции в байтах
long GetFrameSize(long ea);
Возвращает полный размер стекового фрейма в байтах
long MakeFrame(long ea,long lvsize,long frregs,long argsize)
Создает фрейм функции или модифицирует уже существующий
long GetSpd(long ea);
Возвращает значение регистра SP в произвольной точке функции
long GetSpDiff(long ea);
Возвращает относительное изменение регистра SP указанной инструкцией
success SetSpDiff(long ea,long delta);
Корректирует изменение регистра SP, указанной командой
long FindFuncEnd(long ea)
Определяет линейный адрес конца функции
success MakeFunction(long start,long end);
Вызов MakeFunction позволяет создавать функцию. IDA не различает функций и процедур - в ее терминологии все это функции.
Каждая функция обладает принадлежащим ей непрерывным диапазонов адресов. В его границах может отслеживаться значения указателя стека, создаются ссылки на следующие инструкции и так далее. То есть ряд вызовов API работает исключительно с функциями.
Для создания функции достаточно только указать линейный адрес ее начала и конца. Функции могут создаваться только внутри сегментов и располагаться только с начала, а не середины машинных инструкций.
В то же время допускается в качестве конца задавать адрес, приходящейся на середину инструкции. IDA все равно его округлит до адреса конца предыдущей инструкции.
Например:
seg000:
002A
si, 211h
seg000:
002D
call
sub 0 DD
seg000:
0030
si, 2BAh
seg000:
0033
call
sub 0 DD
seg000:
0036
retn
MakeFunction(0x1002A,0x10037);
seg000:
002A
;
U T I N E
seg000:
002A
seg000:
002A
seg000:
002A
sub 0 2A
proc near
seg000:
002A
211h
seg000:
002D
call
0 DD
seg000:
0030
2BAh
seg000:
0033
call
0 DD
seg000:
0036
retn
seg000:
0036
sub 0 2A
endp
seg000:
0036
seg000:
0037
seg000:
0037
;
S U
U T I N E
При этом функции автоматически дается имя, вид которого зависит от настоек. По умолчанию оно предваряется префиксом sub (от subroutine - то есть процедура; забавно - ведь в терминологии IDA она называется функцией) и последующим смещением внутри сегмента.
Если вместо адреса конца функции указать константу BADADDR, то IDA попытается самостоятельно определить его.
Этот механизм довольно бесхитростен (концом функции считается инструкция ret или jmp) и довольно часто приводит к ошибкам и занижает адрес.
Разберем, например, такой случай. Путь некая функция имеет более одной точки выхода. В этом случае IDA часто принимает за конец функции первый встретившийся их них, а второй так и остается в «хвосте».
Это не упрек в несовершенстве алгоритма, а просто предостережения от всецелого доверия ему. В действительности же машинный анализ никогда не станет настолько совершенным, что бы полностью заменить человека.
Обратите внимание, что вызов MakeFunction провалится, если выделенная под функцию область будет помечена как undefined. Что и видно из следующего примера:
seg000:
002A
0BEh
seg000:
002B
seg000:
002C
seg000:
002D
0E8h
seg000:
002E
0ADh
seg000:
002F
seg000:
0030
0BEh
seg000:
0031
0BAh
seg000:
0032
seg000:
0033
0E8h
seg000:
0034
0A7h
seg000:
0035
seg000:
0036
0C3h
Message("0x%X \n",MakeFunction(0x1002A,0x10037));
Но в то же время, если в качестве адреса конца указать константу BADADDR, то функция будет успешно создана!
seg000:
002A
0BEh
seg000:
002B
seg000:
002C
seg000:
002D
0E8h
seg000:
002E
0ADh
seg000:
002F
seg000:
0030
0BEh
seg000:
0031
0BAh
seg000:
0032
seg000:
0033
0E8h
seg000:
0034
0A7h
seg000:
0035
seg000:
0036
0C3h
Message("0x%X \n",MakeFunction(0x1002A,-1));
seg000:002A
S U B R O U T I N E
seg000:002A seg000:002A seg000:002A sub 0 2A seg000:002A