当前位置:   article > 正文

《CTF特训营》学习总结——Reverse:逆向分析概述

逆向分析

一、逆向分析的主要方法

逆向分析主要是将二进制机器码进行反汇编得到汇编代码,在汇编代码的基础上,进行功能分析。经过反编译生成的汇编代码中缺失了源代码中的符号、数据结构等信息,因此需要尽可能地通过逆向分析还原以上信息,以便分析程序原有逻辑和功能。逆向分析主要包括静态和动态分析。

1.静态分析

是在不执行代码文件地情况下,对代码进行静态分析,通过对代码外部特征进行观察,主要包括静态反汇编、反编译。

文件类型分析主要是用于了解程序是什么语言编写的,或者是用什么编译器编译的,以及程序是否被加密处理过。

在逆向过程中,主要是使用反汇编工具查看内部代码,分析代码结构。

2.动态分析

是在程序文件的执行过程中对代码进行动态分析的一种方法,其通过调试来分析代码,获取内存的状态等。在逆向过程中,通常使用调试器来分析程序内部结构和实现原理。

二、汇编指令体系结构

1.x86指令架构

(1)寄存器组

通用寄存器:包括EAX、EBX、ECX、EDX、ESI、EBP、ESP

指令指针寄存器(EIP):指向当前要执行的指令

状态标识寄存器(EFLAGS):根据状态标识寄存器中状态的值控制程序的分支转跳

段寄存器:CS、DS、SS、ES、FS、GS。在当前的操作系统,CS、DS、SS和ES的段寄存器的基地址通常为0.

特殊寄存器:包括DRO-DR7,用于设置硬件断点

(2)汇编指令集

x86汇编语言有两种语法记法:intel和AT&T,常用的IDA pro、OD、MASM这些逆向分析工具使用intel记法,而UNIX系统上的工具gcc通常遵循AT&T记法,intel记法更常用

intel的汇编语言格式为:

操作项 目的操作数,源操作数

操作项:汇编语言中的一些指令,比如add(加法)、mov(移动)等指令

目的操作数和源操作数:寄存器、内存地址或者立即数

(3)数据传送指令

数据传送指令是使用最频繁的指令,其格式为:

  1. MOV DEST,SRC
  2. 功能:将一个字节、字或者双子从原操作数SRC传送至目的操作数DEST

(4)栈操作与函数调用

入栈PUSH,出栈POP,函数调用与返回通过CALL/RET指令实现,CALL指令将当前的EIP保存到堆栈中,RET指令读取堆栈,得到返回地址。

入栈:PUSH SRC          功能:ESP-=4;[ESP]=SRC

出栈:POP DEST          功能:DEST-=[ESP];ESP+=4

调用函数:CALL FUNC 功能:PUSH EIP;EIP=FUNC

函数返回:RET              功能:EIP=[ESP];ESP+=4

5)算数、逻辑运算指令

①算数运算指令

ADD: 加法。

ADC: 带进位加法

INC:   加1

AAA: 加法的ASCII码调整

DAA: 加法的十进制调整

SUB: 减法

SBB: 带借位减法

DEC: 减1

NEG: 取补

CMP: 比较。(两操作数作减法,仅修改标志位,不回送结果)

AAS: 减法的ASCII码调整

DAS: 减法的十进制调整。

MUL: 无符号乘法。结果回送AH和AL(字节运算),或DX和AX(字运算)

IMUL: 整数乘法。结果回送AH和AL(字节运算),或DX和AX(字运算)

AAM: 乘法的ASCII码调整。

DIV: 无符号除法:商回送AL,余数回送AH,(字节运算);或商回送AX,余数回送DX(字运算)

IDIV: 整数除法:商回送AL,余数回送AH,(字节运算);或商回送AX,余数回送DX(字运算)

AAD: 除法的ASCII码调整

CBW: 字节转换为字(把AL中字节的符号扩展到AH中去)

CWD: 字转换为双字(把AX中的字的符号扩展到DX中去)

CWDE: 字转换为双字(把AX中的字符号扩展到EAX中去)

CDQ: 双字扩展(把EAX中的字的符号扩展到EDX中去)

②逻辑运算指令

AND: 与运算

or: 或运算

XOR: 异或运算

NOT: 取反

TEST: 测试(两操作数作与运算,仅修改标志位,不回送结果)、

(6)转移控制指令

①无条件转移指令(长转移)

JMP: 无条件转移指令

CALL: 过程调用

RET/RETF: 过程返回

②条件转移指令(短转移:短转移,-128到+127的距离内;当且仅当(SF、XOR、OF)=1时,OP1<OP2 )

A/JNBE: 大于转移

JAE/JNB: 大于或等于转移

JB/JNAE: 小于转移

JBE/JNA: 小于或等于转移

以上四条,测试无符号整数运算的结果(标志C和Z)

JG/JNLE: 大于转移

JGE/JNL: 大于或等于转移

JL/JNGE: 小于转移

JLE/JNG: 小于或等于转移

以上四条,测试带符号整数运算的结果(标志S,O和Z)

JE/JZ: 等于转移

JNE/JNZ: 不等于时转移

JC: 有进位时转移

JNC: 无进位时转移

