如何仅使用sh命令替换二进制文件指定偏移位置的单个字节
纯sh内置命令修改二进制文件指定偏移单字节方法
前提说明
大部分嵌入式设备自带的sh(ash、busybox sh等)均内置POSIX标准的printf、read命令,无需依赖任何外部二进制工具即可完成单字节补丁操作,操作前建议先备份原文件避免损坏。
通用操作方案(兼容大部分带head、tail的精简环境)
- 先定义需要用到的变量,根据你的实际需求修改对应值:
# 目标二进制文件路径 target_file="/path/to/your/binfile" # 要修改的字节偏移(支持十进制/十六进制,十六进制格式为0xXXX,从0开始计数) offset=$((0x1234)) # 要替换的新字节的十六进制值,比如替换为NOP指令就是90 new_byte_hex="90"
- 执行替换操作:
# 读取偏移前的内容写入临时文件 head -c "$offset" "$target_file" > "$target_file.tmp" # 写入替换的新字节,若环境不支持\x十六进制转义,可转为八进制格式用\${八进制值}写入 printf "\\x$new_byte_hex" >> "$target_file.tmp" # 读取原文件偏移之后的剩余内容追加到临时文件 tail -c +$((offset + 2)) "$target_file" >> "$target_file.tmp" # 覆盖原文件完成补丁 mv "$target_file.tmp" "$target_file"
极端精简环境兼容方案(无head、tail、dd等所有外部工具)
如果系统所有外部命令均被裁剪,可完全依赖sh内置命令实现:
target_file="/path/to/your/binfile" offset=$((0x1234)) new_byte_hex="90" tmp_file="$target_file.tmp" # 逐字节读取到偏移位置 count=0 while [ $count -lt $offset ]; do IFS= read -r -n 1 -d '' byte printf "%s" "$byte" >> "$tmp_file" count=$((count + 1)) done < "$target_file" # 写入新字节 printf "\\x$new_byte_hex" >> "$tmp_file" # 跳过原文件待替换的旧字节,读取剩余所有内容追加 read -r -n 1 -d '' skip_byte < "$target_file" cat >> "$tmp_file" < "$target_file" mv "$tmp_file" "$target_file"
注意事项
- 偏移为从0开始计数的字节偏移,如果你拿到的是1开头的偏移需要自行减1
- 串口输入命令时避免单条命令过长,可将上述逻辑逐行输入,或者写入临时脚本再执行
- 操作前务必执行
cp "$target_file" "$target_file.bak"备份原文件,避免固件损坏变砖
内容的提问来源于stack exchange,提问作者Max Pastushkov
相关产品推荐
相关产品推荐

