lea edi, dword ptr ss:[ebp-40]
取地址编号赋给edi
即edi = esp + 3*0x4
, 下面三条之路是一组 , stos
用于将eax
的值存储到edi
的地址编号中 , ecx
记录执行次数 。每执行一次 , ecx - 1, edi + 4(df位为0)或者edi - 4(df位为1)
。cccccccc
是int 3
的硬编码int 3
是端点 , 这样做为了防止缓冲区溢出 , 未到的栈空间都被设置为cccccccc
, CPU执行遇到这里就会将程序停下来了 。下一步mov eax, dword ptr ss:[ebp+8]
是函数的第二个参数 , ebp+c
是函数的第一个参数 , 这两步执行了关键操作 2 + 1 = 3此时函数功能就完成了 , 下面就是恢复现场了 , pop edi
, 可分为两步 , mov edi, espadd esp,4
, 先push的后pop然后执行mov, esp, ebp
, 即将栈指针esp
下降到之前sub
执行前的位置 , 栈中的数据并没有清除
然后pop ebp
, 即将0x12ff30
赋给ebp
然后esp + 4
, 最后执行retn
, 相当于pop eip
即mov eip, 401171
然后esp + 4
, 这个地址就很关键了 , 这就是我们在pwn中经常覆盖的返回地址 。然后返回到调用者中执行 , 但是需要注意此时esp
与刚开始不一样 , 还没有平衡堆栈 , 由上图下面的add esp, 8
用于平衡堆栈 , 这种方式就叫外平栈 。
文章插图
文章插图
要覆盖返回地址 , 即
ebp + 4
, 覆盖了ebp
之后还需要再覆盖ebp + 4
的位置 , 64位下为ebp + 8
, 如上图所示401171
即为返回地址裸函数示例leave
指令相当于这两条指令:movl %ebp, %esp即令esp=ebppopl %ebp 即 ebp = M[esp] , esp = esp + 4
int __declspec(naked) plus(){__asm{//在函数调用之前会先push 1 push 2(传参数)call后会执行push 返回地址//保留调用前的栈底push ebp//提升堆栈mov ebp,espsub esp,0x40//保留现场push ebxpush esipush edi//填充缓冲区主要用于存储函数的局部变量mov eax,0xccccccccmov ecx,0x10// 之所以是10 是因为之前提升堆栈0x40 / 4 = 10栈一个格四个字节lea edi,dword ptr ds:[ebp-0x40]rep stosd //每次填充四个字节 , 重复16次//函数的核心功能ebp + 0x4为返回地址mov eax,dword ptr ds:[ebp+0x8]//把第一个参数给eaxebp+0x4为函数返回地址add eax,dword ptr ds:[ebp+0xc]//第二个参数 + eax -> eax//恢复现场pop edi// 取出栈顶给edi , 然后esp+4pop esi// 取出栈顶给esi , 然后esp+4pop ebx// 取出栈顶给ebx , 然后esp+4//降低堆栈mov esp,ebppop ebp//恢复栈底 , 刚开始ebp保留过ret//相当于pop eip 把函数返回地址401171给eip然后 rsp + 4}}//裸函数 , 系统不会生成任何指令 , 调用时会出错 , 会导致指令跳转后回不来 , 往往需要自己写入汇编指令
Pwntools用法参考手册- 连接:本地process()、远程remote( , );对于remote函数可以接url并且指定端口
- 数据处理:主要是对整数进行打包:p32、p64是打包为二进制 , u32、u64是解包为二进制
- 设置目标系统架构及操作系统
经验总结扩展阅读
- 四十一 增删查改分页 Java开发学习----MyBatisPlus标准数据层开发
- 中 学习ASP.NET Core Blazor编程系列十——路由
- CC1,3,6回顾
- 图学习【参考资料2】-知识补充与node2vec代码注解
- 二十四 设计模式学习:Spring 中使用到的设计模式
- Java安全之CC3
- TensorFlow深度学习!构建神经网络预测股票价格!?
- JUC学习笔记——共享模型之管程
- Seata Server 1.5.2 源码学习
- 2022极端高温!机器学习如何预测森林火灾?? 万物AI