我正在尝试用 bash 修改一个字节,
因此,我将写入偏移量之前的字节,然后写入要修改的字节,以及文件的其余部分。
但以下脚本没有按预期工作
有人请看一下吗?无法弄清楚哪一部分是错误的
#!/bin/bash
file=/etc/passwd
out=passwd.mod
offset=0x5
dd if="$file" of="$out" conv=notrunc bs=1 count=$(($offset - 1))
printf '\x41' | dd of="$out" conv=notrunc bs=1 seek=$(($offset))
dd if="$file" of="$out" conv=notrunc bs=1 skip=$(($offset + 1))
答案1
如果我理解正确,我相信这对你有用:
#!/bin/bash
file=passwd.orig
out=passwd.mod
offset=0x5
dd if="$file" of="$out" conv=notrunc bs=1 count=$(($offset))
printf '\x41' | dd of="$out" conv=notrunc bs=1 seek=$(($offset))
dd if="$file" of="$out" conv=notrunc bs=1 seek=$((offset+1)) skip=$(($offset + 1))
您确实需要seek
将“写入头”放置在正确的位置,并skip
避免这些字节(再次)写入输出。
更好的
如果您需要做的只是更改(替换)一个字节,则可以直接在文件的副本中执行此操作,就像这对简单(和 POSIX)命令所做的那样:
#!/bin/sh
file=passwd.orig out=passwd.mod offset=0x05
cp "$file" "$out"
printf '\x41' | dd of="$out" conv=notrunc bs=1 seek=$(($offset))
如果您想“插入”一个字节,您确实需要上面的命令,但对偏移量进行一些更改。请询问这是否是您所需要的。
答案2
您错过了seek
最后一个命令中的:
dd if="$file" of="$out" \
conv=notrunc \
bs=1 \
skip="$((offset + 1))" \
seek="$((offset + 1))"
skip=n
复制前跳过输入文件中的 n 个输入块,seek=n
复制前跳过输出文件中的 n 个输入块。您需要它们两者来正确书写偏移。
答案3
两个问题:
1)dd if="$file" of="$out"
似乎覆盖$出在某一点。
2)即使考虑到这一点,计数=,跳过=, &寻求=逻辑在某处丢失了一个字节。
相反,尝试这样的事情:
file=/etc/passwd
out=passwd.mod
offset=0x5
dd if="$file" of="$out" conv=notrunc bs=1 count=$offset
printf '\x41' >> $out
dd if="$file" conv=notrunc bs=1 skip=$(($offset + 1)) >> $out
调整$偏移量根据需要给予或拿走一些——因为在这只是我的猜测之前它已经减少了一个。