寻址

寻址公式一:【立即数】

读取内存中的值:
MOV EAX,DWORD PTR DS:[0x13FFC4]

向内存中写入数据:
MOV DWORD PTR DS:[0x13FFC4],EAX

获取内存编号:
LEA EAX,DWORD PTR DS:[0x13FFC4]

寻址公式二:【reg】 可以是8个寄存器中的任意一个

读取内存中的值:
MOV EAX,DWORD PTR DS:[ECX]

向内存中写入数据:
MOV DWORD PTR DS:[ECX],0xAAAAAAAA

获取内存编号:
LEA EAX,DWORD PTR DS:[ESP]

寻址公式三:【reg+立即数】

读取内存中的值:
MOV EAX,DWORD PTR DS:[ECX+4]

向内存中写入数据:
MOV DWORD PTR DS:[ECX+0xC],0xAAAAAAAA

获取内存编号:
LEA EAX,DWORD PTR DS:[ESP+8]

寻址公式四:【reg+reg*{1,2,4,8}】

读取内存中的值:
MOV EAX,DWORD PTR DS:[EAX+ECX*4]

向内存中写入数据:
MOV DWORD PTR DS:[ECX+EAX*2],0xAAAAAAAA

获取内存编号:
LEA EAX,DWORD PTR DS:[ESP+EAX*8]

寻址公式五:【reg+reg*{1,2,4,8}+立即数】

堆栈

1、BASE,TOP是2个32位的通用寄存器,里面存储的是内存单元编号(内存地址)

2、BASE里面存储了一个地址,记录的起始地址.

3、TOP里面也存储了一个地址,记录的是结束的地址. win堆栈一般是从高到低,BASE>TOP

4、存入数据的时候,TOP的值减4(为方便演示,每次存取都是4个字节)

5、释放数据的时候,TOP的值加4(为方便演示,每次存取都是4个字节)

6、如果要读取中间的某个数据的时候可以通过TOP或者BASE加上偏移的方式去读取

7、这种内存的读写方式有个学名:堆栈 堆栈的优点:临时存储大量的数据,便查找

压入堆栈

MOV EBX,0x00CFF9C0   BASE
MOV EDX,0x00CFF9C0   TOP

方式一:
MOV DWORD PTR DS:[EDX-4],0xAAAAAAAA  先将数据存入TOP之后的内存
SUB EDX,4  将TOP减去4,移动TOP

方式二:
SUB EDX,4  先移动TOP
MOV DWORD PTR DS:[EDX],0xBBBBBBBB 再赋值

方式三:
MOV DWORD PTR DS:[EDX-4],0xDDDDDDDD  先赋值
LEA EDX,DWORD PTR DS:[EDX-4] 再移动TOP

方式四:
LEA EDX,DWORD PTR DS:[EDX-4] 先移动TOP 
MOV DWORD PTR DS:[EDX],0xEEEEEEEE 再赋值

读取第N个数

1. 通过BASE加偏移的方式来读取

读第一个压入的数据:
mov esi,dword ptr ds:[ebx-4]
读第四的数据:
mov esi,dword ptr ds:[ebx-0x10]

2. 通过TOP加偏移的方式来读取

读第三个压入的数据:(一共压入4个)
mov edi,sword ptr ds:[edx+4]

弹出数据

mov esi,dword ptr ds:[edx] 先取出数据
add edx,4  后移动TOP,不再指向已弹出的地址

操作系统内置堆栈

EBP用于BASE

ESP用于TOP

压入数据

push 0xAAAAAAAA
push ebx

弹出数据

pop ebx  # 将弹出的数据置于ebx

保存现场

pushad
popad

hhhhh