CTFHUB技能树——Pwn前置技能学习

CTFHUB技能树——Pwn前置技能学习

文章目录

PS:这里仅供查阅指令用,不需要很认真的学,因为写题过程中,你总要看汇编代码的,总会接触原理,自然而然就会懂了

一、汇编语言学习

资料来源:

汇编语言(第4版)_9787302539414.pdf

image-20240114174332947

一、(一)基础知识

a、计算机操作和机器指令及汇编指令的转化形式:
名称实际行动
操作寄存器BX的内容发送到AX中
机器指令1000100111011000
汇编指令mov ax,bx(即将BX的内容传送进AX)
b、汇编语言的组成:
名称实际操作
汇编指令机器码的助记符,有对应的机器码
伪指令没有对应的机器码,由编译器执行,计算机并不执行
其他符号如±*/等,有编译器识别,没有对应的机器码
c、指令和数据:

没有太大区别,只用应用时才会视作有区别

d、CPU对存储器的读写:

需要

  • 存储单元的地址(地址信息);
  • 器件的选择,读或写的命令(操作信息);
  • 读或写的数据(数据信息)

过程:

image-20240114190714780

e、转化形式:
名称解释
机器码101000010000001100000000
对应的汇编指令MOV AX,[3]
含义传送3号单元的内容入AX
f、机器部件:
名称解释
存储单元是存储器的单元划分,一般编号为0-127
地址总线CPU通过地址总线来指定存储器单元,一般CPU通过这个计算可对对少存储单元进行寻址,如若有N根线,则可寻找2的N次方个内存单元
数据总线CPU通过数据总线进行与内存或其他器件之间的数据传送,1根数据可传送1位8位二进制数据(1bit)

image-20240114192541235

a-f小结:

image-20240114192959517

a-f检测:

image-20240114193511787

g、内存地址空间

CPU能探寻的内存单元

g、①主板

image-20240114194232867

g、②接口卡

image-20240114210604609

h、各类存储器芯片

读写分两类:随机存储器只读存储器

名称解释
随机储存器存放CPU使用的绝大部分程序和数据
装有BIOS的ROM利用该硬件,设备进行最基本输入输出
接口卡上的RAM对接口卡的大批量数据输入输出数据进行暂时存储
I、各类存储器的逻辑连接情况

image-20240114211250496

J、内存地址空间

image-20240114211447058

image-20240114211458240

一、(二)寄存器

CPU的主要部件

即可用指令读写部件

在CPU中:

image-20240115163045747

通用寄存器

AX、BX、CX、DX四种

一个寄存器能存储16位,同时可拆分为两个八位的寄存器

image-20240115163300610

字在寄存器的存储

8086CPU可一次性处理两种尺寸的数据

image-20240115163442621

image-20240115163542889

几条汇编指令
汇编指令控制CPU完成的操作用高级语言的语法描述
mov ax,18将18送入寄存器AXAX=18
mov ah,78将78送入寄存器AHAH=78
add ax,8将寄存器AX中的数值加上8AX=AX+8
mov ax,bx将寄存器BX中的数据送入寄存器AXAX=BX
add ax,bx将AX和BX中的数值相加,结果存在AX中AX=AX+BX

image-20240115164042535

image-20240115164106396

即超出的位会被“丢弃”

image-20240115164149204

正确的指令和错误的指令:

image-20240115164221471

物理地址

即每个内存单元在此空间中的唯一地址,称为物理地址

16位结构的CPU

一次性处理、传输、暂时存储的信息最大长度为16位

8086CPU给出物理地址的方法

image-20240115174525090

段地址x16+偏移地址=物理地址的本质含义

CPU在访问内存时,用基础地址一个相对基础地址的偏移地址相加,给出内存单元物理地址

形象比喻:

image-20240115175028948

image-20240115175045481

段的概念

即对内存地址的划分,不是物理意义上的分段

段寄存器

即形如:CS,DS,SS,ES的寄存器,可提供该内存单元的段地址

CS和IP

CS为代码段寄存器,IP为指针寄存器

在8086PC机中,如若CS的内容为M,IP的内容为N,8086CPU将从内存Mx16+N单元开始,读取指令执行

亦或如此理解:8086机中,任意时刻,CPU将CS:IP指向的内容当成指令执行

image-20240115182035572

如果内存内的一段信息曾被CPU执行过的话,那么,它所在的内存单元必然被CS:IP指向过

修改CS、IP的指令

jmp命令:转移指令

jmp 段地址:偏移地址

image-20240115182608433

jmp 某一合法寄存器

用寄存器中的值修改IP

代码段

若有一段N字节的指令,存放在指定的一组内存单元内,那么就可认为,这组内存单元即用来存放代码的,是一个代码段长度为N个字节

小结

image-20240115183702946

实验一:查看PDF:Debug指令表

image-20240115184212389

