逆向分析-数据结构

数据结构是计算机存储,组织数据的方式。在逆向分析时,确定数据结构以后,算法就很容易得到了。有些时候,事情也会反过来,即根据特定算法来判断数据结构。

1.局部变量

  局部变量是函数内部定义的一个变量,其作用域和生命周期局限于索在函数内。使用局部变量使程序模块化封装成为可能。从汇编的角度看,局部变量分配空间时通常会使用栈和寄存器。

  (1)利用栈存放局部变量

    局部变量在栈中进行分配,函数执行后会释放这些栈,程序用“sub esp,8” 语句为局部变量分配空间,用【ebp-xxx】寻址调用这些变量,而参数调用相对于ebp偏移量是正的,即[ebp+xxxx],因此在逆向分析时比较容易区分。

    编译器在优化模式时,通过esp寄存器直接对局部变量和参数进行寻址。当函数退出时,用“add esp,8” 指令平衡栈,以释放局部变量占用的内存。有些编译器(例如Delphi) 通过给esp加一个负值来进行内存的分配。

    另外,编译器可能会用“push reg”指令取代“sub esp,4”以节省字节的空间。

    局部变量的起始值是随机的,是其他函数执行后留在栈中的垃圾数据,因此需要对其进行初始化。初始化局部变量有俩种方法:

      一种是通过mov指令为变量赋值

      另一种是直接压入栈中

  (2)利用寄存器存放局部变量

    除了栈占用俩个寄存器,编译器会利用剩下的6个通用寄存器尽可能有效地存放局部变量,这样可以少产生代码,提高程序效率。如果寄存器不够用,编译就会将变量放入栈中。在进行逆向分析时要注意,局部变量的生存周期较短。必须及时确定当前寄存器的变量是哪个变量。

2.全局变量

   全局变量作用于整个程序,它一直存在,放在全局变量的内存区中。局部变量则存在于函数的栈区中,函数调用结束后便会消失。在大多程序中,常数一般在全局变量中,例如一些注册版标记,测试版标记等。

   在大多数情况下,在汇编代码中识别全局变量比其他结构中要容易得多。全局变量通常位于数据区块(.data)的一个固定地址处,当程序需要访问全局变量时,一般会用一个固定的硬编码地址直接对内存进行寻址。

   全局变量可以被同一文件中的所有函数修改,如果某个函数改变了全局变量的值,就能影响其他函数(相当于函数间的传递通道),因此,可以利用全局变量来传递参数和函数返回值等。全局变量在程序的整个执行过程中占用内存单元,而不像局域网变量那样需要时才开辟内存单元。

3.数组

    数组是相同数据类型的元素的集合,它们在内存中按顺序连续存放在一起。在汇编状态下访问数组一般是通过基址+变址 寻址实现的。

    在内存中,数组可存在于栈,数据段及动态内存中。本例中的a[]数组就保存在数据段中。

猜你喜欢

转载自www.cnblogs.com/godoforange/p/10368015.html