安全笔记:逆向|windows逆向工程和8086汇编语言

目录

基础知识

代码分析

逆向分析法

修改应用程序文件或进程内存内容方法

入口点

修改地址方法

区分代码为部分的方法

快速查找制定代码

两个反调试方法

函数调用约定

字符串

字符串编码

修改字符串方法

内存

内存分区

字节序

PE文件

格式

地址映射

PE头

节区头

工具

8086汇编语言


基础知识

汇编语言依赖于CPU,每个产品用的CPU种类不同,则汇编语言也有略微差异

代码分析

汇编文件(主)

十六进制文件(辅)

逆向分析法

静态分析——分析源码

动态分析——调试分析

推荐方法:先静态分析再动态分析

修改应用程序文件或进程内存内容方法

打补丁——Patch

破解——Crack

入口点

调试器停止的地方即为PE文件执行的起始地址

修改地址方法

call [地址]

jmp [地址]

区分代码为部分的方法

goto命令

设置断点

注释

标签

快速查找制定代码

代码执行法

字符串检索法

API检索法

两个反调试方法

压缩器——修改文件结构、压缩后文件仍为可执行文件

保护器——压缩、反调试、反模拟、反转储

函数调用约定

函数执行完毕,ESP需要回滚(用户执行)


字符串

字符串编码

字符的编码方式不同,占据位数不同,调试代码要注意

Unicode码中字符长度不够后需要填充NULL

修改字符串方法

直接修改字符串缓冲区(新字符串长度大于原有字符串,覆盖可能损坏字符串后面的数据)

在其他内存区域生成新字符串并传递给消息函数(注意地址,地址并不是按照规定载入内存,其按一定规律,即其要按一定文件偏移,否则程序出错)。


内存

内存分区

应用程序被加载到内存有最小内存分配大小,若不够则要填充NULL(一般为1000)

字节序

多字节数据在计算机内存中存放的字节顺序(小端序和大端序)

安全笔记:逆向|windows逆向工程和8086汇编语言_第1张图片

采用大端序存储数据时,内存地址低位存储数据的高位,内存地址的高位存储数据的低位。例如:Unix CPU/网络协议。

采用小端序存储数据时,内存地址低位存储数据的低位,内存地址的高位存储数据的高位。例如:Intel x86 CPU。


PE文件

格式

安全笔记:逆向|windows逆向工程和8086汇编语言_第2张图片

PE头:DOS头到节区头

PE体:PE头其下的节区

文件中使用偏移,内存中使用VA(虚拟地址)来表示位置。

文件分为.text(代码)、.data(数据)、.rsrc(资源)节,其分别保存

PE头与各节区的尾部存在一个区域,称为NULL填充(不够最小基本单位则填充NULL)

地址映射

VA:虚拟内存的绝对地址,RVA:相对虚拟地址,ImageBase:基准地址

ImageBase+RVA=VA

32位Windows OS中,各进程分配有4GB的虚拟内存,VA范围为00000000~FFFFFFFF。

PE头

PE头由许多结构体组成(40字节),PE头的最前面添加了一个IMAGE_DOS_HEADER结构,用来扩展已有的DOS EXE头。

IMAGE_DOS_HEADER分为e_magic(DOS签名)、e_lfanew(指示NT头的偏移)。

所有PE文件在开始部分(e_magic)都有DOS签名(“MZ”)。

e_lfanew指向NT头所在位置(NT头:IMAGE_NT_HEADERS)。

DOS存根在DOS头下方,是个可选项,且大小不固定,其由代码和数据混合而成。

NT头结构分为签名、文件头、可选头三部分。

节区头

安全笔记:逆向|windows逆向工程和8086汇编语言_第3张图片

安全笔记:逆向|windows逆向工程和8086汇编语言_第4张图片


工具

Hex Editor:二进制->十六进制

OllyDbg:汇编逆向工具


8086汇编语言

​​​​字:16bit  字节:8bit

通用寄存器:ax、bx、cx、dx(16位)