一、(三)寄存器(内存访问)

内存中字的存储:字单元

字单元的概念:即存放一个字形数据(16位)的内存单元,由两个地址连续的内存单元组成

起始地址为N的字单元简称为N地址单元

PS:任何两个地址连续的内存单元,N号单元和N+1号单元,也可看成两个内存单元,也可看成一个地址为N的字单元中的高位字节单元和低位字节单元

020H
14EH
212H
300H
4
5

image-20240116161100492

DS和[address]

DS寄存器:存放要访问数据段地址

mov al,[0]
//[]代表从内存单元偏移地址为零取出数值,而如果不指定,则将会从段地址寄存器ds取出

PS:不能直接mov ds,1000H之类的操作,只能中转,即由一般寄存器存放后,转移到ds

字的传送

mov指令,可在寄存器和内存之间进行字节型数据的传送

例子:

image-20240116175223828

mov(传送)、add(相加)、sub(相差)命令

mov:

指令方式例子
mov 寄存器,数据mov ax,8
mov 寄存器,寄存器mov ax,bx
mov 寄存器,内存单元mov ax,[0]
mov 内存单元,寄存器mov [0],ax
mov 段寄存器,寄存器mov ds,ax

image-20240116175658044

数据段

一组包含数据内存单元,然后将其导入ds,即可通过ds访问数据段中的具体单元

image-20240116181612819

小结:

image-20240116181721798

image-20240116181728830

数据结构:一种概念,后进先出

CPU提供的栈机制

push和pop指令,和栈是同理的

引出两个寄存器:段寄存器SS和寄存器SP,SS:SP指向栈顶元素

栈顶超界问题

只能自己注意,8086CPU没有对应的措施

push、pop命令

一些命令:

形式解释
push 寄存器将一个寄存器中的数据入栈
pop 寄存器出栈,用一个寄存器接收出栈的数据
push 段寄存器同上的push
pop 段寄存器同上的pop
push 内存单元将一个内存单元处的字入栈(栈操作均以字为单位)
pop 内存单元出栈,用一个内存单元接收出栈的数据
栈的综述

image-20240116190810151

栈段

栈占用内存空间

一个栈段最大容量64KB

栈的综述

image-20240116191759852

实验二、看PDF

一、(四)第一个程序

一个源程序从写出到执行的过程
步骤实际工作结果
编写汇编源程序产生了一个存储原程序的文本文件
对源程序进行编译链接产生了一个可在操作系统中运行的可执行文件
执行可执行文件中的程序操作系统根据描述信息,进行相关初始化并执行程序
源程序

image-20240117154032186

1、伪指令
指令解释
XXX segment和 XXX ends定义一个段,segment代表段开始,ends代表段结束
end汇编语言的结束标记
assume将有特定用途的段和相关的段寄存器关联
2、源程序中的“程序”

这里的程序指的是源程序最终由计算机执行、处理的指令数据

image-20240117154825350

3、标号

标号指代了一个地址

例如刚刚的codesg作为一个段的名称,最终将被编译、链接程序处理为一个段的段地址

4、程序的结构

形如写代码的框架

image-20240117155230625

5、程序返回

目前尚未解释

但指明:

使用

mov ax,4c00H
int 21H

即可使得程序返回

与结束相关的概念:

目的相关指令指令性质指令执行者
通知编译器一个段的结束段名 ends伪指令编译时,由编译器执行
通知编译器程序结束end伪指令编译时,由编译器执行
程序返回mov ax,4c00H int 21H汇编指令执行时,由CPU执行
6、语法错误和逻辑错误

和正常的写代码时的错误差不多

编辑源程序

也就是写代码

这里使用DOSBOX

DOS中输入edit

然后输入程序

保存为C:\1.asm

assume cs:codesg

codesg segment

	mov ax,0123h
	mov bx,0456h
	add ax,bx
	add ax,ax
	
	mov ax,4c00h
	int 21h
	
codesg ends

end
编译

使用MASM5.0即可

下载MASM5.0后跳转到其目录,然后

输入masm.exe运行masm

过程如图所示:

image-20240117172601232

连接

生成可执行文件,步骤如图:

image-20240117172904862

以简化的方式进行编译和连接

即使用

masm c:\1;(省略后缀)

link 1;

生成1.exe

程序执行过程的跟踪

使用Debug 1.exe即可

PSP:程序段前缀的数据区

这里讲解了我们的程序加载在内存的什么地方

而这个地方即ds:0,也就是PSP后,PSP在内存区前0-255,程序就会从256开始

通俗易懂的计算:
从ds可得知PSP的段地址SA,又PSP的偏移地址为0,那么PSP物理地址为SA*16+0,又因为PSP占256字节(100H),那么程序的物理地址为:SA*16+0+256=SA*16+16*16+0=(SA+16)*16+0

用段地址和偏移地址表示为:SA+10H:0

