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

Shell脚本中转换地址变量为数值适配dd命令的方法

问题描述

我通过Shell脚本解析/proc/PID/maps文件后,得到两个十六进制格式的地址变量:

START_ADDR=982fe000
END_ADDR=984fe000

想要将这两个变量用于以下dd命令,提取对应内存段到输出文件:

dd if=SOME_MEMORY skip=START_ADDR count=(END_ADDR-START_ADDR) of=out.bin bs=1

需要如何转换变量才能适配dd的参数要求?

解决方法

dd的skip和count参数仅接受十进制数值,但当前变量是十六进制格式,因此需要完成进制转换、地址差计算两步处理:

方式一:分步处理(用临时变量)

先将十六进制地址转成十进制,再计算内存段大小:

# 把十六进制起始地址转为十进制
START_DEC=$(printf "%d" 0x$START_ADDR)
# 计算地址差并转为十进制(0x前缀让Shell识别十六进制数值)
SIZE_DEC=$(printf "%d" 0x$((0x$END_ADDR - 0x$START_ADDR)))

# 执行dd命令
dd if=SOME_MEMORY skip=$START_DEC count=$SIZE_DEC of=out.bin bs=1

方式二:内联计算(减少临时变量)

直接在dd命令中嵌入转换逻辑,一步执行:

dd if=SOME_MEMORY \
    skip=$(printf "%d" 0x$START_ADDR) \
    count=$(printf "%d" 0x$((0x$END_ADDR - 0x$START_ADDR))) \
    of=out.bin bs=1

优化建议:提升读写速度

默认bs=1(单字节读写)速度极慢,建议使用页对齐的块大小(如4096),同时调整skip和count的计算方式:

BLOCK_SIZE=4096
# 计算起始块位置和总块数
START_BLOCK=$(( $(printf "%d" 0x$START_ADDR) / $BLOCK_SIZE ))
SIZE_BLOCK=$(( $(printf "%d" 0x$((0x$END_ADDR - 0x$START_ADDR))) / $BLOCK_SIZE ))

dd if=SOME_MEMORY skip=$START_BLOCK count=$SIZE_BLOCK of=out.bin bs=$BLOCK_SIZE

注:大部分/proc/PID/maps中的内存段是页对齐的,因此无需处理余数情况。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:55:12