JNO: 不溢出时转移

JNP/JPO: 奇偶性为奇数时转移

JNS: 符号位为 "0" 时转移

JO: 溢出转移

JP/JPE: 奇偶性为偶数时转移

JS: 符号位为 "1" 时转移

③循环控制指令(短转移)

LOOP: CX不为零时循环

LOOPE/LOOPZ: CX不为零且标志Z=1时循环

LOOPNE/LOOPNZ: CX不为零且标志Z=0时循环

JCXZ: CX为零时转移

JECXZ: ECX为零时转移

④中断指令

INT:    中断指令

INTO: 溢出中断

IRET: 中断返回

(7)数据传输指令

①数据传送指令

MOV:传送字或字节。

MOVSX:先符号扩展,再传送。

MOVZX:先零扩展,再传送。

PUSH:把字压入堆栈

POP: 把字弹出堆栈

PUSHA: 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈

POPA: 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈

PUSHAD: 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈

POPAD: 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈

BSWAP: 交换32位寄存器里字节的顺序。

XCHG: 交换字或字节。( 至少有一个操作数为寄存器,段寄存器不可作为操作数)

CMPXCHG: 比较并交换操作数。(第二个操作数必须为累加器AL/AX/EAX)

XADD: 先交换再累加。( 结果在第一个操作数里 )

XLAT: 字节查表转换── BX 指向一张 256 字节的表的起点,AL 为表的索引值(0-255,即0-FFH); 返回 AL 为查表结果 ( [BX+AL]->AL) [6] 

②输入输出端口传送指令

IN: I/O端口输入。( 语法:IN 累加器,{端口号│DX} )

OUT: I/O端口输出. (语法:OUT {端口号│DX},)输入输出端口由立即方式指定时,其范围是 0-255;由寄存器DX 指定时,其范围是 0-65535。

③目的地址传送指令

LEA: 装入有效地址例:LEA DX,string;把偏移地址存到DX。

LDS: 传送目标指针,把指针内容装入DS。例: LDS SI,string;把段地址:偏移地址存到DS:SI。

LES: 传送目标指针,把指针内容装入ES。例: LES DI,string;把段地址:偏移地址存到ES:DI。

LFS: 传送目标指针,把指针内容装入FS。例: LFS DI,string;把 段地址:偏移地址存到FS:DI。

LGS: 传送目标指针,把指针内容装入GS。例: LGS DI,string;把 段地址:偏移地址存到GS:DI。

LSS: 传送目标指针,把指针内容装入SS。例: LSS DI,string;把 段地址:偏移地址存到SS:DI。

④标志传送指令

LAHF:标志寄存器传送,把标志装入AH。

SAHF:标志寄存器传送,把AH内容装入标志寄存器。

PUSHF: 标志入栈

POPF: 标志出栈

PUSHD: 32位标志入栈

POPD: 32位标志出栈

(8)伪指令

DB: 定义字节(1字节)

DW: 定义字(2字节)

DD: 定义双字(4字节)

PROC: 定义过程

ENDP: 过程结束

SEGMENT: 定义段

ASSUME: 建立段寄存器寻址

ENDS: 段结束

END: 程序结束

(9)处理机控制指令

即标志处理指令,处理机控制指令完成简单的控制功能。

CLC:进位位置0指令

CMC:进位位求反指令

CLC: 进位位置为0指令

STC: 进位位置为1指令

CLD: 方向标志位置0指令

STD: 方向标志位置1指令

CLI: 中断标志置0指令

STI: 中断标志置1指令

NOP: 无操作

HLT: 停机

WAIT: 等待

ESC: 换码

LOCK: 封锁

(10)特殊指令

int3指令:对应字节码0xcc,主要用于设置软断点

int 0x80:linux系统中32位的系统调用指令

三、x86应用程序二进制接口

调用惯例是指一些规则,其规定了在机器层面如何进行函数调用,对于特定的系统来说,它是由应用程序二进制接口(ABI)定义的。x86指令体系中的函数调用图如下,当发生函数调用时,首先将参数从右向左加入堆栈中,然后通过call指令将函数的返回地址压入堆栈中,最后,在新的函数中将之前的ebp保存到堆栈中,同时esp会减去一定的值,留下一部分分栈空间给局部变量使用。

四、x64指令体系架构

1.寄存器

通用寄存器加到16个,分别为RAX,RBX,RDX,RCX,RBP,RDI,RSI,RSP,R8~R15

2.系统调用指令

syscall/sysret是linux64位操作系统的调用方式

3.x64应用程序二进制接口

有两种广泛使用的x64 ABI,列举如下:

microsoft's x64 ABI:主要用于windows操作系统中的64位程序

sysV x64 ABI:主要用于linux,BSD,MAC等操作系统的64位程序

microsoft's x64 ABI的前4个参数通过寄存器RCX,RDX,R8,R9传递,其余则是通过栈传递,但是在栈上会预留下0x20字节的空间用于临时保存前4个参数,返回值位RAX,对应的函数调用形式如下:

RAX func (RCX,RDX,R8,R9,[rsp+0x20],[rsp+0x28],.....}
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/90603
推荐阅读
  

闽ICP备14008679号