
- •Образ мышления – дизассемблер ida Pro том I описание функций встроенного языка ida Pro Аннотация
- •Введение. Об этой книге
- •Версии ida Pro
- •Кратное введение в дизассемблирование
- •Первые шаги с ida Pro
- •Язык скриптов ida Си
- •Консоль
- •Функции, объявление функций, аргументы функции, возвращаемое значение
- •Объявление переменных, типы переменных, преобразования переменных
- •Директивы
- •If, else;
- •Архитектура страничной памяти
- •Взаимодействие с физической памятью
- •Навигатор по функциям
- •Сводная таблица функций
- •Long Byte (long ea)
- •Long Word (long ea)
- •Long Dword (long ea)
- •Void PatchByte (long ea, long value)
- •Void PatchWord (long ea,long value)
- •Void PatchDword (long ea,long value)
- •Long NextAddr (long ea)
- •Long PrevAddr (long ea)
- •Long GetFlags(long ea)
- •Void SetFlags(long ea)
- •Long FindBinary(long ea,long flag,char str)
- •Сегменты и селекторы #Definition
- •Навигатор по функциям
- •Сводная таблица функций
- •Long mk_fp (long seg,long off)
- •Char atoa(long ea)
- •Success SegCreate(long startea,long endea,long base,long use32,long align,long comb)
- •Success SegDelete(long ea,long disable)
- •Success SegBounds(long ea,long startea,long endea,long disable)
- •Long SegStart(long ea)
- •Long SegEnd(long ea)
- •Long SegByName(char segname)
- •Long SegByBase(long base)
- •Success SegRename(long ea,char name)
- •Success SegAddrng(long ea,long use32)
- •Success SegAlign(long ea,long alignment)
- •Success SegComb(long segea,long comb)
- •Success SegClass(long ea,char class)
- •Success SegDefReg(long ea,char reg,long value)
- •Success SetSegmentType (long segea,long type)
- •Long GetSegmentAttr(long segea,long attr)
- •Char SegName(long ea)
- •Long FirstSeg()
- •Long NextSeg(long ea)
- •Void SetSelector(long sel,long value)
- •Void DelSelector(long sel)
- •Long AskSelector(long sel)
- •Long FindSelector(long val)
- •Элемемены #Defenition
- •Навигатор по функциям
- •Сводная таблица функций
- •Long ItemSize(long ea)
- •Long ItemEnd(long ea)
- •Long NextHead(long ea)
- •Long NextHead(long ea, long maxea)
- •Long PrevHead(long ea)
- •Long PrevHead(long ea, long minea)
- •Long NextNotTail(long ea)
- •Long PrevNotTail(long ea)
- •Типы элементов #Definition
- •Навигатор по функуциям
- •Сводная таблица функций
- •Success MakeByte(long ea)
- •1. Эксперимент
- •2. Эксперимент
- •3. Эксперимент
- •4. Эксперимент
- •Success MakeWord(long ea)
- •1. Эксперимент
- •2. Эксперимент
- •Success MakeDword(long ea)
- •1. Эксперимент
- •2. Эксперимент
- •Success MakeQword(long ea)
- •Success MakeFloat(long ea)
- •Success MakeDouble(long ea)
- •Success MakePackReal(long ea)
- •Success MakeTbyte(long ea)
- •Success MakeStr(long ea,long endea)
- •Success MakeArray(long ea,long nitems)
- •Success MakeAlign(long ea,long count,long align)
- •Long MakeCode (long ea)
- •Char GetMnem(long ea)
- •Void MakeUnkn(long ea,long expand)
- •1. Эксперимент
- •2. Эксперимент
- •3. Эксперимент
- •Long FindCode(long ea,long flag)
- •Long FindData(long ea,long flag)
- •Long FindExplored(long ea,long flag)
- •Long FindUnexplored(long ea,long flag)
- •Операнды #definition
- •Сводная таблица функций
- •Success OpBinary(long ea,int n)
- •Success OpOctal(long ea,int n)
- •Success OpDecimal(long ea,int n)
- •Success OpHex(long ea,int n)
- •Success OpChr(long ea,int n)
- •1. Эксперимент
- •2. Эксперимент
- •Success OpNumber(long ea,int n)
- •Success OpOff(long ea,int n,long base)
- •Success OpOffEx(long ea,int n,long reftype,long target,long base,long tdelta)
- •Success OpSeg(long ea,int n)
- •Success OpAlt(long ea,long n,char str)
- •Success OpSign(long ea,int n)
- •Success OpStkvar(long ea,int n)
- •Char GetOpnd(long ea,long n)
- •Char AltOp (long ea,long n)
- •Long GetOpType (long ea,long n)
- •LongGetOperandValue(long ea,long n)
- •Long FindVoid (long ea,long flag)
- •Long FindImmediate(long ea,long flag,long value)
- •Объекты #Definition
- •Сводная таблица функций
- •Success MakeName(long ea,char name)
- •Success MakeComm(long ea,char comment)
- •Success MakeRptCmt(long ea,char comment)
- •Void ExtLinA(long ea,long n,char line)
- •Void ExtLinB(long ea,long n,char line)
- •Void DelExtLnA(long ea,long n)
- •Void DelExtLnB(long ea,long n)
- •Void MakeVar(long ea)
- •Char Name(long ea)
- •Char GetTrueName(long ea)
- •Char Comment(long ea)
- •Char RptCmt(long ea)
- •Char LineA(long ea,long num)
- •Char LineB(long ea,long num)
- •Long LocByName(char name)
- •Функции #Definition
- •Сводная таблица функций
- •Success MakeFunction(long start,long end);
- •Success DelFunction(long ea);
- •Success SetFunctionEnd(long ea,long end);
- •Long NextFunction(long ea);
- •Long PrevFunction(long ea)
- •Long GetFunctionFlags(long ea);
- •Func_noret
- •Func_far
- •Func_lib
- •Func_frame
- •Func_userfar
- •Func_hidden
- •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 FindFuncEnd(long ea);
- •Long GetFrame(long ea);
- •Long GetFrameLvarSize(long ea);
- •Long GetFrameRegsSize(long ea);
- •Long GetFrameArgsSize(long ea);
- •Long GetFrameSize(long ea);
- •Long MakeFrame(long ea,long lvsize,long frregs,long argsize);
- •Long GetSpd(long ea);
- •Long GetSpDiff(long ea);
- •Success SetSpDiff(long ea,long delta);
- •Success MakeLocal(long start,long end,char location,char name)
- •Success SetReg (long ea,char reg,long value);
- •Long GetReg (long ea,char reg);
- •Перекрестные ссылки что такое перекрестные ссылки?
- •Alma mater
- •Архитектруа перекрестных ссылок
- •Хранение перекрестных ссылок
- •Void AddCodeXref(long From,long To,long flowtype);
- •Long DelCodeXref(long From,long To,int undef);
- •Long Rfirst (long From);
- •Long Rnext (long From,long current);
- •Long RfirstB (long To);
- •Long RnextB (long To,long current);
- •Long Rfirst0 (long From);
- •Long Rnext0 (long From,long current);
- •Long RfirstB0(long To);
- •Long RnextB0 (long To,long current);
- •Void add_dref(long From,long To,long drefType);
- •Dr_o - Смещение (Offset)
- •Dr_w Запись (Write)
- •Dr_r Чтение (Read)
- •Void del_dref(long From,long To);
- •Long Dfirst (long From);
- •Long Dnext (long From,long current);
- •Long DfirstB (long To);
- •Long DnextB (long To,long current);
- •Long XrefType(void);
- •XrefType()
- •Точки входа архитектура точек входа
- •Long GetEntryPointQty(void);
- •Success AddEntryPoint(long ordinal,long ea,char name,long makecode);
- •Long GetEntryOrdinal(long index);
- •Long GetEntryPoint(long ordinal)
- •Success RenameEntryPoint(long ordinal,char name);
- •Структуры alma mater
- •Архитектура структур в ida
- •Long GetStrucQty(void);
- •Long GetFirstStrucIdx(void);
- •Long GetLastStrucIdx(void);
- •Long GetNextStrucIdx(long index);
- •Long GetPrevStrucIdx(long index);
- •Long GetStrucId(long index);
- •Long GetStrucIdx(long id);
- •Long GetStrucIdByName(char name);
- •Char GetStrucName(long id);
- •Char GetStrucComment(long id,long repeatable);
- •Long GetStrucSize(long id);
- •Long GetMemberQty(long id);
- •Long GetStrucNextOff(long id,long offset);
- •Long GetStrucPrevOff(long id,long offset);
- •Long GetFirstMember(long id);
- •Long GetLastMember(long id);
- •Char GetMemberName(long id,long member_offset);
- •Char GetMemberComment(long id,long member_offset,long repeatable);
- •Long GetMemberSize(long id,long member_offset);
- •Long GetMemberStrId(long id,long member_offset);
- •Long AddStrucEx(long index,char name,long is_union);
- •Long IsUnion(long id);
- •IsUnion(
- •IsUnion(
- •Success DelStruc(long id);
- •Long SetStrucIdx(long id,long index);
- •0000 Struc_11 ends
- •0000 Union_13 ends
- •Long SetStrucName(long id,char name);
- •Long SetStrucComment(long id,char comment,long repeatable);
- •Long AddStrucMember(long id,char name,long offset,long flag, long typeid,long nbytes);
- •0001 MyMember4 db ?
- •Long DelStrucMember(long id,long member_offset);
- •0000 MyMember_1 dw 4 dup(?)
- •0009 Field_9 dw ?
- •Long SetMemberName(long id,long member_offset,char name);
- •Long SetMemberType(long id,long member_offset,long flag,long typeid,long nitems);
- •Long SetMemberComment(long id,long member_offset,char comment,long repeatable);
- •Перечисления alma mater
- •Архитектура перечислений
- •Long GetEnumQty(void);
- •Long GetnEnum(long idx);
- •Long GetEnumIdx(long enum_id);
- •Long GetEnum(char name);
- •Char GetEnumName(long enum_id);
- •Char GetEnumCmt(long enum_id,long repeatable)
- •Long GetEnumSize(long enum_id);
- •Long GetEnumFlag(long enum_id);
- •Long GetConstByName(char name);
- •Long GetConstValue(long const_id);
- •Char GetConstName(long const_id);
- •Char GetConstCmt(long const_id,long repeatable);
- •Long AddEnum(long idx,char name,long flag);
- •Void DelEnum(long enum_id);
- •Success SetEnumIdx(long enum_id,long idx);
- •Fixup alma mater
- •Long GetNextFixupEa(long ea);
- •Long GetPrevFixupEa(long ea);
- •Long GetFixupTgtType(long ea);
- •Long GetFixupTgtSel(long ea);
- •Long GetFixupTgtOff(long ea);
- •Long GetFixupTgtDispl(long ea);
- •Void SetFixup(long ea,long type,long targetsel,long targetoff,long displ);
- •Void DelFixup(long ea);
- •Void DeleteAll ();
- •Long AnalyseArea (long sEa,long eEa);
- •Void AutoMark (long ea,long queuetype);
- •Void AutoMark2 (long start,long end,long queuetype);
- •Long FindText (long ea,long flag,long y,long X,char str);
- •Char Demangle(char name, long disable_mask)
- •Взаимодействие с пользователем alma mater
- •Char AskStr (char defval,char prompt);
- •Char AskFile (long forsave,char mask,char prompt);
- •Long AskAddr (long defval,char prompt);
- •Long AskLong (long defval,char prompt);
- •Long AskSeg (long defval,char prompt);
- •Char AskIdent (char defval,char prompt);
- •Long AskYn (long defval,char prompt);
- •Void Message (char format,...);
- •Void Warning (char format,...);
- •Void Fatal (char format,...);
- •Long ScreenEa ();
- •Long SelStart ();
- •Long SelEnd ();
- •Success Jump (long ea);
- •Void Wait ();
- •Long AddHotkey(char hotkey, char idcfunc);
- •Success DelHotkey(char hotkey);
- •Маркировка позиций для быстрого перемещения методы
- •Void MarkPosition(long ea,long lnnum,long X,long y,long slot,char comment);
- •Long GetMarkedPos(long slot);
- •Char GetMarkComment(long slot);
- •Генерация выходных фАйлов
- •Int GenerateFile(long type, long file_handle, long ea1, long ea2, long flags);
- •Файловый ввод – вывод
- •Long fopen (char file,char mode);
- •Void fclose (long handle);
- •Long filelength (long handle);
- •Long fseek (long handle,long offset,long origin);
- •Long ftell (long handle);
- •Success loadfile (long handle,long pos,long ea,long size);
- •Success savefile (long handle,long pos,long ea,long size);
- •Long fgetc (long handle);
- •Long fputc (long byte,long handle);
- •Long fprintf (long handle,char format,...);
- •Long readshort (long handle,long mostfirst);
- •Long readlong (long handle,long mostfirst);
- •Long writeshort (long handle,long word,long mostfirst);
- •Long writelong (long handle,long dword,long mostfirst);
- •Char readstr (long handle);
- •Long writestr (long handle,char str);
- •Виртуальные массивы организация массивов
- •Long CreateArray(char name);
- •Long GetArrayId(char name);
- •Success RenameArray(long id,char newname);
- •Void DeleteArray(long id);
- •Success SetArrayLong(long id,long idx,long value);
- •Success SetArrayString(long id,long idx,char str);
- •Char or long GetArrayElement(long tag,long id,long idx);
- •Success DelArrayElement(long tag,long id,long idx);
- •Long GetFirstIndex(long tag,long id);
- •Long GetLastIndex(long tag,long id);
- •Long GetNextIndex(long tag,long id,long idx);
- •Long GetPrevIndex(long tag,long id,long idx)
- •Ассоциативные массивы об ассоциативных массивах
- •Архитектура ассоциативных массивов
- •Success SetHashLong(long id,char idx,long value);
- •Success SetHashString(long id,char idx,char value);
- •Long GetHashLong(long id,char idx);
- •Char GetHashString(long id,char idx);
- •Success DelHashElement(long id,char idx);
- •Char GetFirstHashKey(long id);
- •Char GetLastHashKey(long id);
- •Char GetNextHashKey(long id,char idx);
- •Char GetPrevHashKey(long id,char idx);
- •Операции с глобальными настройками методы
- •Настойки ida
- •Inf_version
- •Inf_procname
- •Inf_lflags
- •Inf_demnames
- •Inf_filetype
- •Inf_ostype
- •Inf_apptype
- •Inf_start_sp
- •Inf_start_af
- •Inf_start_ip
- •Inf_begin_ea
- •Inf_high_off
- •Inf_maxref
- •Inf_ascii_break
- •Inf_indent
- •Inf_comment
- •Inf_xrefnum
- •Inf_entab
- •Inf_voids
- •Inf_showauto
- •Inf_auto
- •Inf_border
- •Inf_null
- •Inf_showpref
- •Inf_prefseg
- •Inf_asmtype
- •Inf_baseaddr
- •Inf_xrefs
- •Inf_binpref
- •Inf_cmtflag
- •Sw_rptcmt
- •Sw_allcmt
- •Sw_nocmt
- •Inf_nametype
- •Inf_showbads
- •Inf_prefflag
- •Inf_packbase
- •Inf_asciiflags
- •Inf_listnames
- •Inf_start_ss
- •Inf_start_cs
- •Inf_main
- •Inf_short_dn
- •Inf_long_dn
- •Inf_datatypes
- •Inf_strtype
- •Success SetPrcsr (char processor);
- •Long Batch (long batch);
- •Char GetIdaDirectory ();
- •Char GetInputFile ();
- •Char substr (char str, long x1,long x2);
- •Long strstr (char str, char substr);
- •Long strlen (char str);
- •Char form (char format,...);
- •Long xtol (char str);
- •Char atoa (long ea);
- •Char ltoa (long n,long radix);
- •Long atol (char str);
- •Разное char Compile (char filename);
- •Void Exit (long code);
- •Long Exec (char command);
- •Приложения кратко о загрузке файлов опции командной строки
Навигатор по функциям
Созданием элементов всецело занимается ядро IDA; пользовательские скрипты хотя и имеют достаточные для «ручного» создания элементов привилегии, пользоваться этими привилегиями категорически не рекомендуется - даже незначительная ошибка способна вызвать непредсказуемое поведения дизассемблера вплоть до его полного «зависания».
Напротив, работая с уже созданными ядром элементами, пользователь может решить ряд задач, облегчающих дизассемблирование исследуемого файла. Пусть, например, требуется отыскать в тексте все условные переходы, стоящие после инструкции “test”, следующей за вызовом функции, иначе говоря, произвести поиск по шаблону “call *\test *,*\j? *” и вывести протокол отчета.
Это можно осуществить с помощью следующего листинга, сердцем которого является цикл, вызывающий функцию NextHead, последовательно переходящей от одной машинной инструкции к другой:
#include <ida.idc>
static main()
{
auto a;
a=0;
while(a!=BADADDR)
{
if (isCode(GetFlags(a)))
if( (GetMnem(a)=="call")
&& (GetMnem(NextHead(a,BADADDR))=="test")
&& (Byte(NextHead(NextHead(a,BADADDR),BADADDR)) > 0x6F)
&& (Byte(NextHead(NextHead(a,BADADDR),BADADDR)) < 0x80))
Message(">%s %4s %s\n>%s %4s %s,%s\n>%s %s %s\n>-------\n",
atoa(a),GetMnem(a),GetOpnd(a,0),
atoa(NextHead(a,BADADDR)),
GetMnem(NextHead(a,BADADDR)),
GetOpnd(NextHead(a,BADADDR),0),
GetOpnd(NextHead(a,BADADDR),1),
atoa(NextHead(NextHead(a,BADADDR),BADADDR)),
GetMnem(NextHead(NextHead(a,BADADDR),BADADDR)),
GetOpnd(NextHead(NextHead(a,BADADDR),BADADDR),0));
a=NextHead(a,BADADDR);
}
}
Результат его работы может быть следующим (в данном примере использовался файл first.exe –см. главу «Первые шаги с IDA Pro»)
>004010C0 call ostream::opfx(void)
>004010C5 test eax,eax
>004010C7 jz loc_4010E0
>---------------------------
>0040111F call ios::~ios(void)
>00401124 test [esp+4+arg_0],1
>00401129 jz loc_401132
>---------------------------
>004011BE call ios::~ios(void)
>004011C3 test [esp+4+arg_0],1
>004011C8 jz loc_4011D1
>---------------------------
...
Две функции NextHead и PrevHead обеспечивают прямую (от младших адресов к страшим) и обратную (от старших к младшим) трассировку элементов, возвращая линейный адрес головы следующего элемента или значение BADADDR если достигнут последний элемент в цепочке.
Это позволяет рассматривать анализируемый код не как поток бессвязных байт, а упорядоченную последовательность инструкций и данных. Разница между ними заключается в том, что поиск байт из интервала 0x70-0x7F в первом случае обнаружит не только все условные переходы, но и множество других инструкций и данных, частью которых является ячейка с таким значением, например, “DW 6675h”; “MOV AX, 74h”; напротив, во втором случае можно быть уверенным, что анализируется именно начало инструкции, а не нечто иное.
Разбивка потока байт на элементы позволяет решить и другую задачу – определить какой именно инструкции (или данным) принадлежит такой-то линейный адрес, т.е. по линейному адресу ячейки определить адрес головы элемента, которому эта ячейка принадлежит.
Манипулируя с флагами узнать это достаточно просто – достаточно проанализировать старшие 12 бит хвостовых атрибутов – флаги, расположенные по четному линейному адресу – содержат количество оставшихся байт до конца элемента, а флаги расположенные по нечетному линейному адресу – до его начала.
Реализация функции, возвращающей адрес головы элемента по любому принадлежащему элементу адресу может выглядеть так:
#include <idc.idc>
static MyGetHead(ea)
{
auto off,F;
F=GetFlags(ea);
if (!F) return -1; //Адрес не принадлежит ни одной ячейке
if (!(F & FF_TAIL)) //Это голова, возвращает ее адрес
return ea;
if (ea & 1) // ...нечетный линейный адрес
return (ea - (F >> 20));
// ...четный линейный адрес
return MyGetHead(ea-1);
}
Недостатком такого подхода является его потенциальная несовместимость с последующими версиями IDA Pro, но обойтись для решения проблемы одними лишь высокоуровневыми функциями, встроенными в IDA, не получается.
Задача могла бы быть решена при помощи вызовов функций ItemSize и ItemEnd, предназначенных для вычисления длины и адреса конца элемента соответственно, очевидно, адрес начала элемента равен ItemEnd(ea) – ItemSize(ea), но ItemSize возвращает не размер элемента, а смещение до его конца!
Ниже приведен другой вариант реализации функции MyGetItemHeadEA, вместо низкоуровневых манипуляций с флагами, использующий вызов PrevHead, однако, полностью отказаться от обращений к флагам не удается – приходится вызывать макрос isTail, определенный в файле <idc.idc> для проверки не является ли переданный адрес адресом головы элемента.
static MyGetItemHeadEA(ea)
{
if (!GetFlags(ea)) return –1; // ошибка
if (!isTail(GetFlags(ea)) // голова
return ea;
return PrevHead(ea,0);
}
Пара функций NextNotTail и PrevNotTail возвращают адрес следующего (предыдущего) элемента или бестипового байта. В полностью дизассемблированной программе не должно быть ни одного бестипового байта, но они могут присутствовать на промежуточной стадии анализа – все ячейки, на которые IDA не смогла распознать ни одной ссылки, она оставляет бестиповыми байтами, которые надлежит перевести в элементы кода или данных пользователю.