IDA-逆向分析-反汇编导航-双击导航-跳转地址-调用约定-局部变量-栈视图-搜索-工具教程

本文围绕IDA逆向分析展开,介绍了反汇编导航方法,如双击导航、跳转到地址及使用导航历史记录;阐述了栈帧相关知识,包括调用约定、局部变量布局和IDA栈视图;还讲解了搜索功能,有文本搜索和二进制搜索,为逆向分析提供了实用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.反汇编导航

1.1.双击导航

多数情况下,要导航到你感兴趣的位置,只需双击鼠标即可。双击任何一个符号,IDA将跳转到相应的位置。通常,交叉引用被格式化成一个名称和一个十六进制偏移值。如下图所示,loc_40134E右边的交叉引用引用了sub_4012E4之前的4D16或7710字节的位置。双击交叉引用文本,IDA将跳转到引用位置(本例中为00401331)。
在这里插入图片描述
如果窗口中的一个十六进制值是二进制文件中的一个合法虚拟地址,那么,双击这个值,反汇编窗口将显示你选择的虚拟地址。

1.2.跳转到地址

有时候,你清楚地知道你想要导航的目的地址,但反汇编窗口中并没有可供双击导航的名称。在这种情况下,你有几种选项供选择。第一个是最基本的选项,即使用反汇编窗口滚动条上下滚动窗口,直到看到想要访问的地址。通常,只有知道要导航到的目标地址的虚拟地址时,才能采用这个选项,因为反汇编窗口是按虚拟地址逐行显示的。如果你仅仅知道一个已命名的位置,如一个名为foobar的子程序,那么,通过滚动条找目的地址就无异于大海捞针。这时,你可以选择对函数窗口按字母排序,滚动到想要的名称,然后再双击该名称。第三个选项是使用IDA的Search菜单提供的搜索功能。通常,在要求IDA搜索前需要指定一些搜索标准。如果你搜索的是一个已知的位置,使用该选项有点小题大做。
在这里插入图片描述
使用Jump>Jump to Address命令或在处于活动状态的反汇编窗口中按下热键G,均可以打开Jump to Address对话框。

1.3.导航历史记录

工具栏上还有两个更有用的导航按钮,如下图所示,它们的作用与浏览器中的前进和后退按钮类似。
在这里插入图片描述

2.栈帧

栈帧是在程序的运行时栈中分配的内存块,专门用于特定的函数调用。程序员通常会将可执行语句分组,划分成叫做函数(也称过程、子例程或方法)的单元。在将控制权转交给函数之前,编译器会插入代码,将函数参数放入栈帧内,并分配足够的内存,以保存函数的局部变量。

2.1.调用约定

x86体系结构的许多C编译器使用的默认调用约定叫做C调用约定。如果默认的调用约定被重写,则C/C++程序中常用的_cdecl修饰符会迫使编译器利用C调用约定。cdecl调用约定规定:调用方按从右到左的顺序将函数参数放入栈中,在被调用的函数完成其操作时,调用方(而不是被调用方)负责从栈中清除参数。
为避免标准一词引起混淆,在本书的剩余部分,我们将这种调用约定称为stdcall调用约定。和cdecl调用约定一样,stdcall调用约定按从右到左的顺序将函数参数放在程序栈上。使用stdcall调用约定的区别在于:函数结束执行时,应由被调用的函数负责删除栈中的函数参数。根据惯例,微软对所有由共享库(DLL)文件输出的参数数量固定的函数使用stdcall约定。如果你正尝试为某个共享库组件生成函数原型或与二进制兼容的替代者,请一定记住这一点。
fastcall约定是stdcall约定的一个变体,它向CPU寄存器(而非程序栈)最多传递两个参数。Microsoft Visual C/C++ 和GNU gcc/g++(3.4及更低版本)编译器能够识别函数声明中的fastcall修饰符。如果指定使用fastcall约定,则传递给函数的前两个参数将分别位于ECX和EDX寄存器中。剩余的其他参数则以类似于stdcall约定的方式从右到左放入栈上。同样与stdcall约定类似的是,在返回其调用方时,fastcall函数负责从栈中删除参数。
C++语言标准并未规定应如何向非静态成员函数传递this指针,因此,不同编译器使用不同的技巧来传递this指针,这点也就不足为奇了。Microsoft Visual C++提供thiscall调用约定,它将this传递到ECX寄存器中,并且和在stdcall中一样,它要求非静态成员函数清除栈中的参数。GNU g++编译器将this看成是任何非静态成员函数的第一个隐含参数,而在所有其他方面与使用cdecl约定相同。

