0x01 释
本章是对王爽的第五第六章阅读的笔记 跳过了第四章 因为本人是对 逆向和APT感兴趣 对某一些 非必要的东西就剔除了
但第四章也有一些简要的内容
0x02 伪指令
伪代码:一般我们写的程序代码都是伪代码由编译器转化成对应的机器码的指令,才可以被及其执行。
segment 和ends是一对承兑使用的伪指令,这是可被汇编编译的指令
codesg segment ;这个段从这里开始
codesg ends ;这个段这里介绍
注codesg是段名
end是汇编程序的结束标记,编译器在编译汇编程序的过程中,碰到伪指令end就表示程序结束了
注: end和ends是两个指令 ends与 segment对应
assume: 这个指令时假设的意思寄存器和程序中某一段相关联,通过assume说明这种关联
例
assume cs:codesg
codesg segment
mov ax,0123H
codesg ends
end
注 这里codesg是 标号 是段的名称段的名称会被编译,连接程序处理为一个段的段地址。
0x03 [bx]和内存单元的描述
[BX]
mov ax,[bx]
功能:bx中存放的数据作为一个偏移地址EA,段地址SA默认在ds中,将SA:EA处的数据送入ax中,即(ax)=((ds)*16+(bx))
mov [bx],ax
功能:bx中存放的数据作为一个偏移地址EA,段地址SA默认在ds中,将ax中数据送入内存SA:EA处
简单来说就是同[0]一样但是他用的是寄存器来转
loop
loop循环指令:CX寄存器中的值影响着loop值如果CX的值不为0则向下执行,cx中通常存放着循环的次数
loop执行的过程有点像c++中的do…while
- 先执行一次 cx=cx-1 注这里的cx是指cx内的值
- 判断cx的值是否等于零
- 如果不为0则转到标号处如果为0执行其他指令(注,标号代表一个地址,它实际上表示了一个地址例如
code segment
mov ax,2
mov cx,11 ;这里是指下面的循环要执行11次
s: add ax,ax
loop s
mov ax,4c00h
int 21h
0x03 段前缀
例
mov ax,ss:[0] ;将ss:[0]内存单元中的值送给ax
ss就表示ss段前缀还有cs,ds,es等
0x04 一个安全空间
- 我们需要直接向一段内存中写入内容
- 这段内存空间不应存放系统或其他程序的数据或代码,否则写入操作很可能引发错误
- DOS方式下,一般情况0:200~0:2ff空间中没有系统或者其他程序的数据或代码
0x05 获取空间
合法地通过操作取得地空间都是安全地,因为操作系统不会让一个程序所用地空间和其他程序以及系统自己地空间相冲突。
获取空间地两种方法
- 加载程序地时候程序分配
- 程序在执行地过程中向系统申请(win32的内容)
加载程序的时候分配已经体验过额,必须要在源程序中做出声明。
0x06 在代码段中使用数据
dw
dw即 define word 定义了8个字型数据(数据之间可以用逗号隔开)他们所占的内存空间大小为16个字节
例
dw 0123h,0841h,0bedh,01a2h
dw由于它是代码段中,所以他一般运行的时候是存放在CS中存放代码段的段地址,所以可以从CS中获取段地址,又因为dw定义数据处于毒代码段的最开始,所以偏移地址为0,上面定义了四个数据,所以存偏移地址依次为0,2,4,6所以地址为cs:0,cs:2…
我们已经知道在单任务系统中他的执行步骤如下:
- 由其他程序(debug,command或其他程序)将执行文件载入内存;
- 设置CS:IP指向第一条要执行的指令(即程序入口),从而使程序得以运行
- 程序运行结束后,返回加载者
现在问题是,根据什么设置CPU的CS:IP指向程序的第一条要执行的指令?如何知道哪一条指令时程序的第一条执行的指令?这一点,是由可执行文件中的描述信息指明的。我们知道可执行文件由描述信息和程序组成,程序来自于源程序中的汇编程序和定义的数据;描述信息则主要时汇编,连接程序对源程序中相关伪指令进行处理所得到的信息。我们在之前的的学习中,用伪指令end描述了程序结束和程序的入口。在编译,连接后由“end start”指明程序入口,被转化为一个入口地址,存储在可执行文件的描述信息中。就是我们若要CPU从何处开始执行程序,只要在源程序中用”end 标号”指明就可以了。
0x07 将数据,代码,栈放入不同的段中
定义多个段的方法,定义一个段的方法和前面所讲的方法一样,只要用不同的段名去使用这一就可以很容易区分