常用的IDC函数

来源: 作者:选择作者 发布时间:2021-06-24 16:19:23
读取和修改数据的函数
下面的函数可用于访问数据库中的各个字节,字和双字

long Byte(long addr),从虚拟地址addr处读取一个字节值
long Word(long addr),从虚拟地址addr处读取一个字(2个字节)值
long Dword(long addr),从虚拟地址addr处读取一个双字(4个字节)值
long PatchByte(long addr,long val),设置虚拟地址addr处的一个字节值
long PatchWord(long addr,long val),设置虚拟地址addr处的一个字值
long PatchDword(long addr,long val),设置虚拟地址addr处读取一个双字值
void idLoaded(long addr),如果addr包含有效数据,则返回1,否则返回0
在读取和写入数据库时,这里的每一个函数都考虑到了当前处理器模块的字节顺序(小端或者大端)。例如,调用PatchByte(0x401010,0x1234)将使用字节值0x34(0x1234的低位字节)修改0x401010位置。如果在用Byte,Word和Dword读取数据库时提供了一个无效的地址,他们将分别返回值0xFF,0xFFFF和0xFFFFFFFF。因为你没有办法将这些错误值与存储在数据库中的合法值分开来,因此,在尝试从数据库中的某个地址读取数据之前,可以调用isLoaded函数,

用户交互函数
void Message(string fromat,……),在输出窗口打印一条格式化消息,这个函数类似于C语言的printf函数,并接受printf风格的格式化字符串
void printf(……),在输出窗口中打印每个参数的字符串表示形式
void Warning(string fromat,……),在对话框中显示一条格式化消息
string AskStr(string default,string prompt),显示一个输入框,要求用户输入一个字符串值。如果操作成功,则返回用户的字符串;如果对话框被取消,则返回0
string AskFile(long doSave,string mask,String prompt),显示一个文件选择对话框,以简化选择文件的任务。你可以创建新文件保存数据(doSave=1),或选择现有的文件读取数据(doSave=0)。你可以根据mask(如*.*或*.idc)过滤显示的文件列表。如果操作成功,则返回选定文件的名称;如果对话框被取消,则返回0
long AskYN(long deafult,string prompt),用一个答案为“是”或“否”的问题提示用户,如初一个默认的答案(1为是,0为否,-1为取消)。返回值是一个表示选定答案的整数。
long ScreenEA(),返回当前光标所在位置的虚拟地址
bool Jump(long addr),跳转到反汇编窗口的指定地址
因为idc没有任何调试工具,可将Message作为主要调试工具,AskXXX函数用于处理更加专用的输入,如整数输入。如果希望创建一个根据光标位置调整其行为的脚本,这时,ScreenEA的函数就非常有用。如果脚本需要将用户的注意力转移到反汇编代码的清单中的某个位置,也需要用到Jump函数

字符串操纵函数
简单的字符串赋值和拼接操作可以直接通过idc 基本运算符实现,其它更加复杂操作需要用到以下函数:

string form(string format,…………)preIDA5.6,返回一个新字符串,该字符串根据所提供的格式化字符串和值进行格式化。这个函数基本等同于c中的sprintf函数
string sprintf(string format,……)IDA5.6+,在IDA5.6中,sprintf用于替代form
long atol(string val),将十进制val转换成对应的整数值
long xtol(string val),将十六进制val(可选择以0x开头)转换成对应的整数值
string Itoa(long val,long radix),以指定的radix(2,8,10或16)返回val的字符串值
long ord(string str),返回单字符字符串ch的ASCII值
long strlen(string str),返回所提供字符串的长度
long strstr(string str,string substr),返回str中substr 的索引,如果没有发现子字符串,则返回-1
string substr(string str,long start,long end),返回包含str中由start到end-1位置的字符的子字符串,如果使用分片(IAD5.6以及更高的版本),此函数等同于str[start:end]
IDC没有任何字符数据类型,它也不支持任何数组语法,如果想要遍历字符串的每个字符,必须把字符串中的每个字符当成连续的单字符子字符串处理

文件输入/输出函数
已经讨论了AskFile函数要求用户输入文件名,但是AskFile仅仅返回一个包含文件名的字符串值

