1、pwn的前置知识之一需要汇编语言,在这里整理了mov、lea、add、sub、ret、call、push、pop这几种:
mov:
(片内RAM)传送指令MOV(Move)把一个字节、字或双字的操作数从源位置传送到目的位置,源操作数的内容不变。可以实现立即数到通用寄存器或主存的传送,通用寄存器与通用寄存器、主存或段寄存器之间的传送,主存与段寄存器之间的传送。该操作属于复制性质,不属于搬家性质。
格式:MOV DST,SRC(从SRC复制数值,覆盖DST)。
MOV EAX,#050aH ;将十六进制数050a 传送到通用寄存器eax中
MOV DI,BX(寄存器到寄存器之间传数)
MOV ES,AX(通用寄存器与段寄存器之间传数)
MOV AX,DS(段寄存器至通用寄存器)
MOV AL,23H(将立即数"复制"到寄存器)
MOV [2000H],02H(直接寻址)
MOV [2061H],BX
tips:
-
目的操作数要与源操作数类型要一致,不能一个是字,一个是字节
-
目的操作数要和源操作数类型之一必须要有明确的类型
-
立即数不能作为目的操作数
-
不能用立即寻址方式给段寄存器传数
-
源操作数和目的操作数不能同时为存储器操作数,即存储单元之间不能用MOV指令直接传送
-
CS和IP不能作为目的操作数,但CS可以作为源操作数。
-
段寄存器之间不能用MOV指令直接传送
-
在传送字单元时,遵循“高字节存放在高地址,低字节存放在低地址”的原则。
lea:
lea 0x4(%esp),%ecx
lea指令的作用是,取出esp寄存器中的值,加上4,不再继续寻址,而是将得到的值直接传递给ecx;
如果是其他指令,则还需要进行间接寻址,再将值传递给ecx寄存器。
add:
add 寄存器,数据
解释:将数据累加到寄存器中,比如寄存器当时是1,数据为2,则结果为3,此时寄存器所保存的值就是3.
sub:
减法指令,不带借位的减法指令。SUB (subtract) 指令的汇编格式:SUB dst,src 指令的基本功能:(dst)<-(dst)-(src)
指令支持的寻址方式:他们两个操作数不能同时为存储器寻址。即为除源操作数为立即数的情况外,源操作数和目地操作数必须有一个寄存器寻址方式。
指令对标志位的影响:SF=1 减法结果为负数(符号位为1) SF=0 减法结果为正数(符号位为0) ZF=1 减法结果为零 ZF=0 减法结果不为零。
CF=1 二进制减法运算中最高有效位向高位有借位(被减数小于减数,不够减的情况) CF=0 二进制减法运算中最高有效为向高位无借位(被减数〉=减数,够减的情况) OF=1 两数符号相反(正数-负数,或负数-正数),而结果符号与减数相同。
OF=0 同符号数相减时,或不同符号数相减,其结果符号与减数不同。
ret:
白话文一点的————RET指令是子程序的最后一条指令,即恢复断点,返回主程序。
没有要求RET指令非要和哪一条指令要配对使用。
RET是子程序返回指令,放在子程序的结尾,当子程序执行完后,靠该指令返回主程序。
专业术语的—————ret指令是从堆栈中退出pc的高8位和低8位字节,把堆栈指针减2,从pc值处开始继续执行程序。堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
call:
CALL指令用于调用其他函数(或过程,如果你这样叫的话)。 [1] 前提是,该函数必须在内存中。
分为两步。
(1)将下一条指令的所在地址(即当时程序计数器PC的内容)入栈,
(2)并将子程序的起始地址送入PC(于是CPU的下一条指令就会转去执行子程序)。
用途
CALL是调用子函数,而JMP是跳转(类似于C++的高级语言中的goto。) [1]
细节
CALL会操作调用栈,JMP不会。这意味着JMP不会回到原处。
tips:
call指令:
第一步:先将call指令的下一条指令的CS和IP入栈(当然如果是段间转移就要将CS和IP入栈,如果是段内转移就只要将IP入栈)
第二步:就是操作与call对应的jmp指令
所有的call指令都是可以用上面的两步来确定的,这是个通用的法则
push:
PUSH的操作过程是: (SP)<--(SP)-2,((sp))<--OPRD 即先修改堆栈指针SP(压入时为自动减2),然后,将指定 的操作数送入新的栈顶位置。
此处的((SP))<--OPRD,也可以理解为:
[(SS)*16+(SP)]<--OPRD 或 [SS:SP]<--OPRD
示例: PUSH DX
PUSH BP
PUSH CS
PUSH DATA1
PUSH ALFA[BX][SI]
tips: 每进行一次压入操作,都压入一个字(16位)。
pop:
POP是汇编语言中的指令是将堆栈段中的一个字单元弹出。
汇编语言中的POP指令
将堆栈段中的一个字单元弹出
指令执行后有两步:
1.将堆栈段中当前SS:SP所指的字内容弹出到某个寄存器或段寄存器或内存单元
2.SP←SP+2
POP为单操作数
格式:
POP 寄存器
POP 段寄存器 注:除 cs之外的段寄存器才可
POP 内存地址
例如:
POP AX
POP DS
POP [0]