在Debug中使用T命令单步执行程序中每个指令,到了int 21,使用P命令,然后使用Q命令退出debug

实验三:看pdf:必须完成

一、(五)[BX]和loop指令

一些描述:
[bx]和内存单元的描述

注意到[0]作为表示内存单元,即解释:

[0]表示一个内存单元时,0表示单元的偏移地址,段地址默认在ds中,单元的长度(类型)可以由具体指令中的其他操作对象(比如说寄存器)指出

[bx]也同样为表示内存单元,即解释:

[bx]表示一个内存单元你是,它的偏移地址在bx中,段地址默认在ds中,单元的长度(类型)可以由具体指令中的其他操作对象(比如说寄存器)指出

loop

循环的含义

定义的描述性符号:“()”

"()"表示一个寄存器或一个内存单元中的内容:

比如:

(ax)表示ax中的内容、(al)表示al中的内容;

应用:

image-20240118171529998

约定符号idata表示常量

image-20240118171638050

[BX]

功能:

注意等号应该为赋值的意思,不是相等

image-20240118171832132

Loop指令

格式:loop 标号

CPU执行loop指令的时候,进行两步操作:

  1. (cx)=(cx)-1;
  2. 判断cx中的值,必为零则转至标号处执行程序,如果为零则向下执行

可知:cx的值影响loop指令的执行结果,通常:loop指令实现循环功能,cx中存放循环次数。

image-20240118172419685

Debug跟踪loop

要点:G命令可指定执行次数,

用法:g IP

这里的IP即让指针在IP时继续对loop的指令执行

要点:P命令可一次性执行完所有次数

Debug和汇编编译器masm对指令的不同处理

简述:Debug视mov ax,[0]的操作中[idata]为内存单元,而编译器解释为idata

那么统一:mov ds,ax后,使用mov al,ds:[0]

即显式地给出段地址所在的段寄存器

loop和[bx]的联合应用

image-20240118173926473

程序对比:

image-20240118173953669

image-20240118174008966

段前缀

image-20240118174104711

一段安全的空间

image-20240118174200285

image-20240118174221298

段前缀的使用

即不过度设置ds

image-20240118174325878

实验四:看PDF

一、(六)包含多个段的程序

在代码段中使用数据

dw:定义字型数据,即defind word,可用在代码段中

标号start:与end start连用

end start:end后面的start可以提醒编译期程序的入口在什么地方

image-20240122152829786

程序的框架图

image-20240122152929883

在代码段中使用栈

也就是通过dw的形式,定义一个类似于数组的玩艺儿,把它当成栈来使用就可以了

将数据、代码、栈放入不同的段

通过name segment实现,然后通过mov 寄存器,name访问name段地址

实验五:看pdf实现

一、(七)更灵活的定位内存地址的方法

and 和 or 指令

and指令:逻辑与指令,按位进行与运算

or指令:逻辑或指令,按位进行或运算

关于ASCII码

如何显示在控制台中:将字符的ascii码输入显存中

以字符形式给出的数据

db:defind byte,定义数据,并将其存储在内存中,以’'单引号括起来的内容被视为字符形式,将会转化为ascii码存储到内存中

大小写转化的问题

一般来说,应该减去大写和小写之间的数值差:20,但在汇编中,我们应该通过二进制的方法,观察客至,第五位置决定了是否为大小写:自己观察或者看书即可知道了

[bx+idata]

表示一个内存单元:它的偏移地址为(bx)+idata(bx中的数值加上idata)

数学化的描述为:(ax) = ((ds)*16+(bx)+200)

可写为:

mov ax,[200+bx]
mov ax,200[bx]
mov ax,[bx].200
用[bx+idata]的方式处理数组

形象化:

C语言:a[i],b[i]

汇编语言:0[bx],5[bx]

SI和DI

和bx功能类似的寄存器,但是不能分开成bh,bl这样的两个八位寄存器,通常用来处理字符串,SI存储源(source),DI存储目的(Destination),这两个的i代表index

[bx+si]和[bx+di]

表示一个内存单元,偏移地址为(bx)+(si)(即bx中的数值加上si中的数值)

数学化描述为:

(ax) = ((ds)*16+(bx)+(si))

可写成以下格式

mov ax,[bx][si]

[bx+si+idata]和[bx+di+idata]

表示一个内存单元,偏移地址为(bx)+(si)+idata(即bx中的数值加上si中的数值,再加上idata)

数学化描述为:

(ax) = ((ds)*16+(bx)+(si)+idata)

可写成以下格式

mov ax,[bx+200+si]
mov ax,[200+bx+si]
mov ax,200[bx][si]
mov ax,[bx].200[si]
mov ax,[bx][si].200
不同寻址方式的灵活运用
  1. [idata]用一个常量来表示地址,可用于直接定位一个内存单元;
  2. [bx]用一个变量来表示内存地址,可用于间接定位一个内存单元;
  3. [bx+idata]用一个变量和常量表示地址,可在一个起始地址的基础上用变量间接定位一个内存单元
  4. [bx+si]用两个变量表示地址
  5. [bx+si+idata]用两个变量和一个常量表示地址