long fopen(string filename,string mode),返回一个整数文件句柄(如果发生错误,则返回0),供所以IDC文件输入/输出函数使用。mode参数与C语言的fopen函数使用的模式(r表示读取,w表示写入,等等)
void fclose(long handle),关闭fopen中文件句柄指定的文件
long filelength(long handle),返回指定文件的长度,如果发生错误,则返回-1
long fgetc(long handle),从给定文件中读取一个字节,如果发生错误,则返回-1
long fputc(long val,long handle),写入一个字节到给定文件中。如果操作成功,则返回0;如果发生错误,则返回-1
long fprintf(long handle ,string fromat,……)将一个格式化字符串写入到给定文件中
long writestr(long handle ,string str),将指定的字符串写入到给定文件中
string/long readstr(long handle),从给定文件夹中读取一个字符串,这个函数读取到下一个换行符为止的所有字符(包括非ASCII字符),包括换行符本身(ASCII 0xA)。如果操作成功,则返回字符串;如果读取到文件结尾,则返回-1
long writelong(long handle,long val,long bigendian),使用大端(bigendian=1)或小端(bigendian=0)字节顺序将一个4字节整数写入到给定文件
long readlong(long handle,long bigendian),使用大端(bigendian=1)或小端(bigendian=0)字节顺序从给定的文件读取一个4字节整数
long writeshort(long handle,long val,long bigendian),使用 大端(bigendian=1)或小端(bigendian=0)字节顺序将一个2字节整数写入到给定文件
long readshort(long handle,long bigendian),使用大端(bigendian=1)或小端(bigendian=0)字节顺序从给定的文件读取一个2字节整数
bool loadfile(long handle,long pos ,long addr,long length),从给定文件的pos位置读取length数量的字节,并将这些字节写入到以addr地址开头的数据库中
bool savefile(long handle,long pos,long addr,long length),将以addr数据库地址开头的length数量的字节写入给定文件的pos位置

操纵数据库名称
下面的IDC函数用于处理IDA数据库中已命名的位置:

string Name(long addr),返回与给定地址有关的名称,如果该位置没有名称,则返回空字符串,如果名称被标记为局部名称,这个函数并不返回用户定义的名称
string NameEx(long from,long addr),返回与addr有关的名称,如果该位置没有名称,则返回空字符串,如果from是一个同样包含addr 的函数中的地址,则这个函数返回用户定义的局部名称
bool MakeNameEx(long addr,string name,long flags),将给定的名称分配给给定的地址。该名称使用flags为掩码中指定的属性创建而成。这些标志在帮助系统中的MakeNameEx文档中有记载描述,可用于指定各种属性,如名称是局部名称还是公共名称,名称是否应在名称窗口中列出
long LocByName(string name),返回一个位置(名称已给定)的地址。如果数据库中没有这个名称,则返回BADADDR(-1)
long LocByNameEx(long funcaddr,string localname),在包含funcaddr 的函数中搜索给定的局部名称,如果给定的函数中没有这个名称,则返回BADADDR(-1)

处理函数的函数
许多脚本专用于分析数据库中的函数。IDA为经过反汇编的函数分配大量属性,如函数局部变量区域的大小,函数的参数在运行时栈上的大小。下面的IDC函数可用于访问与数据库中的函数有关信息

long GetFunctionAttr(long addr,long attrib),返回包含给定地址的函数的被请求的属性。例如,要查找一个函数的结束地址,可以使用GetFunctionAttr( addr,FUNCATTR_END)
string GetFunctionName(long addr),返回包含给定地址的函数的名称,如果给定的地址并不属于一个函数,则返回一个空字符串
long NextFunction(long addr),返回给定地址后的下一个函数的起始地址,如果数据库中给地地址后没有其他函数,则返回-1
long PrevFunciton(long addr),返回给定地址之前距离最近的函数的起始地址,如果在给定函数之前没有函数,则返回-1
根据函数的名称,使用LocByName 函数查找该函数的起始地址

代码交叉引用函数
long Rfirst(long from),返回给定地址向其转交控制权的第一个位置。如果给定的地址没有引用其他地址,则返回BADADDR(-1)
long Rnext(long from,long current),如果current已经在前一次调用Rfirst或Rnext时返回,则返回给定地址(from)转交控制权的下一个位置,如果没有其他交叉引用存在,则返回BADADDR
long XrefType(),返回一个常量,说明某个交叉引用查询函数(如Rfirst)返回的最后一个交叉引用的类型。对于代码交叉引用,这些常量包括fl_CN(近调用),fl_CF(远调用),fl_JN(近跳转),fl_JF(远跳转)和fl_F(普通顺序流)
long RfirstB(long to),返回转交控制权到给定地址的第一个位置。如果不存在对给定地址的交叉引用,则返回BADADDR(-1)
long RnextB(long to,long current),如果current已经在前一次调用RfirstB或RnextB时返回,则返回下一个转交控制权到给定地址(to)的位置。如果不存在其他对给定位置的交叉引用,则返回BADADDR(-1)
每次调用一个交叉引用函数,IDA都会设置一个内部IDC状态变量,指出返回的最后一个交叉引用的类型,如果需要知道你收到的交叉引用类型,那么在调用其他交叉引用查询函数之前,必须调用XrefType函数