高位寄存器:ah、bh、ch、dh(高8位)

低位寄存器:al、bl、cl、dl(低8位)

从CS:IP的内存单元地址中读取指令,执行该指令,之后IP=IP+所读取指令的长度。(CS:IP永远指向当前指令的下一条指令)

CS:段地址寄存器

IP:偏移地址

物理地址=段地址×16+偏移地址

jmp 段地址:偏移地址 修改CS、IP寄存器

jmp 寄存器 仅修改IP寄存器

ds寄存器

ds 段地址

[…] 表示一个内存单元的偏移地址

DS:[…]表示的是内存(保存数据的位置)

数据保存方向:从低地址向高地址保存,数据的高位保存在高地址,数据的低位保存在低地址。

入栈操作:push

出栈操作:pop

SS:SP指向栈顶元素(操作者只能修改SP,一个段最大范围为0~FFFFH,最大容量为64KB)

入栈,栈顶从高地址向低地址移动 SP=SP-2

出栈,栈顶从低地址向高地址移动 SP=SP+2

栈空间由程序声明,CPU没有控制栈空间的概念,意味着栈溢出时可以覆盖其它内存单元数据。

内存信息:①内存单元地址②内存单元长度

[寄存器] 表示一个内存单元,其偏移地址位于寄存器中

loop使用方法:

s:

代码段

loop s

汇编源程序中,数据不能以字母开头(前面补0来解决这一问题)

debug和源程序区别:

debug: mov al,[0]

源程序: mov al,ds:[0]

循环方法:

mov cx,10 #cx为循环计数器

s:

代码段

inc bx

loop s

mov ax,ds:[bx] 相当于 mov ax,[bx]

mov ax,ss:[bx] 段地址寄存器为ss

若不体现:前面的寄存器,默认为ds

寻找到安全的内存空间(其中没有重要数据,不必担心覆盖导致数据丢失)

查看内存空间,找到全为0的连续空间,即为安全空间

DOS系统:0:200~0:2FF一般是安全空间

操作系统:合法通过操作系统取得的安全都为安全空间

源程序的伪指令需要经过编译器编译,由编译器执行

伪指令举例:

assume cs:code

code segment

start(程序入口)

代码段

code ends

end start(程序结束)

dw define word 定义字型数据

dw [数据]  从当前的CS:IP处开始存储数据

dw 0,…,0  声明内存空间,将其用作栈(清空一个数据空间)

编写代码时应注意用多个段存放数据、代码和栈。

si和di和bx功能相近,但不能分成两个8位寄存器使用。

多层循环时,需要通过对cx数据进行保存,恢复来进行。

需要暂存数据的时候,我们都应该使用栈。

没有寄存器名存在情况,用word ptr/byte ptr指明内存单元的大小。

安全笔记:逆向|windows逆向工程和8086汇编语言_第5张图片

call 实现CS、IP入栈,转移地址执行命令

安全笔记:逆向|windows逆向工程和8086汇编语言_第6张图片

内中断

安全笔记:逆向|windows逆向工程和8086汇编语言_第7张图片

安全笔记:逆向|windows逆向工程和8086汇编语言_第8张图片

安全笔记:逆向|windows逆向工程和8086汇编语言_第9张图片

安全笔记:逆向|windows逆向工程和8086汇编语言_第10张图片

外中断

安全笔记:逆向|windows逆向工程和8086汇编语言_第11张图片

安全笔记:逆向|windows逆向工程和8086汇编语言_第12张图片

安全笔记:逆向|windows逆向工程和8086汇编语言_第13张图片

安全笔记:逆向|windows逆向工程和8086汇编语言_第14张图片

安全笔记:逆向|windows逆向工程和8086汇编语言_第15张图片

安全笔记:逆向|windows逆向工程和8086汇编语言_第16张图片

安全笔记:逆向|windows逆向工程和8086汇编语言_第17张图片

安全笔记:逆向|windows逆向工程和8086汇编语言_第18张图片

 

你可能感兴趣的:(安全笔记:逆向)