一般来说,在需要暂存数据的时候,都应该使用栈

实验六:实践课程中的程序

一、(八)数据处理的两个基本问题

前置知识

描述型符号:reg和sreg

reg的集合:ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si,di

sreg的集合:ds,ss,cs,es

bx、si、di和bp
  1. 在8086CPU中,只有这四个寄存器可以用在"[…]"中来进行内存单元的寻址
  2. 在[…]中,这四个寄存器可以单个出现,或只能以四种组合出现:bx和si、bx和di、bp和si、bp和di
  3. 只要在[…]中使用寄存器bp,而指令中没有先行的给出段地址,段地址就默认在ss中
机器指令处理的数据在什么地方

指令执行前一刻,所要处理数据所在的位置:CPU内部、内存、端口

机器码汇编指令指令执行前数据的位置
8E1E0000mov bx,[0]内存,ds:[0]单元
89C3mov bx,axCPU内部,ax寄存器
BB0100mov bx,1CPU内部,指令缓冲器
汇编语言中数据位置的表达
  1. 立即数(idata)
    即直接包含在机器指令中的数据(执行在CPU的指令缓冲器中),在汇编语言中称为立即数(idata),在汇编指令中直接给出
  2. 寄存器
    指令要处理的数据啊在寄存器中,在汇编指令中给出相对应的寄存器名
  3. 段地址(SA)和偏移地址(EA)
    指令要处理的数据在内存中,在汇编指令中可用[X]的格式给出EA,SA在某个段寄存器中
寻址方式

image-20240123181050382

指令要处理的数据有多长
  1. 通过寄存器名指明要处理的数据的尺寸
  2. 在没有寄存器名存在的情况下,用操作符X ptr指明内存单元的长度,X在汇编指令中可以为word或者byte
  3. 其他方法
寻址方式的综合应用

以不同方式用在合理的地方

div指令

div是除法指令

注意的问题:

  1. 除数:有8位和16位两种,在一个reg或内存单元中
  2. 被除数:默认放在AX或DX和AX中,如果除数位8位,则被除数为16位,默认在AX中存放;如果除数位16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位
  3. 结果:如果被除数位8位,则AL存储除法操作的商,AH存放除法操作的余数;如果除数位16位,则AX存储除法操作的商,DX存储除法操作的余数
伪指令dd

用来定义dword(double word,双字)型数据的

dup

操作符,用来进行数据的重复。

image-20240123182431224

实验七:寻址方式在结构化数据访问中的应用:这个是对从前学习的最好实践

一、(九)转移指令的原理

前置知识

可以修改IP,或同时修改CS和IP的指令统称为转移指令,即,可以控制CPU执行内存中某处代码的指令

8086CPU的转移行为有:

  • 只修改IP时,称为段内转移,比如:jmp ax
  • 同时修改CS和IP时,称为段间转移,比如:jmp 1000:0

由于转移指令对IP的修改范围不同,段内转移又分为:短转移和近转移

  • 短转移IP的修改范围为-128~127
  • 近转移IP的修改范围位-32768~32767

8086CPU的转移指令分为以下几类

  • 无条件转移指令(jmp)
  • 条件转移指令
  • 循环指令(loop)
  • 过程
  • 中断
操作符offset

功能是取得标号的偏移地址

image-20240123183404029

image-20240123183414962

jmp指令

无条件转移指令,可以只修改IP,也可同时修改CS和IP

jmp要给出两种信息:

  1. 转移的目的地址
  2. 转移的距离(段间转移、段内短转移、段内近转移)
根据位移进行转移的jmp指令

image-20240123183723491

image-20240123183807550

转移的目的地址在指令中的jmp指令

jmp far ptr 标号实现的是段间转移,又称为远转移

image-20240123184035669

转移地址在寄存器中的jmp指令

功能格式:jmp 16位reg

功能:(IP)=(16位reg)

转移地址在内存中的jmp指令

两种格式:

  1. jmp word ptr 内存单元地址(段内转移)
    功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址

  2. jmp dword ptr 内存单元地址(段间转移)
    功能:从内存单元地址处开始存放着两个字,高地指出的字是转移的目的段地址,低地址处是转移的目的偏移地址

    (CS)=(内存单元地址+2)

    (IP)=(内存单元地址)

jcxz指令

指令形式:jcxz 标号(如果(cx)=0),转移到标号处执行

操作:当(cx)=0时,(IP)=(IP)+8位位移

image-20240123184818135

loop指令

image-20240123190037475

image-20240123190043679

根据位移进行转移的意义

jmp short 标号

jmp near ptr 标号

