0x01 通用寄存器
32位16位8位编号(二进制)编号(十进制)
32位 16位 8位 编号(二进制) 编号(十进制)
EAX AX AL 0 0
ECX CX CL 1 1
EDX DX DL 10 2
EBX BX BL 11 3
ESP SP AH 100 4
EBP BP CH 101 5
ESI SI DH 110 6
EDI DI BH 111 7
0x02 mov指令
mov 目标操作数,源操作数
1. 源操作数可以是立即数,通用寄存器 段寄存器 或者内存单元
2.目标操作数,可以试试通用寄存器、段寄存器、内存单元
3.操作数宽度必须相同
4.源操作数和目标操作数不能同时位内存单元、
0x03 内存
寄存器与内存区别:
1.寄存器位于CPU内部,执行速度快,但比较贵。
2.内存速度相对角门,但成本低,所以可以做的 很大。
3.寄存器和内存没有本质区别,都是存储数据的,都是定宽的。
4.寄存器常用的有8个。
5.计算机中的几个常用计量单位: BYTE WORD DWORD
6.内存数量特别庞大,用编号来代替,我们称计算机CPU是32位或64位。
每块内存有唯一的编号, 编号以字节为单位,(8bit),
则 32位CPU可以识别内存 FFFFFFFF+1=100000000 bit =4G
内存格式
1.每块内存单元宽度为8
2.【】称为地址
3.地址的作用:当我们向内存中读取数据或者向内存中写数据。
mov,dword ptr ds:[0x8fffffff],0x12345678
可以访问的是ESP
0x04 寻址方式
1.寻址公式-:[立即数]
读取内存的值:
mov EAX,dword ptr ds:[0x13ffc4]
mov eax,dword ptr ds:[0x13ffc8]
向内存中写入数据
mov dword ptr ds:[0x13ffc4],eax
mov dword ptr ds:[0x13ffc8],eax
获取内存编号
lea eax,dword ptr ds:[0x13ffdd]
lea eax,dword ptr ds:[esp+8]
2.寻址公式二:[reg] 将reg中的值,作为内存编号进行寻址
读取内存的值:
mov ecx,0x13ffdd
mov eax,dword ptr ds:[ecx]
向内存中写入数据:
mov edx,0x13ffdd
mov dword ptr ds:[edx],0x12345678
获取内存编号:
lea eax,dword ptr ds:[edx]
mov eax,dword ptr ds:[edx]
3.寻址公式三:[reg + 立即数]
读取内存的值:
mov ecx,0x13ffdd
mov eax,dword ptr ds:[ecx+4]
向内存中写入数据:
mov edx,0x13ffdd
mov dword ptr ds:[edx+0x12345678],0x12345678
获取内存编号:
lea eax,dword ptr ds:[edx+4]
mov eax,dword ptr ds:[edx+4]
4.寻址公式四:[reg + reg*{1,2,4,8}]
读取内存的值:
mov ecx,0x13ffdd
mov eax,dword ptr ds:[ecx+ecx*4]
向内存中写入数据:
mov edx,0x13ffdd
mov ecx,2
mov dword ptr ds:[edx+ecx*4],0x12345678
获取内存编号:
lea eax,dword ptr ds:[ecx+ecx*4 ]
5.寻址公式四:[reg + reg*{1,2,4,8}+立即数]
读取内存的值:
mov ecx,0x13ffdd
mov eax,dword ptr ds:[ecx+ecx*4+4]
向内存中写入数据:
mov ecx,2
mov edx,0x13ffdd
mov dword ptr ds:[edx+ecx*4+4],0x12345678
获取内存编号:
lea eax,dword ptr ds:[ecx+ecx*4+2 ]
0x05 堆栈
堆栈的优点:临时存储大量的数据,便于查找。
压入数据 :
方式一:
mov dword ptr ds:[edx-4],0xaaaaaaaa
sub edx,4
方式二:
sub edx,4
mov dword ptr ds:[edx],0xbbbbbbbb
方式三:
mov dword ptr ds:[edx-4],0xdddddddd
lea edx,dword ptr ds:[edx-4]
方式四:
lea edx,dword ptr ds:[edx-4]
mov dword ptr ds:[edx],0xeeeeeeee
读取第N个数
1.方式一:通过栈低加偏移来读取
读取第一个压入的数据:
mov esi,dword ptr ds:[ebx-4]
读取第四个压入的数据:
mov esi,dwordptr ds:[edx-0x10]
2.方式二:通过栈顶加偏移来读取
读取第二个压入的数据:
mov edi,dword ptr ds:[edx+4]
读取第三个压入的数据:
mov edi,dword ptr ds:[edx+8]
弹出数据
1.方式一:
mov ecx,dword ptr ds:[edx]
lea edx,dword ptr ds:[edx-4]
2.方式二:
mov esi,dword ptr ds:[edx]
add edx,4
3.方式三:
lea edx,dword ptr ds:[edx+4]
mov edi,dword ptr ds:[edx-4]
push 指令
1.push r32
2.push r16
3.push m16
4.push m32
5.push imm16/imm32/imm8
pop 指令:
1.pop r32
2.pop r16
3.pop m16
4.pop m32
堆栈保护
pushad 将8个通用寄存器存入堆栈中
popad 将数据恢复到通用寄存器
0x06 WIndows堆栈的特点
1.先进先出
2.向低地址扩展
什么是堆栈平衡
Windows堆栈,是一块普通的内存,主要用来存储一些临时的数据和参数。