逆向分析技术

1.启动函数

功能:检索新进程命令指针,环境指针,全局变量初始化,内存堆栈初始化

比如:
GetCommandLineA 命令指针
GetStartupInfoA 启动信息
GetModuleHandleA 执行文件基地址

编译器自动加入的代码:

00401020 >/$  55            push    ebp
00401021  |.  8BEC          mov     ebp, esp
00401023  |.  6A FF         push    -1
00401025  |.  68 A0504000   push    004050A0
0040102A  |.  68 7C1C4000   push    00401C7C                         ;  SE 处理程序安装
0040102F  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
00401035  |.  50            push    eax
00401036  |.  64:8925 00000>mov     dword ptr fs:[0], esp
0040103D  |.  83EC 10       sub     esp, 10
00401040  |.  53            push    ebx
00401041  |.  56            push    esi

2.函数及其参数

反编译分析时,将注意力集中在函数的识别以及参数的传递上
函数多以call(保存函数返回信息)地址为跳转 也有动态计算或者寄存器传地址

函数的参数传递方式有三种:

堆栈方式

寄存器方式

全局变量

3.函数的返回值

1. return操作符返回值

逆向分析技术
od遇到了一个bug 就是不是每个指令都会下到int3断点 从而debug时F8单步有一些代码是一起执行的。(这让想起了原子操作)

一般的返回值时存放在eax寄存器中,如果超过了容量则会放到edx寄存器中。

2.通过参数按照传引用的方式返回

注意ds和ss的区别 然后一般通过引用来传值需要使用变量的地址,在调用某个函数时再把变量的地址传给函数。
逆向分析技术

3.通过全局变量返回

4.数据结构

逆向算法和数据结构

1.局部变量

1.堆栈分配局部变量
在堆栈中进行分配,分配完在释放。或者直接存放在寄存器中。
分配[ebp-xxx]
访问[ebp+xxx]

初始化局部变量的两种方法:
mov [ebp-xxx],5

push 5

2.利用寄存器存放局部变量

堆栈占用两个寄存器,编译器会利用剩下的6个通用寄存器尽可能的有效存放局部变量。寄存器不够时才会使用堆栈,且局部变量的生命周期比较短,需要确定时那个寄存器存放的那个变量。

2.全局变量

全局变量存放在内存区,静态pe的.data的可读写区域的固定地址上。访问时即访问硬编码的特定地址即可。
(静态变量 static 作用范围有限)
如果是常量 则在只可读区域内。

3.数组

数组保存在.data段中 使用基地址+偏移来寻址

4.虚函数

虚函数实在运行时刻定义的函数,地址无法在编译时确定(在即将调用时确定)
对所有虚函数的引用常放在一个专用的数组虚函数表VTBL里,

逆向分析技术
这里使用4050A0存放着虚表(虚表里有两个方法的地址 利用两次间接寻址找到虚函数的正确地址)
逆向分析技术

每太搞懂右边的流程,为什么有个失败的流程 xor esi,esi

还有为什么每次任然需要新建一个this指针( mov ecx,esi )ecx来传递参数给成员函数

(更好奇的是如何复原ida里面的函数流程)

5.控制语句

1.if-then-else的循环控制语句

整数比较实用cmp 浮点数使用fcom fcomp

逆向分析技术
不太懂这个初始化的时候的值。书上说是指向局部变量空间

这里使用test替换cmp指令 如果为0则zf=1 不跳转继续执行
逆向分析技术

2.Switch-case语句

未优化前的代码都含有printf函数
逆向分析技术

编译优化后使用dec eax 来代替cmp指令 指令更短执行更快速

使用调转表

cmp 和ja 无符号大于则跳转 jmp table
逆向分析技术

3.转移指令的机器码的计算

短转:无条件和条件转移的机器码都是两个字节

长转:无条件转移是5个字节 条件转移是6个字节

子程序调用:call

6.循环语句

受用Maximize Speed优化后的代码使用寄存器来传值
逆向分析技术

7.数学运算符

1.一般使用add和sub指令,优化后比较喜欢使用lea指令来代替add和sub指令

逆向分析技术

这两个变量是什么时候初始化的

004007030 是%d

004701020 是printf函数

2.整数的乘法

mul和imul指令。
如果一个数是2的幂,会使用指令shl来实现乘法。

逆向分析技术

3.除法

div或者idiv指令
逆向分析技术

符号拓展指令cdq,作用是把eax寄存器中的数视为有符号的数字。

编译优化后为:
逆向分析技术

用于将除法转化为乘法

8.文本字符串

1.字符串存储格式
C \0 也成为ASCII字符串 广泛用于windows和unix中

DOS $

Pascal Y

Delphi Y

2.字符寻址指令

80x86支持直接和间接寻址等模式

mov eax,[40010h]
mov eax,[ecx]

load effective address

lea eax,[40040h]== mov eax,40040h

lea eax,[eax+8]== add eax,8

3.字符大小写转换

大写41~5A 小写 61~7A 大小写转换为减去20h

或者将第五位置0

4.计算字符串的长度

strlen()的实现

repne scasb指令获取字符串长度 strlen.c文件中的内联汇编代码如下:

#include <string.h>

size_t
strlen (const char *str)
{
  int cnt;

  asm("cld\n"           /* Search forward.  */
      /* Some old versions of gas need `repne' instead of `repnz'.  */
      "repnz\n"         /* Look for a zero byte.  */
      "scasb" /* %0, %1, %3 */ :
      "=c" (cnt) : "D" (str), "0" (-1), "a" (0));

  return -2 - cnt;
}

并没有使用scasb指令,而是直接比对字节内容。

转载于:https://blog.51cto.com/10509896/2150774

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值