jcxz 标号

loop 标号

image-20240123190210941

编译器对转移位移超界的检测

image-20240123190317786

实验八:分析一个奇怪的程序
实验九:根据材料编程

一、(十)CALL和RET指令

前置知识

这两个命令都是转移指令,都修改IP,或同时修改CS和IP。经常被共同用来实现子程序的设计。

ret和retf

用栈中的数据

指令修改什么IP或CS和IP的变化
retIP,实现近转移1、(IP)=((ss)*16+(sp));2、(sp)=(sp)+2
retfCS和IP,实现远转移1、(IP)=((ss)*16+(sp));2、(sp)=(sp)+2;3、(CS)=((ss)*16+(sp));4、(sp)=(sp)+2
执行ret指令时相当于进行:pop IP;执行retf指令时相当于进行:pop IP和pop CS
call指令

执行call指令时:

  1. 将当前的IP或CS和IP压入栈中
  2. 转移
根据位移进行转移的call指令

call 标号(将当前的IP压入栈后,转移到标号处执行指令)

执行此格式的call指令时,进行:

  1. (sp)=(sp)-2
    ((ss)*16+(sp))=(IP)
  2. (IP)=(IP)+16位位移

image-20240124170020069

其实相当于:

push IP

jmp near ptr 标号

转移的目的地在指令中的call指令

call far ptr 标号 实现的是段间转移

执行此格式的call指令时,进行如下操作。

  1. (sp)=(sp)-2
    ((ss)*16+(sp))=(CS)
    (sp)=(sp)-2
    ((ss)*16+(sp))=(IP)
  2. (CS)=标号所在段的段地址
    (IP)=标号在段中的偏移地址

相当于:

push CS

push IP

jmp far ptr 标号

转移地址在寄存器中的call指令

指令格式:call 16位reg

功能:

(sp)=(sp)-2

((ss)*16+(sp))=(IP)

(IP)=(16位reg)

相当于:

push IP

jmp 16位reg

转移地址在内存中的call指令
  1. call word ptr 内存单元地址
    相当于:
    push IP
    jmp word ptr 内存单元地址

  2. call dword ptr 内存单元地址
    相当于:
    push CS

    push IP

    jmp dword ptr 内存单元地址

call和ret的配合使用

用于编写一个具有一定功能的程序段,称为子程序;框架如下;

image-20240124171033392

image-20240124171052341

mul指令

乘法指令

注意要点:

  1. 两个相乘的数:位数相同,8位对8位,16位对16位
  2. 结果:如果是8位,结果默认放在AX中;如果是16位,结果高位默认在DX中存放,低位在AX中放

格式:

  1. mul reg
  2. mul 内存单元
模块化程序设计

使用call和ret指令

参数和结果传递的问题

用寄存器存储参数和结果

  1. 对于调用者:将参数送入参数寄存器,从结果寄存器中取得返回值;
  2. 对于子程序:从参数寄存器中取得参数,将返回值送入结果寄存器;
批量数据的传送

使用栈或连续的内存空间,然后使用其首地址

寄存器冲突的问题

子程序编写标准框架,如下:

image-20240124172245262

实验十:编写子程序

一、(期中)课程设计一

一、(十一)标志寄存器

前置知识

特殊寄存器:标识寄存器的作用

  1. 用来存储相关指令的某些执行结果
  2. 用来为CPU执行相关指令提供行为依据
  3. 用来控制CPU的相关工作方式

简称:flag

1514131211109876543210
OFDFIFTFSFZFAFPFCF

flag的图上空白的位在8086CPU没有使用,不具有含义,其余有含义

ZF标志
  • 零标志位。用于记录相关指令执行后,期结果是否为0。如果结果为0,那么zf=1;如果结果不为0,那么zf为0
PF标志
  • 奇偶标志位。用于记录相关指令执行后,其所有结果中的所有bit位中1的个数是否位偶数,如果是,则,pf=1,否则pf=0
SF标志
  • 符号标志位。用于记录相关指令执行后,其结果是否为负。如果是,则sf=1,非负则sf=0
CF标志
  • 进位标志位。记录运算结果的最高有效位向更高位的进位值,或从更高位的借位值
OF标志
  • 溢出标志位。一般情况下,OF记录了有符号数运算的结果是否发生了溢出,如果是,则OF=1;如果没有,OF=0
  • CF和OF的区别:CF是对无符号数运算有意义的标志位,而OF是对有符号数运算有意义的标志位
abc指令

带进位加法指令,利用的就是就是CF位上记录的进位值

指令格式:

abc 操作对象1,操作对象2

功能:操作对象1 = 操作对象1 + 操作对象2 + CF

abc指令和add指令相配合就能对更大的数据进行加法运算

sbb指令

带借位减法指令,利用CF位上记录的借位值

指令格式:sbb 操作对象1,操作对象2