2.2.局部变量布局

编译器的第一个任务是,计算出函数的局部变量所需的空间。编译器的第二个任务,则是确定这些变量是否可在CPU寄存器中分配,或者它们是否必须在程序栈上分配。
在这里插入图片描述
其中的“偏移量”栏显示的是引用栈帧中的任何局部变量或参数所需的基址+位移地址:
在这里插入图片描述
生成利用栈指针计算所有变量引用的函数需要编译器做更多工作,因为栈指针会频繁变化,编译器必须确保它在引用栈帧中的任何变量时始终使用了正确的偏移量。
由于专门使用一个寄存器作为帧指针,并通过一段代码在函数入口点配置了帧指针,因此,计算局部变量偏移量的工作变得更加轻松。在x86程序中,EBP(extended base pointer,扩展基址指针)寄存器通常专门用作栈帧指针。默认情况下,多数编译器会生成代码以使用帧指针,而无视规定应使用栈指针的选项。
在这里插入图片描述
使用一个专用的帧指针,所有变量相对于帧指针寄存器的偏移量都可以计算出来。许多时候(尽管并无要求),正偏移量用于访问函数参数,而负偏移量则用于访问局部变量。使用专用的帧指针,我们可以自由更改栈指针,而不至影响帧内其他变量的偏移量。常用的尾声代码。
在这里插入图片描述

2.3.IDA 栈视图

确定某函数是否使用一个专用的帧指针(例如,通过识别push ebp/mov ebp, esp序列),以及识别对函数栈帧内变量的所有内存引用。
在这里插入图片描述
IDA提供了一个摘要栈视图,列出了栈帧内被直接引用的每一个变量,以及变量的大小和它们与帧指针的偏移距离。IDA会根据变量相对于被保存的返回地址的位置,为变量取名。局部变量位于被保存的返回地址之上,而函数参数则位于被保存的返回地址之下。局部变量名称以var_为前缀,后面跟一个表示变量与被保存的帧指针之间距离(以字节为单位)的十六进制后缀。在本例中,局部变量var_C是一个4字节(dword)变量,它位于所保存的帧指针之上,距离为12字节([ebp-oCh])。函数参数名则以arg_为前缀,后面跟一个表示其与最顶端的参数之间的相对距离的十六进制后缀。因此,最顶端的4字节参数名为arg_0,而随后的参数则分别为arg_4、arg_8、arg_C,以此类推。临时变量保存在内存中,而不是寄存器上。IDA只会为那些在函数中直接引用的栈变量自动生成名称。IDA得出推断,arg_4是一个4字节变量,并将其标记如此(db定义一个存储字节,dw定义两个存储字节,也叫做字;dd定义4个存储字节,也叫做双字)。

3.搜索

3.1.文本搜索

IDA文本搜索相当于对反汇编列表窗口进行子字符串搜索。通过Search>Text(热键:ALT+T)命令启动文本搜索。
在这里插入图片描述

3.2.二进制搜索

如果需要搜索特定的二进制内容,如已知的字节序列,这时就不能使用文本搜索功能,而应使用IDA的二进制搜索工具。文本搜索针对反汇编窗口进行搜索,但是,你可以认为二进制搜索仅搜索十六进制视图窗口。根据你指定搜索字符串的方式,你可以搜索十六进制或ASCII字符串。使用Search>Sequence of Bytes(搜索>字节序列)或ALT+B即可启动二进制搜索。
在这里插入图片描述

4.作者答疑

− − − − − − − − 插 ∗ 件 ∗ 开 ∗ 发 − − − − − − − − p h 99 o n e = 1 8 9 2 8 8 9 9 7 2 8 W e i 88 X i n = 1 8 9 2 8 8 9 9 7 2 8 Q 99 Q = 3 1 2 1 1 7 2 7 1 --------插*件*开*发--------\\ ph99one= \begin{matrix} 1 & 8 &9 & 2 &8 & 8 &9 & 9 &7 & 2 &8 \end{matrix}\\ Wei88Xin= \begin{matrix} 1 & 8 &9 & 2 &8 & 8 &9 & 9 &7 & 2 &8 \end{matrix}\\ Q99Q= \begin{matrix} 3 & 1 &2 & 1 &1 & 7 &2 & 7 &1 \end{matrix} ph99one=18928899728Wei88Xin=18928899728Q99Q=312117271

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值