当前位置:   article > 正文

学逆向工程前看懂的汇编语言_如何看懂汇编语言

如何看懂汇编语言

前言:刚刚入门学习漏洞,就被不会看寄存器和指令打败了,安照0day书本的内容走一遍下来,发现每一章都会被环境不能实现,还有软件下载不成功所劈死,入门学习第一大阻碍是下载工具,第二大阻碍是使用工具,安装插件啥的完全找不到,还有寄存器和指令都看不懂。本文参考汇编语言第三版,还有cdns的各位大神的总结笔记后面附上链接,若侵权,请联系作者,会删除。

想要学好汇编语言重要的是会用这个语言 编译 运行 操作,最好是需要用到的时候再去学,会发现自己很多疑惑的,这样的学习方式才是有意思的。不要别人学就跟着别人,学习之路是自己的,复制齐白石走过的路也不可能是齐白石。

汇编语言简介点来说是什么?

CPU主搞运算的,你要是输入一条指令(instruction)就运行一次,然后停下来,等待下一条指令。指令都是二进制的,0和1,组合的时候可以代表很多意思,如果人去识别,那可难了。为了解决人类可读性的问题,以及偶尔的编辑需求人脑能快速看懂的知识,就诞生了汇编语言。

机器语言就是二进制的,0和1,机器才懂,加法指令是00000011

汇编语言的加法指令是ADD

高级语言的加法指令就是符号  +  

寄存器:用于存放cpu的数据信息

学习汇编语言,最先看的是寄存器和内存模型。CPU 包括运算器和控制器还有寄存器,负责运算,不负责储存数据。数据一般都储存在内存之中,CPU 使用是去内存读写数据。但是,CPU 的运算速度远高于内存的读写速度,为了避免被拖慢,CPU 都自带一级缓存和二级缓存。基本上,CPU 缓存可以看作是读写速度较快的内存。

不同CPU,寄存器个数不一样,结构不一样。 拿8086CPU来说,14个

AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW

通用寄存器:AX、BX、CX、DX

数据寄存器主要用来保存操作数和运算结果等信息,从而节省读取操作数所需占用总线和访问存储器的时间。 
32位CPU有4个32位的通用寄存器EAX、EBX、ECX和EDX。对低16位数据的存取,不会影响高16位的数据。这些低16位寄存器分别命名为:AX、BX、CX和DX,它和先前的CPU中的寄存器相一致。4个16位寄存器又可分割成8个独立的8位寄存器:

AX可分为AH和AL.
BX可分为BH和BL.
CX可分为CH和CL.
DX可分为DH和DL.
每个寄存器都有自己的名称,可独立存取。程序员可利用数据寄存器的这种“可分可合”的特性,灵活地处理字/字节的信息。

每个可分为 ~H 与 ~L,如 AH 和 AL ,H 表示高八位,L 表示低8位。

思考1:

上面图有点看不太懂啊?  原来是这样啊    如果 十进制数值2000  那么十六进制是4EH20H    而且高字节和低字节分开的十进制分别是 78 32  

AX的简单汇编指令

 突然长脑袋的问题 为何从起始地址0x1000开始分配,一直分配到地址0x100A,如果再要求得到22个字节,那么就分配到0x1020。这是如何计算的呢?

1个字节是8个比特 ,说明一个字节有8个0和1.

0x100是256个字节   ,那么0x100A就有4016个字节 ,增加22个字节 计算4038个字节是0x1020

寄存器AX通常称为累加器(Accumulator Register),用累加器进行的操作可能需要更少时间。累加器可用于乘、除、输入/输出等操作,它们的使用频率很高; 

寄存器BX称为基址寄存器(Base Register)。它可作为存储器指针来使用; 

寄存器CX称为计数寄存器(Count Register)。在循环和字符串操作时,要用它来控制循环次数;在位操作中,当移多位时,要用CL来指明移位的位数; 

寄存器DX称为数据寄存器(Data Register)。在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存放I/O的端口地址。

指针寄存器  EBP,  ESP   (Pointer Register)
32位CPU有2个32位通用寄存器EBP和ESP。其低16位对应先前CPU中的SBP和SP,对低16位数据的存取,不影响高16位的数据。

指针寄存器主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。指针寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。

寄存器BP称为基址指针寄存器(Base Pointer);

寄存器SP称为堆栈指针寄存器(Stack Pointer)。

变址寄存器  ESI,   EDI   (Index Register)
32位CPU有2个32位通用寄存器ESI和EDI。其低16位对应先前CPU中的SI和DI,对低16位数据的存取,不影响高16位的数据。