功能:操作对象1 = 操作对象1 - 操作对象2 - CF

sbb指令可以对任意大的数据进行减法运算

cmp指令

比较指令,功能相当于减法指令,但不保存结果,会对flag产生影响

指令格式:

cmp 操作对象1,操作对象2

功能:

计算操作对象1 - 操作对象2,但不保存结果

  1. 如果因为溢出导致实际结果为负,那么逻辑上,真正的结果必然为正
  2. 反之为负
通过比较结果的条件转移指令

image-20240124174808376

image-20240124174825279

DF标志和串传送指令
1、DF标志

方向标志位,控制每次操作后si、di的增减

2、串传送指令
1️⃣、movsb

功能:将ds:si指向的内存单元中的字节送入es:di中,根据标志寄存器df位的值,将si和di递增或递减

相当于:

  1. ((es)*16+(di))=((ds)*16+(si))
  2. 如果df=0则:(si)=(si)+1
    (di)=(di)-1
    如果df=1则:(si)=(si)-1
    (di)=(di)-1
2️⃣、movsw

功能:将ds:si指向的内存字单元中的字送入es:di中,然后根据标志寄存器df位的值,将si和di递增2或递减2

3️⃣、总结

一般来说,movsb和movsw都和rep配合使用,格式如下:rep movsb

功能:

s:movsb

​ loop s

image-20240124182340880

pushf和popf

pushf:将标志寄存器的值压栈

popf:从栈中弹出数据,送入flag中

标志寄存器在Debug中的表示

标志值为1的标记值为0的标记
ofOVNV
sfNGPL
zfZRNZ
pfPEPO
cfCYNC
dfDNUP
实验十一:编写子程序

一、(十二)内中断

前置知识
中断信息:如若从外部或者内部检测到产生了一中特殊信息,则立即队所接受到的信息进行处理(中断:CPU不再接着(刚执行完的指令)向下执行,转去处理这个特殊信息)
内中断的产生
产生以下情况时,产生对应的中断信息:
  1. 除法错误,比如,执行div指令产生的除法溢出
  2. 单步执行
  3. 执行into指令
  4. 执行int指令
中断码如下:
  1. 除法错误:0
  2. 单步执行:1
  3. 执行into指令:4
  4. 执行int指令,该指令的格式位int n,指令中的n为字节型立即数,是提供给CPU的中断类型码
中断处理程序

用来处理中断信息的程序

根据8位的中断类型码得到中断处理程序的段地址和偏移地址

中断向量表

CPU通过8位的中断类型码的中断向量表处理中断程序的入口地址,这里的中断向量的列表就是中断向量表:中断处理程序入口地址的列表

image-20240125152105895

一个表项存放一个中断向量,也就是一个中断处理程序的入口地址:包括段地址和偏移地址,占两个字,高地址字存放段地址,低地址字存放偏移地址

中断过程

用中断类型码找到中断向量,并用它设置CS和IP,这个过程就是中断过程

8086CPU在 收到信息后,所引发的中断过程:
  1. (从中断信息中)取得中断类型码
  2. 标志寄存器的值入栈
  3. 设置flag的第8位TF和第九位IF的值位0
  4. CS的内容入栈
  5. IP的内容入栈
  6. 从内存地址为中断类型码*4和中断类型码*4+2的两个字单元中读取中断处理程序的入口地址设置IP和CS
简洁地描述中断过程:
  1. 取得中断类型码N
  2. pushf
  3. TF=0,IF=0
  4. push CS
  5. push IP
  6. (IP)=(N*4),(CS)=(N*4+2)
中断处理程序和iret指令
中断处理程序的编写方法:
  1. 保存用到的寄存器
  2. 处理中断
  3. 恢复用到的寄存器
  4. 用iret指令返回
iret指令的汇编语法描述:
pop IP
pop CS
popf
除法错误中断的处理

显示提示信息“Divide overflow”后,返回操作系统中

编程处理0号中断
  1. 编写可以显示"overflow!"的中断处理程序:do0
  2. 将do0送入内存0000:0200处
  3. 将do0的入口地址0000:0200存储在中断向量表0号表项中

框架如下:

image-20240125154317636

  1. 安装do0,设置中断向量的程序
  2. do0
安装

可使用movsb指令,将do0的代码送入0:200处

程序如下:

assume cs:code
code segment

	start:设置es:di指向目的地址
		  设置ds:si指向源地址
		  设置cx为传输长度
		  设置传输方向为正
		  rep movsb
		  
		  设置中断向量表
		  
		  mov ax,4c00h
		  int 21h
		  
	do0:显示字符串"overflow!"
		mov ax,4c00h
		int 21h
		
code ends
end start
使用rep movsb指令要确定的信息:
  1. 传送的原始位置,段地址:code,偏移地址:offset do0
  2. 传送的目的位置:0:200
  3. 传送的长度:do0部分代码的长度
  4. 传送的方向:正向

