版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Yes_butter/article/details/88144267
第四章
x86反汇编学习
一。计算机系统被描述为以下六个抽象层次。
1.硬件。 硬件层是唯一的一个物理层,由电子电路组成。这些电路实现了xor,and,or,not门等逻辑运算器的
复杂组合,成为数字逻辑。由于物理特性,硬件很难被软件所操纵。
2.微指令。 微指令又成为固件。微指令只能在为它设计的特定电路上执行。这层由一些微指令构成,它们
从更高的机器码层翻译过来,提供了访问硬件的接口。当分析恶意代码时,我们通常不关心微指令,因为
它们通常是为特定的计算机硬件设计的。
3.机器码。 机器码层由操作码组成,操作码是一些十六进制形式的数字,用于告诉处理器你想要它做什么。
机器码一般由多条微指令实现,这样底层硬件就能实际执行代码了。而机器码本身又由高级语言编写的计
算机程序编译而来。‘
4.低级语言。 低级语言是计算机体系结构指令集的人类易读版本,主要是汇编语言。恶意代码分析师使用
这一层,因为对人来说,机器码不易理解。我们使用过反汇编器来生成低级语言的文本,这些文本由一些
简单的助记符组成,如mov和jmp。汇编语言存在一些不同的语法,我们会逐一介绍。
5.高级语言。 大部分程序员使用高级语言。高级语言对机器层做了很强的抽象,从而可以很轻松地使用程
序逻辑和流程控制机制。高级语言包括c,c++等。它们被一个编译器经过成为编译的过程转化为机器码。
6.解释型语言。 解释型语言位于最高层。 很多程序员使用诸如c#,perl,.net.java等解释语言。这一层的代码
不会被编译为机器码,而是被翻译为了字节码。字节码是特定于该语言的一种中间表示,它在解释器中执
行。解释器是一个运行时将字节码实时翻译为可执行机器码的程序,它在解释器中执行。
二.逆向工程
恶意代码存储在磁盘上,通常是机器码层的二进制形式。机器码是一种计算机可以快速高效执行的代码形式。
反汇编恶意代码,是将恶意代码二进制文件作为输入,输出汇编语言代码。
x86,又成为intel IA-32,是大部分32位PC使用 体系结构,大部分amd64和Intel 64也可以运行x86的32位二进
制程序。正因如此,大部分恶意代码是x86编译的。
本书主要分析x86--这种恶意代码分析时最常遇到的架构。
三.x86体系架构
大部分内部实现上遵循冯诺依曼结构。
包含三种硬件组成
- 中央处理单元(cpu),负责执行代码
- 内存,(RAM),负责存储数据和代码
- 输入/输出系统(i/o),为硬盘,键盘,显示器等设备提供接口。
四.简单指令学习
栈。用于函数的内存,局部变量,流控制结构等被存储在栈中。栈是一种用于压和弹操作来刻画的数据结构。
用来短期存储。经常用于保存局部变量,参数和返回地址。其主要用途是管理函数调用之前的数据交换,而
不同的编译器对这种管理方法的具体实现有所不同,但大部分常用约定都使用相对EBP的地址来引用局部变
量与参数
mov寻址方式
1.立即寻址 mov eax,56 //作用是赋值
2.直接寻址 mov eax,[0x3f3f3f11]
od显示为 mov eax,dword ptr [0x3f3f3f11]
3.寄存器寻址 mov eax,edx
od显示为 mov eax, dword ptr [edx]
4.寄存器相对寻址 mov eax ,[edi+32]
od显示为 mov eax ,dword ptr [edi+32]
5.基址加变址寻址 mov eax ,[ebp+esi]
od显示为 mov eax ,dword ptr [ebp+esi]
6.相对基址加变址寻址mov eax,[ebx+edi-10]
od显示为 mov eax,dword ptr [ebp+edi-10]
xchg交换指令
xcgh eax ,edx //交换eax,edx的值
xcgh [esp+36],ebx
od显示为 xcgh dword ptr [esp+36],ebx
push和pop指令
push eax
push 123
push dword ptr [ebx] //注意不能访问
push -4
pop +4
add esp ,10 //10表示为16
LEA相当于取地址
lea eax,dword ptr[0x3f3f3f11] //得到eax 为3f3f3f11
lea eax,dword ptr[ecx*4+55] //获得
算数运算指令
8条加减指令ADD,ADC//带进位的加法ADC
SUB,SBB//带进位的减法 SBB
INC,DEC//加一,和减一
CMP,NEG//比较,取补
cmp eax,56
cmp eax,dword ptr[edx+edx]
cmp比较是做减法,用cmp的 oper1-oper2不保存结果
设置寄存器EFLAGS的CF,PF,ZF,AF,SF,OF,获得比较的结果
CF 进位标志,PF奇偶标志,AF辅助进位标志,ZF零标志,
SF 符号标志 OF 溢出标志 DF方向标志 IF中断标志
4条乘除法指令 MUL,IMUL//乘法
DIV,IDIV
EAX也叫累加器
mov eax 2
mov ebx 4
mul edx //4*2结果存到 低32位存在eax,高32位存到edx
IMUL有符号的乘法
DIV 利用eax存放结果,edx存放余数
mov eax 50
mov ecx 5
mov edx 0
div ecx//得到 eax 10 edx 0
逻辑运算指令
OR,AND,NOT,XOR,TEST//或,与,非,异或,not 等价于 neg-1
//Test进行与运算,不保存结果,只设置标志寄存器
移位指令
SAL,SAR,SHL,SHR;//算数左移,右移, 逻辑左移,逻辑右移
//sal,sar每移动一位相当于乘以2
//sar右移一位相当于除以2。shr向右移动一位,最高位用0来填充。
循环移位指令
ROL,ROR//左循环移位指令,右循环移位指令,
RCL,RCR//带进位的左循环指令,带进位的右循环移位指令
把移出去的位数放在相反的位置
//rcl会把之前的CF的值放在最低位。即为带进位的左循环指令
条件跳转指令
(1).jmp无条件跳转,short是短跳。
goto a;break;
(2).无符号数的条件跳转
指令名称 转移条件 转移说明
JA/JNBE CF=0且ZF=0 结果低于等于转移,或者高于转移
JB/JNAE CF=1 结果低于转移,或者不高于等于转移
(3).有符号的条件跳转
JG/JNLE
JNLE
(4).算数条件转移
JZ/JE ZF=1 等于0转移,或者相等转移
JNZ/JNE ZF=0 不等于0转移,或者不相等转移
函数调用
call。
字符串指令
loads dword ptr[esi]
读取esi的数据到eax,读取之后esi自动加4
补充指令:
movsx 读取所指向的低位,高位补充符号位
movzx 读取所指向的低位,高位补0
dword 4个字节
word 2个字节
byte 1个字节
pushad 压入8个寄存器,顺序EAX,ECX,EDX,EBX ESP,EBP,SEI,EDI
popad 弹出8个寄存器
标志位操作指令
clc CF=0
stc CF=1
cmp CF=~CF
PE文件
cmps 比较esi,edi的值
rep 重复指令操作
nop 什么也不做
浮点数操作指令
将BCD压入斜寄存器中
fbld tbyte ptr [ecx] //压入st0
fbstp tbyte ptr [ecx]//弹出到ecx
fld dword ptr [ecx] //加入st0,压入32位
fst dword ptr [ecx] //用st0赋值ecx
fstp dword ptr [ecx]//弹出到ecx
fxch st(1) //交换st0 和st1的值
fadd st,st(1) //st+=st1
fsub st,st(1) //st-=st1
fmul st,st(1) //st*=st1
fdiv st,st(1) //st/=st1
- 第四章没有课后实验。