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

ROP Emporium badchars题XOR操作行为与ROP链逻辑疑问

badchars题目ROP脚本for循环逻辑解析

你遗漏的核心逻辑藏在xor_r14_r15对应gadget的指令行为里,for循环确实是完成逐字节XOR解密、原地修改writehere内存段内容的操作,具体拆解如下:

核心gadget行为澄清

两个关键gadget实际功能如下,其中带内存写入效果的指令就是你没注意到的修改操作:

  • pop r14 ; pop r15 ; ret:执行时从栈顶依次弹出两个64位值,分别存入r14、r15寄存器,之后跳转到栈上后续地址指向的指令执行
  • xor byte ptr [r15], r14b ; ret:这条指令本身就包含内存写入操作——它会把r15存储的值作为内存地址,读取该地址指向的1字节内容,和r14的低8位(即r14b)做异或运算,运算结果直接写回r15指向的内存地址,完成后再执行ret。

for循环逐轮执行逻辑

循环共执行8次,正好对应flag.txt的8个字符长度,每一轮往ROP栈中塞入的内容执行效果完全一致:

  1. 首先压入pop_r14_r15的地址,触发寄存器弹值操作
  2. 压入立即数2:这个值会被弹出到r14寄存器,也就是r14b固定为XOR加密用的密钥2
  3. 压入地址writehere + i:这个值会被弹出到r15寄存器,指向当前待解密的字节位置,从writehere首地址开始逐字节后移
  4. 最后压入xor_r14_r15的地址:执行XOR指令时,直接把r15指向的加密字节和2异或,结果原地写回对应内存位置,完成单字节解密。

举个首轮(i=0)的执行例子:

  • 初始writehere首地址存的是加密后的首字节0x64(对应原始字符'f'和密钥2异或的结果)
  • 指令执行时,0x64 ^ 2 = 0x66,也就是字符'f',结果直接写回writehere首地址
  • 后续每轮解密后移一个字节,8轮跑完后,writehere起始的8字节内存就被还原为完整的flag.txt字符串。

后续传参逻辑说明

循环执行完成后,writehere地址处已经存储了正确的文件名字符串,此时通过pop rdi把writehere地址存入rdi(即函数调用的第一个参数),再跳转到func执行,func自然能读取到正确的字符串完成打印。

补充说明:第一次调用pop_r12131415时给r14、r15传入的两个值2是无效凑数值——执行完mov_r12to13后马上就会进入第一轮循环的pop r14_r15,这两个寄存器的值会直接被栈上新弹出的值覆盖,只要传入的值不会触发内存访问崩溃,就不会影响最终执行结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:01:09