Attack Lab中opcode末尾的c3与后续独立retq指令含义疑问
Attack Lab Gadget中Opcode内嵌0xc3的问题解答
核心原理:x86是变长指令集
CPU只会从当前RIP指向的地址开始,按照x86 opcode的编码规则逐字节解码指令,同一段二进制数据从不同偏移开始解码,得到的指令序列完全不同。你观察到的现象本质是Attack Lab构造gadget的常规操作,具体分两种执行场景解释:
场景1:从指令起始地址0x401a6e开始执行
此时CPU会把地址0x401a6e到0x401a73的6个字节8d 87 58 90 90 c3完整解码为一条lea -0x3c6f6fa8(%rdi),%eax指令:
- 末尾的
0xc3是这条lea指令立即数的组成部分,不会被单独解码为retq - 执行完lea后RIP会自动移动到
0x401a74,仅执行一次此处的retq,不存在两次返回的问题 - 和把末尾
0xc3替换为0x90的版本相比,仅lea计算得到的%eax值不同,执行流程完全一致
场景2:从指令中间偏移0x401a70开始执行(找gadget的常用场景)
此时CPU从0x401a70开始解码,对应字节序列为58 90 90 c3:
- 依次解码为
popq %rax、nop、nop、retq,就是典型的可用gadget序列 - 此处的
0xc3会被解码为retq,执行该指令后程序会直接跳转到栈上存储的返回地址,根本不会执行到0x401a74位置的另一个retq,所以也不会出现两次返回的问题 - 如果把原lea末尾的
0xc3替换为0x90,此时从0x401a70开始解码得到的序列是popq %rax、nop、nop、nop,随后会继续执行到0x401a74的retq,得到的gadget只是多了一个空操作,返回逻辑本身没有区别
内容的提问来源于stack exchange,提问作者user202004
相关产品推荐
相关产品推荐

