You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言如何查看结构体对齐填充位置 缓冲区溢出canary值放置方法

结构体填充定位与canary偏移计算方法

先纠正你方案里的致命错误

你之前把10位数字的canary转成ASCII格式写入是完全错误的:int32_t类型占4字节,存储的是二进制整数值,不是十进制数字对应的ASCII字符串。比如canary值为1234567890,对应的小端序存储字节序列是\xd2\x02\x96\x49,如果直接写入ASCII字符串"1234567890",实际写入内存的是0x31、0x32这类ASCII码值,和真实canary值完全不匹配,校验必然失败。

零规则基础计算填充位置与偏移

你已经拿到了结构体所有成员的内存地址,根本不需要死记硬背对齐规则,直接做地址减法就能算出所有填充段和正确偏移,步骤如下:

  • 按结构体声明顺序,把每个成员的起始地址、自身占用长度列成清单
  • 按顺序计算:前一个成员的起始地址 + 自身长度,得到前一个成员的理论结束地址
  • 用后一个成员的实际起始地址减去前一个成员的理论结束地址,得到的差值就是两个成员之间的填充字节长度
  • 从你要溢出的password数组成员起始地址开始,到canary成员起始地址的差值,就是你需要构造的输入总偏移:前25字节填password内容,中间填充段填任意垃圾值,最后4字节填canary的二进制整数值即可。

默认对齐规则参考(用于校验计算结果)

32位程序默认结构体对齐逻辑为:每个成员的起始地址必须是自身大小的整数倍,int32_t占4字节,因此它的起始地址必须是4的整数倍。对应你给出的结构体,无额外编译优化的情况下内存布局参考如下:

成员名长度相对结构体起始偏移说明
goodcanary4B04字节类型,4对齐无填充
password25B4char数组1字节对齐无填充
填充字节3B29补3字节凑4对齐,供canary使用
canary4B324字节类型,4对齐
good_username25B36char数组1字节对齐无填充
good_password25B61char数组1字节对齐无填充
username25B86char数组1字节对齐无填充

注意:如果编译时加了自定义对齐参数、开启了栈保护额外调整布局,实际偏移以你拿到的地址计算结果为准。

偏移验证方法

如果怕地址计算出错,可以构造特征输入快速定位:给password传入一长串按顺序递增的字符,比如先填25个'A'填满password本身的空间,后面依次接'BBBB'、'CCCC'、'DDDD'这类有明显标识的4字节块。程序执行完strcpy后下断点查看内存,看canary所在的4字节被哪段字符覆盖了,对应的输入位置就是canary的准确偏移,比纯计算更可靠。


内容的提问来源于stack exchange,提问作者Steve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 23:09:41