变址寄存器主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式(在第3章有详细介绍),为以不同的地址形式访问存储单元提供方便。 变址寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。
寄存器SI称为源变址寄存器 (Source Index);

寄存器DI称为目的变址寄存器(Destination Index)。

内存模型:Heap   (堆相关)地址从低到高 

Heap 的一个重要特点就是不会自动消失,必须手动释放,或者由垃圾回收机制来回收。

寄存器只能存放很少量的数据,大多数时候,CPU 要指挥寄存器,直接跟内存交换数据。所以,除了寄存器,还必须了解内存怎么储存数据。

程序运行的时候,操作系统会给它分配一段内存,用来储存程序和运行产生的数据。这段内存有起始地址和结束地址,比如从0x10000到0x90000,起始地址是较小的那个地址,结束地址是较大的那个地址。程序运行过程中,对于动态的内存占用请求(比如新建对象,或者使用malloc命令),系统就会从预先分配好的那段内存之中,划出一部分给用户,具体规则是从起始地址开始划分(实际上,起始地址会有一段静态数据)。

举例  如果起始地址0x1000开始分配,一直分配到地址0x100A,如果再要求得到32个字节,那么就分配到0x102A

内存模型:stack  (栈) 地址从高到低     

Stack 是由于函数运行而临时占用的内存区域。push 和 pop

所有的帧都存放在 Stack,由于帧是一层层叠加的,所以 Stack 叫做栈。生成新的帧,叫做"入栈",英文是 push;栈的回收叫做"出栈",英文是 pop。Stack 的特点就是,最晚入栈的帧最早出栈(因为最内层的函数调用,最先结束运行),这就叫做"后进先出"的数据结构。每一次函数执行结束,就自动释放一个帧,所有函数执行结束,整个 Stack 就都释放了。

Stack 是由内存区域的结束地址开始,从高位(地址)向低位(地址)分配。比如,内存区域的结束地址是0x1000,第一帧假定是16字节,那么下一次分配的地址就会从0xFF0开始;第二帧假定需要64字节,那么地址就会移动到0xFB0。

段寄存器:重点知识是CPU=CSx16+IP 还有jmp跳转

段寄存器有ES、CS、SS、DS、FS、GS、LDTR、TR共8个。

ES:扩展段。在串操作时(比如cmovs)目标操作数的基址是ES,源操作数是DS。

CS:代码段,配合EIP使用。

SS: 堆栈段,凡是基址是EBP或ESP的,段前缀就是SS。

DS:数据段,默认的都是DS。

FS、GS:80386 之后定义的。

读操作时,可以读到段寄存器的段选择子部分的16位。例如 mov ax,es 指令会把es寄存器的段选择子读到ax。

写操作时,会写入96位,其中源操作数的16位写入到段寄存器的段选择子部分,另外80位会根据段选择子从GDT表(全局描述表)中获取

段寄存器的大小是 96 位

段寄存器结构可以抽象成以下结构

struct Segment

{
  WORD Selector;  //16位段选择子,可见部分.  使用OD 或者X64dbg看段寄存器只会显示16位的段选择子可见部分.当读段寄存器(如mov ax,CS)的时候,只会返回这16位。或者push seg 操作针对的都是这16位。如果目标操作数是32位(如mov eax ,CS),则将16位零扩展成32位赋给目标操作数。但是写的时候,就会涉及到96位

  WORD Attribute; //16位表示的段属性, 表示了当前段寄存器是可读的可写的还是可执行的

  DWORD Base;     //32位表示的基址,表示段从哪里开始

  DWORD limit;    //32位表示,表示的是基址的长度. base + limit 可以确定一个段的大小

}
段地址x16+偏移地址=物理地址 常用说法左移4位。位数指二进制位  就是原有的基础上面二进制的机器语言上面左移4位 ==就是2的4次方

思考

下面这个图的思考很重要的,又要长脑袋了  

思考2:8086CPU不支持将数据直接送入段寄存器 比如mov ds,1000H这条指令是非法的

那么如何实现1000H送入ds段寄存器呢? 可以用一个通用寄存器中转。下面的问题就是这个情况

问题3.2
写几条指令,将al 中的数据送入内存单元 10000H 中?思考后看分析。
分析:
怎样将数据从寄存器送入内存单元?从内存单元到寄存器的格式是:“mov 寄存器
名,内存单元地址”,从寄存器到内存单元则是:“mov 内存单元地址,寄存器名”。
10000H 可表示为 1000:0,用 ds 存放段地址 1000H,偏移地址是 0,则 mov [0],al 可完成
从al到 10000H 的数据传送。完整的几条指令是:
mov bx,1000H
mov ds,bx
mov [0],al

