0.IDA-基本操作
打开IDA,拖拽一个EXE文件进去,首先会弹出如下窗口:
Kernel option1、Kernel option2、Processor option这三个选项会控制反汇编引擎的工作状态,一般按默认即可,大多数情况下,分析选项的默认值在准确性和方便性之间提供一个折中参数,如果IDA分析出有问题的代码时,把Kernel option1中的选项Make final analysis pass选项关闭是很好的方法:
在某些情况下,一些代码因不在预计的位置而不被确认,尝试把Kernel option2中的Coagulate data segments in the final pass选上是有帮助的(注意这里是选上)
IDA打开文件时,默认是处于图形化模式的,如果要切换到代码模式,执行右键菜单“Text view”
点了之后到了代码模式,可通过可视化菜单标志切换,也可以通过系统菜单View---Open subviews---Disassembly来重新打开图形化模式,而且每点一次出现一个!
合理配置IDA文件,可以大大提高工作效率, Windows图形界面的主程序是idag.exe,可通过菜单Opeions来配置IDA,注意的是这种配置只对当前的项目有效,新建一个项目时,会恢复成默认配置,改变默认配置必须用UE等修改ida.cfg等配置文件(在cfg目录下)
IDA默认是不显示中文字符串的,只需要在ida.cfg中搜索AsciiStringChars,将cp866 version这段注释掉,恢复full version这段即可显示中文
IDA同样可以在反汇编代码后面输入注释,在窗口右边空白处单击鼠标右键,一种是Enter comment(快捷键是;和OD一样),另一种是Enter repeatable comment(快捷键是shift+;)
前一种输入的注释只在该处出现,后一种注释,会在所有交叉参考处出现
交叉参考:
快捷键是X键,通过交叉参考(XREF)可以知道指令代码相互调用的关系,如下图:
表示该调用地址是40112B,j表示跳转,其他一些符号:"o"表示偏移值(offset),"p"表示子程序,双击;后的内容或按回车键就可以跳到调用该处的地方,
注意的是直接在前面的代码上双击或回车是无效的,按回车时,提示窗口还会提示"Command "JumpEnter" failed"必须在后点双击或回车才能跳转
在loc_401165字符上按X键,将打开交叉参考窗口,如图所示:
参考重命名:
Renaming of reference 是IDA的一个极好功能,增加了代码的可读性,如下是WndClass的开始处,IDA默认用local_401120命名,但loc_401120这个字符没有多大意义,
若加注释,只有这一行有意义,但用参考重命名功能便可把所有参考点一次改动,在loc_401120上单击鼠标右键,弹出右键菜单,在菜单上选择重命名"Rename"
或按N键,打开Rename Address对话框,如下:
标签的用法
右键菜单"Jump/Mark position"打开"标记当前位置"功能,如下:
为这个标记(当前光标位置)加上标记,"WndProc"便是需要返回的位置,当离开这个标记而返回时,可以在菜单"Jump/Jump to marked position"中或按"Ctrl+M"键执行"跳转到标记位置"功能,选择返回的标签,双击就转到指定代码处:
进制的转换
IDA可以提供多种进制显示,先把光标移到需要转换的数据上,单击工具栏上的#按钮,即可转换成所需要的进制:
Toggle leading zeroes功能是用0填补数据前的空位
代码和数据转换
很多工具在反汇编时可能无法正确区分数据和代码,IDA也不例外,有些程序就是利用这点来对抗静态反汇编的,IDA的交互性使得用户可以把某段十六进制数指定为代码或数据,
那么如果确认某段十六进制数据是一段指令,只要把光标移到其第一个字节的偏移位置,执行菜单命令"Edit/Code"或按C键,按P键可以把某段代码定义为子程序,参数调用会列出,
若要取消定义,执行菜单命令Edit/Undefine或按U键,数据重新以16进制数据显示:
在数据行按D键,数据类型会在db、dw与dd间转换,而执行菜单"Options/Setup data types"可以设置更多的数据类型
字符串
编程语言不同造成字符串也有不同的格式,如以"\0"结尾的C字符串,以"$"结尾的DOS字符串等,IDA支持所有的格式,如果确信某段十六进制是个字符串,只要把光标移到其第一个字符的偏移位置,执行菜单命令"Edit/Strings/ASCII"或按A键
按A默认是C字符串,也可以在菜单"Options/ASCII string style"中设置其他字符串格式为默认值
结构体
IDA会根据文件的类型自动加载相应的类型库存,在工具栏上单击T按钮,打开加载类型库窗口(Loaded Type Libraries):
选择好类型库,就可查看内置的结构体数据结构了,选择菜单"View/Open subviews/Structures'或单击工具栏上的
打开结构体管理窗口,按Insert键,在弹出的窗口中单击"Add Standard Structure",打开添加标准结构库窗口,查找需要的结构体,然后就可以正常使用这些库了
枚举类型
可以在反汇编时用IDA去动态的定义与操作枚举类型(Enumerated Types),用以下的街头简单代码生成一个release,再用IDA加载:
- #include <stdio.h>
- int main(void)
- {
- enum weekday{MONDAY, TUESDAY, WEDNESDAY, THUSDAY,FRIDAY,SUTURDAY,SUNDAY};
- printf("%d,%d,%d,%d,%d,%d,%d", MONDAY, TUESDAY, WEDNESDAY, THUSDAY,FRIDAY,SUTURDAY,SUNDAY);
- return 0;
- }
加载后,看下printf函数部分:
下面演示下如何用枚举类型来表示这些数字,执行菜单"View/Open subviews/Enumerations"或直接单击工具栏上的En按钮打开枚举窗口,按Insert插入一个新的枚举类型,取名weekday.在新建的weekday枚举类型中按N键添加枚举成员,0对应MONDAY,1对应TUESDAY,依次类推:
回到反汇编代码窗口,把光标移到需要重新定义的数据处,执行"Edit/Operand types/Enum member"或直接按M键转换成指定的枚举成员,
再按M就会恢复原有的代码