简记录栈迁移学习途中复习汇编的流程

#一些汇编指令的含义

![[Pasted image 20230312120910.png]]
1,pop出栈,即将栈顶指针所指向的数据弹出栈并储存在指定的寄存器中,并将栈顶指针向高地址移动一段距离。
以下为具体示意:pop是汇编指令中的一种,用于从栈中弹出数据并存储到指定的内存地址中。它的含义是将栈顶指针所指向的数据弹出栈并存储到指定的内存地址中,并将栈顶指针向上移动一段距离,以便后续可以继续从栈中弹出数据。在Intel 80x86 CPU架构中,pop指令通常用于函数调用时弹出参数,以及恢复程序现场时恢复寄存器的值等场景。pop指令的操作数可以是寄存器或内存地址,具体取决于所要弹出栈中的数据类型和数据存储的位置。当数据类型为字节时,栈顶指针向上移动一个字节的距离;当数据类型为双字(DWORD)时,栈顶指针向上移动4个字节的距离。在执行pop指令时,需要确保栈顶指针不会越过栈顶,否则就会发生栈下溢等错误。

2,push入栈,即将数据放入栈顶指针所指向的位置,并将栈顶指针向下以移动一段距离。是不是很形象的将栈帧向下移动一段距离
以下为具体示意:push是汇编指令中的一种,用于将数据压入栈中,它的含义是将数据放入栈顶指针所指向的位置,并将栈顶指针向下移动一段距离,以便后续可以继续向栈中压入数据。在Intel 80x86 CPU架构中,push指令通常用于函数调用时将参数入栈,以及保存当前程序现场时保存寄存器的值等场景。push指令的操作数可以是寄存器、内存地址或立即数,具体取决于所要压入栈中的数据类型和数据存储的位置。当数据类型为字节时,栈顶指针向下移动一个字节的距离;当数据类型为双字(DWORD)时,栈顶指针向下移动4个字节的距离。在执行push指令时,需要确保栈顶指针不会越过栈底,否则就会发生栈溢出等错误。

3,mov ebp ,esp即为:ebp<—–esp将右值赋给左值。更可以形象理解为,左边的寄存器移动到右边。

4,b高s低,b底s顶,b静s动,b过去s未来,s就是光标。
b是赛高的s无所谓。
esp ebp在函数调用过程中的形式:

高地址
......
|        |
|        |<- EBP<span class="bd-box"><h-char class="bd bd-end"><h-inner>(</h-inner></h-char></span>栈底<span class="bd-box"><h-char class="bd bd-beg"><h-inner>)</h-inner></h-char></span>
|  局部  |
|  变量  |
|        |
|        |
|  参数  |
|        |
|        |
|        |<- ESP<span class="bd-box"><h-char class="bd bd-end"><h-inner>(</h-inner></h-char></span>栈顶<span class="bd-box"><h-char class="bd bd-beg"><h-inner>)</h-inner></h-char></span>
......
低地址  

5,栈和寄存器的相互作用关系:弹出old ebp地址给ebp寄存器之后ebp寄存器在栈旁侧进行指向。

6,leave为先动sp寄存器指针,再动bp寄存器,而栈迁移的攻击核心就在于利用两次的leave指令使得sp指针被篡改到目标地址(篡改ep地址为目标地址见-4)
———————————————————————————分割线
#以下为栈迁移的讲解
核心思想<span class="bd-box"><h-char class="bd bd-beg"><h-inner>:</h-inner></h-char></span>让esp跑两次,
第一次:使篡改过后的old ebp地址出栈,指向fake ebp
第二次:使esp跟随到fake ebp当中开辟出一段新的栈空间。

![[Pasted image 20230303190918.png]]
![[Pasted image 20230303190931.png]]
栈迁移原理介绍与应用 - Max1z - 博客园 (cnblogs.com)
这篇文章讲解的足够详细,看这篇文章就足矣。
要点归纳:
1,ebp 覆盖为 HijackAddr-4的目的是:当第二次执行完leave的pop ebp后esp回向高地址移动四个字节,从而使得esp指向 HijackAddr的地址,从而使得eip中成功放入目标地址完成程序流窜改。
2. # 第二次溢出,rop写在s中,栈迁移到s,调用system,参数为自己写在栈上的/bin/sh,参数偏移计算可知

payload=p32(elf.plt['system'])+p32(elf.sym['_start'])+p32(leak_ebp-offset+0xc)+b'/bin/sh\x00'
payload=payload.ljust(0x28,b'a')+p32(target_addr)+p32(leave_ret)

第一行为向s中写数据,sys plt + ret add + binsh地址 + binsh字符串
第二行为写入数据并对齐,数据 + target ebp + leave ret