Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2349757
  • 博文数量: 527
  • 博客积分: 10343
  • 博客等级: 上将
  • 技术积分: 5565
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-26 23:05
文章分类

全部博文(527)

文章存档

2014年(4)

2012年(13)

2011年(19)

2010年(91)

2009年(136)

2008年(142)

2007年(80)

2006年(29)

2005年(13)

我的朋友

分类: LINUX

2010-05-13 10:24:06

如果是修改文本文件, 当然用一个文本编辑器如Emacs或vi.

二进制文件, 文件很大, 如果要替换指定偏移处的特定字节. 又不希望产生新文件. 可以用下面的命令实现

printf "\x00" | dd of=big_binary.dat bs=1 count=1 conv=notrunc bs=1 count=1 seek=2

管道前的printf 命令用来产生一个字节的二进制数据, 故意用NUL字符, 以示可以替换为任意内容.
if 没有指定时, 从标准输入读取内容
of指定的是要修改的文件, bs=1 count=1确定要改的字节数, conv=notrunc很重要, 确保修改完这一个字节, 文件的其它部分保持不变.
seek=2 是跳过前面的2个字节. 注意skip是用于指定读取文件时跳过的字节, seek指定写文件时跳过的字节.

用这种办法, 只能把2个字节的内容替换为2个字节, 少一字多一字都不行.

===
今天,我又在脚本中重新实现了一次替换二进制文件的内容。
函数如下,这次,指定了可以替换的源和目标串。稍加修改,也可以替换二进制的内容。

这个函数不需要指定偏移,自动通过 grep -P 的PCRE 正则表达式引擎来搜索。

需要注意的一个地方是od 的-v 参数,如果没有它,一些重复的数据可能不会输出出来。

 the target binary file
# arg 2: the source data
# arg 3: the dest data to subsititute [arg 2], should be same length as [arg 2]
function replace_data()
{
    prog="$1"
    from="$2"
    to="$3"
    len=${#from}
    if [ $len != "${#to}" ]; then
        echo "len[$from] != len[$to]" >&2
        return 1;
    fi
    from_re="$(echo -n $from | od -v -t x1 -w$len | cut -d ' ' -f2- | head -1 | tr ' ' '.' )"
    echo -n "$to" > to_file
    line_no="$(od -v -t x1 -w1 $prog | cut -d ' ' -f2 | grep -nP '(?s)'$from_re)"
    if [ $? != 0 ]; then
        echo "Fail to find [$line_no] '(?s)$from_re'" >&2
        return 1;
    fi
    line_no="${line_no%:*}"

    dd if=to_file of=$prog conv=notrunc count=${len} seek=$((line_no-1)) bs=1c
}

阅读(6213) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~