相关的jmp知识:CPU=CSx16+IP  就是CS向后移动一位再相加。 

指令:

数据传送指令:mov pop push pushf popf


mov:数据传送
示例:mov ax,bx
说明:将bx中的数据传送到ax中,因为使用的是ax和bx,所以数据的长度是16位,下面的例子都相同,如果有操作数据中有寄存器,那么按照寄存器的数据长度计算

push:入栈
示例:push ax
解释:将ax的数据入栈,传送到ss:sp栈顶处

pop:出栈
示例:pop ax
解释:将ss:sp位置的数据出栈,传送入ax中

pushf:所有标志位入栈
示例:pushf
解释:标志位入栈,防止后面的操作对标志位产生影响的通常做法

popf:标志位出栈
示例:popf
解释:标志位出栈,用于还原入栈的标志位

xchg:交换,目前没用到

算数运算指令:add sub adc sbb inc cmp mul div aaa


add:加法
示例:add ax,2
解释:将ax中的数据加2,即ax+0002h

sub:减法
示例:sub ax,2
解释:将ax中的数据减2,即ax-0002h

adc:加法(带符号位)
示例:adc ax,2    ;CF=1
解释:将ax中的数据加3,即ax+0002h+1h

sbb:减法(带符号位)
示例:sbb ax,2    ;CF=1
解释:将ax中的数据减3,即ax-0002h-1h

inc:自增
示例:inc si
解释:将si中的数据加1,常用在循环或条件转移中

dec:自减
示例:dec ax
解释:将ax中的数据减1

cmp:比较
示例:cmp ax,0
解释:相当于减法,ax-0,只不过不影响寄存器的值,而只影响标志寄存器,因为条件转移指令是依据标志寄存器的指令,所以cmp常与条件转移指令配合使用进行条件转移

mul:乘法
示例:mul bx或mul bl
解释:分为两种情况:
1. 指令参数是8位寄存器如bl时,乘数1默认放在al寄存器中,另一个乘数2放在8位寄存器如bl中,结果存在ax中
2. 指令参数是16位寄存器如bx时,乘数1默认放在ax寄存器中,另一个乘数2是指定的16位寄存器如bx中的数据,结果的高16位存在dx,低16位存在ax中

div:除法
示例:div bx或div bl
解释:同样分为两种情况:
1. 指令参数是8位寄存器时,被除数(除法前面那个数。。。)则为16位,默认存放于ax中,除数则是存放于指定8位寄存器如bl中,结果为:al存储商,ah存储余数
2. 指令参数是16位寄存器时,被除数则为32位,默认存放于ax和dx中,dx存高16位,ax存低16位,除数存放于指定16位寄存器如bx中,结果:ax存储商,dx存储余数

aaa:目前没有用到

逻辑指令:and  or not  xor test


and:逻辑与
示例:and al,11011111b
解释:示例中结果是将al中第6位置为0,其他位保持不变,常用与简化运算如,将小写字母转化为大写字母,只需要将字母与11011111做逻辑与运算即可实现

or:逻辑或
示例:or al,00100000
解释:示例中结果是将al中第6位置为1,其他位保持不变,同样也能实现将大写字母转化为小写字母的简化运算,需要将字母与00100000做逻辑或运算即可实现

not:逻辑非,不常用
示例:
解释:

xor:逻辑异或,目前不常用
示例:
解释:

test:不常用
shl:逻辑左移
示例:shl al,1或mov cl,3;shl al,cl
解释:逻辑左移的意思就是左移后,移出的数据存放在标志寄存器CF中,而最低位用0补齐,也分为两种情况:
1. 左移1位:直接shl al,1即可
2. 左移超过1位:需要先将欲移动的位数据存入cl中,再通过左移cl个位的数据来实现

shr:逻辑右移
示例:shr al,1或move cl,2;shr al,cl
解释:逻辑右移与逻辑左移类似,这里就不多讲了,同样也是两种情

转移指令:


无条件转移指令


jmp:无条件转移指令
示例:jmp short s;s:inc ax
解释:jmp转移指令可以实现段内短转移、段内近转移和段间转移这三种基本需求
1. 段内短转移:只对IP寄存器修改,修改范围为-128~127,也就是说向前最多转移+127个字节,向后最多转移-128个字节
2. 段内近转移:与短转移基本相同,不过是16位的位移,即修改IP的范围是-32768~32767
3. 远转移(段间转移):可以转移到指定的内存处,上面的两个转移只是在同一个段中的转移,是根据位移定位的转移方式,而远转移可以指定转移的目的地址