更明确的程序:

image-20240125160508972

do0

程序如下:

image-20240125160546414

更完善的代码:

image-20240125160653962

设置中断向量

image-20240125160724190

单步中断

image-20240125160804316

响应中断的特殊情况

image-20240125160906881

实验十二:编写0号中断的处理程序

一、(十三)int指令

int指令

格式为:int n;n为中断类型码,功能是引发中断过程

执行过程:

  1. 取中断类型码n
  2. 标志寄存器入栈,IF=0,TF=0;
  3. CS、IP入栈
  4. (IP)=(n*4),(CS)=(n*4+2)

int指令的最终功能和call指令类似,都是调用一段程序

编写供应用程序调用的中断例程

避免寄存器的冲突,注意寄存器值的保存和恢复

对int、iret和栈的深入了解

也就是如何利用这三个指令实现loop功能

BIOS和DOS所提供的中断例程

BIOS中主要包括以下几部份内容

  1. 硬件系统的检测和初始化程序
  2. 外部中断和内部中断的中断例程
  3. 用于对硬件设备进行I/O操作的中断例程
  4. 其他和硬件系统相关的中断例程

image-20240129171156989

BIOS和DOS中断例程的安装过程

image-20240129171223226

BIOS中断例程应用

int 10h中断例程是BIOS提供的中断例程,包含多个和屏幕相关的子程序

BIOS和DOS提供和的中断例程一般用ah传递内部子程序的编号

image-20240129171416922

image-20240129171431581

image-20240129171442927

DOS中断例程的应用

image-20240129171525469

image-20240129171606666

实验十三、编写、应用中断例程

一、(十四)端口

端口的读写

image-20240129171747507

image-20240129171806652

CMOS RAM芯片

image-20240129171852990

shl和shr指令

逻辑位移指令

image-20240129171926240

image-20240129171938959

CMOS RAM中存储的时间信息
实验十四、访问CMOS RAM

一、(十五)外中断

接口芯片和端口

CPU通过端口和外部设备进行联系

外中断信息
1、可屏蔽中断

image-20240129172208865

2、不可屏蔽中断

image-20240129172234437

PC机键盘的处理过程
1、键盘输入

image-20240129172327054

image-20240129172337137

image-20240129172408776

2、引发9号中断

image-20240129172506032

3、执行int 9中断例程

image-20240129172530834

编写int 9中断例程
1、从端口60h读出键盘输入

int al,60h

2、调用BIOS的int 9中断例程

image-20240129172723773

3、如果是Esc的扫描码,改变显示的颜色后返回
安装新的int 9中断例程

image-20240129172839856

实验十五、安装新的int 9中断例程

指令系统总结

8086CPU提供以下几大类指令。

1.数据传送指令

​ 比如,mov、push、pop、pushf、.popf、xchg等都是数据传送指令,这些指令实现寄存器和内存、寄存器和寄存器之间的单个数据传送。

2.算术运算指令

比如,add、sub、adc、sbb、inc、dec、cp、imul、idiv、aaa等都是算术运算指令,这些指令实现寄存器和内存中的数据的算数运算。它们的执行结果影响标志寄存器的sf、zf、of、cf、pf、af位。

3.逻辑指令

比如,and、or、not、xor、test、shl、shr、sal、sar、rol、Ior、rcl、Icr等都是逻辑指令。除了not指令外,它们的执行结果都影响标志寄存器的相关标志位。

4.转移指令

​ 可以修改P,或同时修改CS和P的指令统称为转移指令。转移指令分为以下几类。

  1. 无条件转移指令,比如,jmp:
  2. 条件转移指令,比如,jcxz、je、jb、ja、jnb、jna等:
  3. 循环指令,比如,loop:
  4. 过程,比如,call、Iet、retf
  5. 中断,比如,int、iret。
5.处理机控制指令

​ 这些指令对标志寄存器或其他处理机状态进行设置,比如,cld、std、ci、sti、nop、clc、cmc、stc、hlt、wait、esc、lock等都是处理机控制指令。

6.串处理指令

​ 这些指令对内存中的批量数据进行处理,比如,movsb、movsw、cmps、scas、lods、stos等。若要使用这些指令方便地进行批量数据的处理,则需要和rep、repe、repne等前缀指令配合使用。

一、(十六)直接定址表

描述单元长度的标号

即a db 1,2,3,4,5,6

image-20240129173724060

image-20240129173749939

在其他段中使用数据标号

image-20240129174010719

直接定址表

image-20240129174115127

程序入口地址的直接定址表

image-20240129174156467

image-20240129174207763

实验十六:编写包含多个功能子程序的中断例程

一、(十七)使用BIOS进行键盘输入和磁盘读写

不可屏蔽中断

[外链图片转存中…(img-FzAjfl8f-1713970527606)]