数据交叉引用函数
访问数据交叉引用信息的函数与访问代码交叉引用信息的函数非常相似:

long Dfirst(long from),返回给定地址引用一个数据值的第一个位置,如果给定地址没有引用其他地址,则返回BADADDR(-1)
long Dnext(long from,long current),如果current已经在前一次调用Dfirst或Dnext时返回,则返回给定地址(from)向其引用一个数据值的下一个位置。如果没有其他交叉引用存在,则返回BADADDR
long XrefType(),返回一个 常量,说明某个交叉引用查询函数(如Dfirst)返回的最后一个交叉引用的类型,对于数据交叉引用,这些常量包括dr_0(提供的偏移量),dr_w(数据写入)和dr_R(数据读取)
long DnextB(long to,long current),如果current已经在前一次调用DfirstB或DnextB时返回,则返回将给定地址(to)作为数据引用的下一次位置。如果没有其他对给定地址的交叉引用存在,则返回BADADDR
和代码交叉引用一样,如果需要知道你收到的交叉引用的类型,那么在调用另一个交叉引用查询函数之前,必须调用XrefType函数

数据库操纵函数
大量函数用于对数据库的内容进行格式化:

void MakeUnkn(long addr,long flags),取消位于指定位置的项的定义。这里的标志指出是否也取消随后的项的定义,以及是否删除任何与取消定义的项有关的名称,相关函数MakeUnknown允许你取消大块数据的定义
long MakeCode(long addr),将位于指定地址的字节换成一条指令,如果操作成功,则返回指令的长度,否则返回0
bool MakeByte(long addr),将位于指定地址的项目转换成一个数据字节。类似的函数还包括MakeWord和MakeDword
bool MakeComm(long addr,string comment),在给定的地址添加一条常规注释
bool MakeFunction(long begin ,long end),将由begin到end的指令转换成一个函数。如果end 被指定为BADADDR(-1),IDA会尝试通过定位函数的返回指令,来自动确定该函数的结束地址
bool MakeStr(long begin ,long end),创建一个当前字符串(由GetStringType返回)类型的字符串,涵盖由begin到end-1之间的所有字节,如果end被指定为BADADDR,IDA会尝试自动确定字符串的结束位置
还有许多MakeXXX函数可提供上述函数操作

数据库搜索函数
long FindCode(long addr,long flags),从给定的地址搜索一条指令
long FindData(long addr,long flags),从给定的地址搜索一个数据项
long FindBinary(long addr,long flags,string binary),从给定的地址搜索一个字节序列,字符串binary指定一个十六进制字节序列值。如果没有设置SEARCH_CASE,且一个字节值指定了一个大写或小写ASCII字母,则搜索仍然会匹配对应的互补值。例如.“41 42”将匹配“61 62”(和“61 42”),除非你设置SEARCH_CASE
long FindText(long addr,long flags ,long row,long column,string text),在给定的地址,从给定行(row)的给定列搜索字符串text,注意,某个给定地址的反汇编文本可能会跨越几行,因此,你需要指定搜索从哪一行开始的
注意:SEARCH_CASE并未定义搜索的方向,根据SEACH_DOWN标志,其方向可能向上也可能向下,此外,如果没有设置SEACH_NEXT,且addr位置的项与搜索条件匹配,则FindXXX函数很可能会返回addr参数传递给该函数的地址

反汇编行组件
string GetDisasm(long addr),返回给定地址的反汇编文本,返回的文本包括任何注释,但不包括地址信息
string GetMnem(long addr),返回位于地址的指令助记符部分
string GetOpnd(long addr,long opnum),返回指定地址的指定操作数的文本形式。IDA以零为起始编号,从左向右对操作数进行编号
long GetOpType(long addr,long opnum),返回一个证书,指出给定地址的给定操作数的类型
long GetOperandValue(long addr,long opnum),返回与给定地址的给定操作数有关的整数值,返回值的性质取决于GetOpType指定的给定操作数的类型
string CommentEx(long addr,long type),返回给定地址处的注释文本。如果type为0,则返回常规注释文本;如果type为1,则返回可重复注释的文本。如果给定地址处没有注释,则返回一个空字符串。