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

如何补丁Go二进制文件,将time.Sleep固定为仅等待1秒?

修改Go二进制文件中的time.Sleep行为及相关疑问解答

一、补丁time.Sleep使其固定等待1秒

  1. 明确参数传递逻辑:Go的time.Sleep最终调用runtime.timeSleep,接收的time.Duration本质是int64类型(单位纳秒)。在x86_64架构下,该参数通常通过rdi寄存器传递;其他架构规则以你的gdb反汇编结果为准。
  2. 定位参数使用位置:在gdb中反汇编runtime.timeSleep,找到使用传入参数的指令段——比如把寄存器值加载到等待时间计算逻辑里的指令。你需要在参数被使用前,强制将其替换为固定值(1秒=10^9纳秒,对应十六进制0x3B9ACA00)。
  3. 具体补丁操作:
    • 若参数通过寄存器传递:在timeSleep函数开头插入指令,覆盖原参数寄存器的值。比如x86_64下添加mov rdi, 0x3B9ACA00,对应的机器码是48 C7 C7 00 CA 9A 3B。
    • 若参数通过栈传递:找到栈中存储参数的内存位置,将对应字节替换为固定值的十六进制表示。
  4. hexedit修改二进制的步骤:
    • 用gdb获取runtime.timeSleep的虚拟地址:执行info func runtime.timeSleep得到目标地址(比如0x45abc0)。
    • 转换虚拟地址到文件偏移:用objdump -h 你的二进制文件查看text段信息,比如text段虚拟起始地址为0x400000、文件偏移为0x1000,则目标地址的文件偏移为0x1000 + (0x45abc0 - 0x400000)。
    • 打开hexedit跳转到该偏移,将原指令机器码替换为新指令的机器码,注意指令长度要匹配,避免破坏后续指令对齐。

二、关于修改本地time.go文件的疑问

  • 1)修改本地文件不会影响已预编译的二进制:已编译完成的二进制已将runtime的机器码打包在内,和本地源码完全独立。只有用修改后的Go源码重新编译Go工具链,再用新工具链编译目标程序时,修改才会生效。
  • 2)gdb断点指向的是编译时使用的源码:你的二进制是用/usr/local/go/src路径下的Go工具链编译的,所以gdb会加载该路径的源码作为调试符号的对应文件,但运行时二进制执行的是编译后的机器码,并非直接调用这个文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 18:05:13