PC机键盘的处理过程
1、键盘输入

[外链图片转存中…(img-ElUvUG9z-1713970527606)]

[外链图片转存中…(img-g1fD0qU9-1713970527607)]

[外链图片转存中…(img-DmyDDPTk-1713970527607)]

2、引发9号中断

[外链图片转存中…(img-wNyGr6uR-1713970527607)]

3、执行int 9中断例程

[外链图片转存中…(img-jkUJDX80-1713970527607)]

编写int 9中断例程
1、从端口60h读出键盘输入

int al,60h

2、调用BIOS的int 9中断例程

[外链图片转存中…(img-5NloEgOZ-1713970527607)]

3、如果是Esc的扫描码,改变显示的颜色后返回
安装新的int 9中断例程

[外链图片转存中…(img-8sVOhkfn-1713970527608)]

实验十五、安装新的int 9中断例程

指令系统总结

8086CPU提供以下几大类指令。

1.数据传送指令

​ 比如,mov、push、pop、pushf、.popf、xchg等都是数据传送指令,这些指令实现寄存器和内存、寄存器和寄存器之间的单个数据传送。

2.算术运算指令

比如,add、sub、adc、sbb、inc、dec、cp、imul、idiv、aaa等都是算术运算指令,这些指令实现寄存器和内存中的数据的算数运算。它们的执行结果影响标志寄存器的sf、zf、of、cf、pf、af位。

3.逻辑指令

比如,and、or、not、xor、test、shl、shr、sal、sar、rol、Ior、rcl、Icr等都是逻辑指令。除了not指令外,它们的执行结果都影响标志寄存器的相关标志位。

4.转移指令

​ 可以修改P,或同时修改CS和P的指令统称为转移指令。转移指令分为以下几类。

  1. 无条件转移指令,比如,jmp:
  2. 条件转移指令,比如,jcxz、je、jb、ja、jnb、jna等:
  3. 循环指令,比如,loop:
  4. 过程,比如,call、Iet、retf
  5. 中断,比如,int、iret。
5.处理机控制指令

​ 这些指令对标志寄存器或其他处理机状态进行设置,比如,cld、std、ci、sti、nop、clc、cmc、stc、hlt、wait、esc、lock等都是处理机控制指令。

6.串处理指令

​ 这些指令对内存中的批量数据进行处理,比如,movsb、movsw、cmps、scas、lods、stos等。若要使用这些指令方便地进行批量数据的处理,则需要和rep、repe、repne等前缀指令配合使用。

一、(十六)直接定址表

描述单元长度的标号

即a db 1,2,3,4,5,6

[外链图片转存中…(img-eB68mGnB-1713970527608)]

[外链图片转存中…(img-JcsFYYQw-1713970527608)]

在其他段中使用数据标号

[外链图片转存中…(img-JvRN6uTg-1713970527609)]

直接定址表

[外链图片转存中…(img-zY4hvEPQ-1713970527609)]

程序入口地址的直接定址表

[外链图片转存中…(img-tUpZJLeF-1713970527609)]

[外链图片转存中…(img-Vk7BwjUl-1713970527609)]

实验十六:编写包含多个功能子程序的中断例程

一、(十七)使用BIOS进行键盘输入和磁盘读写

一、(综合研究)

  • 20
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你好!很高兴回答你的问题。关于软件安全实验二中的攻击方式Pwn,我可以为你提供一些基本的信息。Pwn是指通过利用软件漏洞来获取对计算机系统的控制权。在实验二中,你可能会学习和尝试使用缓冲区溢出漏洞、格式化字符串漏洞、堆溢出等技术来进行Pwn攻击。 缓冲区溢出是一种常见的Pwn攻击技术,它利用了程序在处理输入数据时没有正确限制长度的漏洞。通过向程序输入过长的数据,可以覆盖到程序运行时的内存空间中的其他重要数据,例如返回地址。通过修改返回地址,攻击者可以控制程序流程,执行恶意代码。 格式化字符串漏洞是另一种常见的Pwn攻击技术。它利用了C语言的格式化字符串函数(如printf、sprintf等)在处理格式化字符串时存在的安全问题。通过向程序输入特定格式的字符串,攻击者可以读取或修改内存中的数据,甚至执行任意代码。 堆溢出是利用堆内存管理中的漏洞进行攻击的一种技术。在使用动态分配内存时,如果没有正确地释放或管理内存,可能会导致堆溢出。通过在堆中溢出写入数据,攻击者可以修改关键数据结构,从而影响程序的执行逻辑。 以上只是Pwn攻击的一些基本概念,实际的Pwn攻击还涉及很多技术和细节。在进行任何Pwn攻击之前,请务必遵循法律和道德规范,并确保你在合法授权的环境中进行实验。 如果你有任何关于Pwn攻击或软件安全实验的具体问题,我会尽力为你解答。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为拆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值