You need to enable JavaScript to run this app. Bomb Lab phase_2 汇编解析:如何推导需输入的6个校验数字
优惠活动
大模型
产品
解决方案
定价
更多

Bomb Lab phase_2 汇编解析:如何推导需输入的6个校验数字

从汇编推导Phase_2输入的完整步骤

基础概念对齐

read_six_numbers的固定作用是把用户输入的6个32位整数,按输入顺序连续存储在栈空间中,起始地址就是传入的%rsp。我们把这组数字按顺序记为num[0]到num[5],每个数字占4字节,对应的内存偏移为:

  • num[0]: 地址(%rsp),偏移0
  • num[1]: 地址0x4(%rsp),偏移4
  • num[2]: 地址0x8(%rsp),偏移8
  • num[3]: 地址0xc(%rsp),偏移12
  • num[4]: 地址0x10(%rsp),偏移16
  • num[5]: 地址0x14(%rsp),偏移20

栈金丝雀相关的代码(%fs:0x28的读写、最后的异或校验)是系统的栈溢出保护逻辑,和输入校验完全无关,可以直接忽略。

第一步:拆解前置硬校验逻辑

读入6个数字后,代码的两次判断触发爆炸的分支非常明确,绕开objdump的地址偏移误导后,实际规则为:

  • 第一个判断:比较num[0]和0,不相等直接触发爆炸,也就是num[0]必须等于0。
  • 第二个判断:比较num[1]和1,不相等直接触发爆炸,也就是num[1]必须等于1。
    很多人卡在这里是被跳转目标的偏移误导,误以为num[0]非0可以跳过校验,实际上两个判断是串联的硬约束,只要不满足就会炸。

第二步:拆解循环校验的递推规则

完成前置校验后,代码初始化两个指针:

  • %rbx被设置为栈数组的起始地址,也就是指向num[0]
  • %rbp被设置为%rbx + 0x10,也就是指向num[4]的地址,作为循环的终止边界

逐行拆解循环内的执行逻辑:

  1. 取当前%rbx指向位置的下一个数字存入%eax:如果当前%rbx指向num[i],取到的值就是num[i+1]
  2. 把%rbx指向的当前数字加到%eax中,此时%eax的值为num[i] + num[i+1]
  3. 比较%rbx指向位置的下下一个数字(也就是num[i+2])和%eax的值,不相等直接触发爆炸
  4. 比较通过后,把%rbx的值加4,也就是指针往后移动一个元素的位置,指向num[i+1]
  5. 检查当前指针是不是已经到达边界num[4]的位置,如果到达就跳出循环,否则继续下一轮校验

把循环执行的所有校验项列出来:

  • 第一轮:校验num[2] == num[0] + num[1],校验通过后指针移到num[1]位置
  • 第二轮:校验num[3] == num[1] + num[2],校验通过后指针移到num[2]位置
  • 第三轮:校验num[4] == num[2] + num[3],校验通过后指针移到num[3]位置
  • 第四轮:校验num[5] == num[3] + num[4],校验通过后指针移到num[4]位置,此时指针到达边界,跳出循环,关卡通过

第三步:计算最终的输入序列

结合前置硬约束和循环递推关系,逐个数计算:

  • num[0] = 0(硬约束)
  • num[1] = 1(硬约束)
  • num[2] = num[0] + num[1] = 0 + 1 = 1
  • num[3] = num[1] + num[2] = 1 + 1 = 2
  • num[4] = num[2] + num[3] = 1 + 2 = 3
  • num[5] = num[3] + num[4] = 2 + 3 = 5

最终满足要求的6个输入数字依次为0 1 1 2 3 5。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.02 15:54:06