条件转移指令:jcxz je jb ja jnb jna


jcxz:如果cx寄存器的值为0,则转移到指定标号
示例:mov cx,0;jcxz s
解释:如果条件满足cx寄存器的值为0,则转移到指定的标号处,常用的场景是:遍历一个以'0'字符结尾的字符串,根据这个0判断字符串是否到末尾的简单实现方式

je:如果cmp得差结果等于0,则转移到指定标号
示例:mov bx,3;cmp bx,3;je s
解释:将会转移到s处

jb:如果cmp的差结果小于0,则转移到指定标号
示例:mov bx,3;cmp bx,4;jb s
解释:将会转移到s处

ja:如果cmp的差结果大于0,则转移到指定标号
示例:mov bx,3;cmp bx,2;ja s
解释:将会转移到s处

jnb:如果cmp的差结果不小于0,则转移到指定标号
示例:mov bx,3;cmp bx,3;jnb s
解释:将会转移到s处

jna:如果cmp的差的记过不大于0,则转移到指定标号
示例:mov bx,3;cmp bx,3;jna s
解释:将会转移到s处

循环指令: loop call ret 


loop:汇编语言中的循环语句
示例:mov cx,10;loop s
解释:将s程序段循环执行10次(循环次数由cx的值指定)

过程
call:调用子程序,常与ret成对使用
示例:call s;s:ret
解释:转移到子程序,类似于转移指令,但相当于执行了
push IP
jmp near s这两条指令,记录了转移的位置,可以使用ret返回此IP的位置

ret:在子程序中同于返回call的指令处,常与call成对使用,并且是近转移
示例:call s;s:ret
解释:从子程序跳出,相当于执行了
pop IP,程序执行的下一条语句就是原来call的IP的地址,从而实现了近转移

retf:在子程序中同于返回call的指令处,常与call成对使用,并且是远转移
示例:call s;s:retf
解释:从子程序跳出,相当于执行了
pop IP
pop CS程序执行的下一条语句就是原来call的IP的地址,从而实现了远转移

处理机控制指令:cld std cli sti nop 


cld:设置DF为0(即正向拷贝)
示例:cld;rep movsb
解释:设置标志寄存器DF为0,即设置拷贝的方向为正向

std:这是DF为1(即反向拷贝)
示例:std;rep movsb
解释:设置标志寄存器DF为1,即设置拷贝的方向为反向

cli:设置TF标志位为1
示例:cli
解释:设置TF为1后,当接受到可屏蔽中断时,会在下一条指令执行中断

sti:设置TF标志位为0
示例:sti
解释:设置TF为0后,当接受到可屏蔽中断时,会忽略中断继续执行当前程序直至结束

nop:添加一个占位的一字节数据
示例:funcend:nop
解释:常用来记录子程序的段结束的位置,比如offset funcend就可以获取func结束位置的偏移地址

标志位 :在内存中占1字节大小,用于运算和程序中的状态等。

常用的标志有ZF,PF,SF,CF,OF,DF

ZF:是否为0

PF:1的个数是否为偶数

SF:是否为负数

有符号整数,只看结果是不是大于7,也就是首位是不是0

CF:是否存在进位或借位(无符号整数)

直接进行无符号运算,首位进位就置1

OF:是否存在溢出(有符号整数)

16位cpu,有符号溢出范围79H(127),-80H(128)

DF:方向标志位,与movsb配合使用

编译运行

学习完基础知识就应该做操作了

 ​​​​​操作开始第一步就是安装好环境 由于我使用的是新版Windows11 没有了debug的内部使用

需要另行安装,所以需要官网下载DOSBox,然后下载插件debug

实验1:查看CPU和内存  观察机器指令和汇编指令编译过程

《汇编语言第三版》王爽著,还有csdn上面各个大神的总结

段寄存器参考为CSDN博主「maomao171314」的原创文章
原文链接:https://blog.csdn.net/maomao171314

通用寄存器参考CSDN博主「幽_篁」的原创文章,
原文链接:https://blog.csdn.net/hallyz945

汇编指令知识参考CSDN博主「coderqjinx」的文章

原文链接:https://blog.csdn.net/coderqjinx

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/875959
推荐阅读
相关标签
  

闽ICP备14008679号