我在perl 中实现了一个解决方案。我假设大小不包括 13 字节的标头。它还没有完全成熟,但可以工作。它是一种工作台模型。它在内存中创建一些数据,然后进行修改。
所以第一部分只是根据标题创建内存中的数据:
#!/usr/bin/perl
use strict;
use warnings;
# Glues binary strings -> not needed $a.$b works properly
#sub glue(@) { pack "W*", map { unpack("W*", $_) } @_; }
# Creates a <header:null data> record
sub pck(@) {
my $h = pack "(H[2])*", @_;
# If it is big-endian use N instead of V!!!
# It has to be unpacked to get the 32 bit data size
my @u = unpack "C5V2", $h;
my $b = pack "x$u[6]"; # put a lot of NULL bytes
$h.$b;
}
my @h1=qw(4a d8 64 54 13 01 00 00 00 2d 00 00 00);
my @h2=qw(4a d8 64 54 20 01 00 00 00 2c 00 00 00);
my $d1 = pck @h1;
my $d2 = pck @h2;
my $d = $d1.$d2;
现在$d 包含两条记录:<header1><zero data1><header2><zero data2>。现在我们可以转储数据了:
sub dumpbin(@) {
open my $fh, "|od -t x1" or die;
binmode $fh;
print $fh @_;
close $fh;
}
dumpbin($d);
输出:
0000000 4a d8 64 54 13 01 00 00 00 2d 00 00 00 00 00 00
0000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0000060 00 00 00 00 00 00 00 00 00 00 4a d8 64 54 20 01
0000100 00 00 00 2c 00 00 00 00 00 00 00 00 00 00 00 00
0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0000160 00 00 00
0000163
现在可以根据需要解析和修改内存中的数据。标头被转储。偏移量以八进制打印以符合od 的输出。
print "=====\n";
for (my $offs=0; $offs<length($d);) {
# Unpack header
my @h = unpack "C5V2", substr($d, $offs, 13);
# Checks if the header type is 0x20 and modifies it
if ($h[4] eq 0x20) { substr($d, $offs + 4, 1) = pack "W", 0x1e;}
printf "%07o HDR: %s%s\n", $offs, join(" ", map {sprintf "%x", $_} @h),
$h[4] eq 0x20 ? " *" : "";
$offs += 13 + $h[6];
}
print "=====\n";
输出:(用'*'标记的修改行)
=====
0000000 HDR: 4a d8 64 54 13 1 2d
0000072 HDR: 4a d8 64 54 20 1 2c *
=====
如果我们转储结果,可以看出数据已正确更改:
dumpbin($d);
输出:
0000000 4a d8 64 54 13 01 00 00 00 2d 00 00 00 00 00 00
0000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0000060 00 00 00 00 00 00 00 00 00 00 4a d8 64 54 1e 01
0000100 00 00 00 2c 00 00 00 00 00 00 00 00 00 00 00 00
0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0000160 00 00 00
0000163
可以看出数据被修改了。
如果输入文件很大,则需要更多的代码来分块读取数据,修改和写回。
我希望这会有所帮助!