IDA反汇编学习-转

IDA Pro是一款强大的反汇编软件,特有的IDA视图和交叉引用,可以方便理解程序逻辑和快速定位代码片断,以方便修改。

 ida-1

IDA视图

示例程序

下面会通过修改示例程序的输出字符串,来讲解如何使用IDA Pro。

#include

main()
{
    int n;
    scanf ("%d",&n);
    if (n > 0)
       printf("a > 0");  //后面会用IDA Pro把'a'改成'n'
    else
       printf("n < 0");
}

编译后的程序下载:demo

运行IDA Pro

运行IDAPro,并使用PE文件的方式打开示例的test.exe文件。IDAPro会新建一个工程,并开始反汇编程序。反汇编完成后,在[IDA-View]窗口中,可以看到程序逻辑的树形图,如下:

ida-2ida-3

树形图把条件分支清晰地显示出来了,绿色线连着的表示条件为true时执行的逻辑,而红色线表示条件为false时执行的逻辑。右下角有IDA视图的缩略图,在上面点击可以快速定位到视图的指定位置。IDA的工具栏有几个按钮对定位代码很重要,如下图所示:

 ida-4

从左到右分别是: Open exportswindow:打开导出窗口 Open import window:打开导入窗口*Open nameswindow:函数和参数的命名列表 *Open functionswindow:程序调用的所有函数窗口 *Open strings window:打开字符串显示窗口,会列出程序中的所有字符串,该窗口有助于你通过程序的运行输出逆向找出对应的代码片断。

定位代码片断

假设我们现在接到个任务,需修正程序,把输出“a > 0”修正为“n >0”。示例程序比较简单,直接看IDA视图我们就能找到需修改的代码片断,但实际处理时,可能程序有几m大,通过一个个看IDA视图已没法有效找到相关的执行代码片断,这时怎么办?使用字符串窗口和IDA强大的交叉引用! 点击工具栏的[Open stringswindows]按钮,可以看到如下的程序字符串:

ida-5

程序的字符串较少,可以很快地看到我们需要的字符串“a > 0”在数据段00403003位置。假如字符串多到已不能肉眼定位查找,因为字符串窗口是没有查找功能的,这时需要借助其他的文本编辑器,如notepad,editplus等。在字符串窗口内右键,选择菜单[copy]命令,会把字符串窗口的所有内容复制到剪贴板,再粘贴到记事本中查找就可以了。 双击字符串窗口的该行字符串,会跳转到IDA视图的00403003位置,如下图所示: 

ida-6 

该位置的字符串后面会注释有DATA XREF的字样,这是程序中引用到该字符串的代码片断的地址!在该行上右键,选择[Jump tocross reference...]项,会立即跳转到引用该字符串的代码片断位置!

ida-7

ida-8

最后定位的代码片断 上图显示的汇编指令即是我们要找的代码片断,这时点击[HexView-A]窗口,会切换到二进制浏览模式,并高亮了汇编代码的二进制格式指令,如下图所示:

ida-9

已找到需修改的代码片断,剩下的只需把a改成n。

修改程序文件

在IDA中,可以在[Hex View-A]窗口右键选择[Edit]来修改二进制指令。修改后通过右键选择[CommitChange]可以看到修改后的IDA视图。但需要注意的是,这种方式的修改并不会更新原始程序文件,实际只是修改了IDA的项目文件!IDA中只适合做一些验证性的修改,确保正确后再使用其他工具修改原始程序文件。在IDA中验证修改正确后,可以使用UltraEdit或HexWorkshop来修改原始程序文件。下面会以UltraEdit为例来说明如何修改。

ida-10 

用UltraEdit直接打开程序文件,UltraEdit会以16进制模式显示程序文件。UltraEdit显示的地址和IDA显示的地址是不同的,为了找到对应代码片断在UltraEdit中的实际地址,需要使用到UltraEdit的查找功能。在IDA中复制需修改的16进制模式显示的指令,在UltraEdit中打开查找,粘贴并查找该16进制字符串,UltrEdit会很快定位到该指令处,如下图所示:

ida-11

在IDA中使得右键来复制

ida-12

在UltraEdit打开查找功能

ida-13 

找到了UltraEdit的对应位置 现在我们要把“a > 0”改成“n >0”,a对应的ASCII码是61,而n对应的ASCII码是6E,只需把61改成6E就可以了,修改后保存。

ida-14

再次运行,可以看到结果已改变!

ida-15

示例只是修改了字符串,只需更改数据段内容就可以了,不用更改指令。假如需要更改指令,需要参考< ahref="http://courses.engr.illinois.edu/ece390/resources/opcodes.html#Main">8086指令操作表写出对应指今的16进制形式,再修改。

参考资料:
http://blog.csdn.net/liquanhai/article/details/5479141 
http://www.youtube.com/watch?v=Gl2S0YPRb9s 
http://www.woodmann.com/crackz/Tutorials/Flores1.htm 
http://courses.engr.illinois.edu/ece390/resources/opcodes.html
http://faydoc.tripod.com/cpu/conventions.htm
=============================================================
2   边写变学IDA

http://hi.baidu.com/onepc/blog/item/bb217259aa539a212834f0f1.html 源码



发觉若是没源码看着来还真的不知是啥意思。

PAGE:0001048EMyUnload       procnear              ; DATA XREF: DriverEntry+9 o
PAGE:0001048E   ;不过这个IDA怎么参数都没有显示?不是很明白。明明写有参数的。
PAGE:0001048Evar_8          = dword ptr -8
PAGE:0001048Evar_4          = dword ptr -4
PAGE:0001048Earg_0          = dword ptr 8
PAGE:0001048E
PAGE:0001048E                push   ebp
PAGE:0001048F                mov    ebp, esp
PAGE:00010491                sub    esp, 8
PAGE:00010494                mov    eax, [ebp+arg_0] ;ebp+8刚好是在参数1的位置。PAGE:00010497                mov    ecx, [eax+4] ;参数1偏移4的值传给ecx;不能动态调试只能猜了。
lkd> dt _DRIVER_OBJECT
nt!_DRIVER_OBJECT
   +0x000Type            : Int2B
   +0x002Size            : Int2B
   +0x004DeviceObject    : Ptr32 _DEVICE_OBJECT ;eax+4这里刚好是驱动对象里存放设备地址的地方
PAGE:0001049A                mov    [ebp+var_4], ecx ;传给变量1 ebp-4
;这句pDeviceObject=pDriverObject->DeviceObject;变量1是设备对象指针。下面[变量1=pDeviceObject]表示
PAGE:0001049D
PAGE:0001049Dloc_1049D:                             ; CODE XREF: MyUnload+40 j
PAGE:0001049D                cmp    [ebp+var_4], 0 ;变量与0比较
PAGE:000104A1                jz     short loc_104D0 ;即是退出
等于0时跳
push   

你可能感兴趣的:(ida)