【问题标题】:perl seek and remove at varying offsets in binmodeperl 在 binmode 中以不同的偏移量查找和删除
【发布时间】:2013-02-09 20:15:08
【问题描述】:

这是我正在编写的脚本。

#usr/bin/perl
use warnings;


open(my $infile, '<', "./file1.bin") or die "Cannot open file1.bin: $!";
binmode($infile);
open(my $outfile, '>', "./extracted data without 00's.bin") or die "Cannot create extracted data without 00's.bin: $!";
binmode($outfile);

local $/; $infile = <STDIN>;
   print substr($infile, 0, 0x840, '');
   $infile =~ s/\0{16}//;
   print $outfile;

我正在用 perl 加载一个二进制文件。 我已经能够在某些偏移量处寻找和修补,但我想做的是,现在能够找到“00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00”(16 字节?)的任何实例并将其从文件中删除,但不少于16 个字节。任何低于我想离开的东西。在某些文件中,00 开始的偏移量将位于不同的偏移量,但如果我的想法正确,如果我可以搜索 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 并删除它的任何实例,那么 00 的偏移量就无关紧要了处于。我会首先从特定的偏移量中提取数据,然后搜索文件并从中删除 00。我已经可以提取我需要的特定偏移量了,我只需要打开提取的文件并刮掉00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

EF 39 77 5B 14 9D E9 1E 94 A9 97 F2 6D E3 68 05
6F 7B 77 BB C4 99 67 B5 C9 71 12 30 9D ED 31 B6 
AB 1F 81 66 E1 DD 29 4E 71 8D 54 F5 6C C8 86 0D 
5B 72 AF A8 1F 26 DD 05 AF 78 13 EF A5 E0 76 BB 
8A 59 9B 20 C5 58 95 7C E0 DB 44 6A EC 7E D0 10 
09 42 B1 12 65 80 B3 EC 58 1A 2F 92 B9 32 D9 07 
96 DE 32 51 4B 5F 3B 50 9A D1 09 37 F4 6D 7C 01 
01 4A A4 24 04 DC 83 08 17 CB 34 2C E5 87 26 C1 
35 38 F4 C4 E4 78 FE FC A2 BE 99 48 C9 CA 69 90 
33 87 09 A8 27 BA 91 FC 4B 77 FA AB F5 1E 4E C0        I want to leave everything from
F2 78 6E 31 7D 16 3B 53 04 8A C1 A8 4B 70 39 22 <----- here up
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <----- I want to prune everything
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00        from here on
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<---- this IS the end of the file, and
                                                     just need to prune these few rows
                                                     of 00's

说上面示例中的“F2 78 6E”位于偏移量0x45000 但是在另一个文件中,00 00 将从不同的偏移量开始,我该如何编码它以便@ 987654328@ 将被修剪。在我打开的任何文件中? 如果我需要更具体,请问。 似乎我会一直窥视文件,直到我击中一个长的 00 00 字符串,然后修剪任何剩余的行。这有意义吗? 我要做的就是在文件中搜索00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 的任何实例并删除/修剪/截断它。我想保存除 00 年代以外的所有内容

编辑 #2 这样做了:

open($infile, '<', './file1') or die "cannot open file1: $!";
binmode $infile;
open($outfile, '>', './file2') or die "cannot open file2: $!";
binmode $outfile;

local $/; $file = <$infile>;
$file =~ s/\0{16}//g;
print $outfile $file;


close ($infile);
close ($outfile);

感谢 ikegami 的所有帮助和耐心:)

【问题讨论】:

  • 您打开了$infile,但从STDIN 读取。你用文件的内容覆盖你的文件句柄。 (去显示你的变量名不合标准。使用..._fh 作为文件句柄。)你没有说要打印什么。
  • 相信我,我一直很努力。我想我今晚要放弃,明天再做一些。感谢您迄今为止的所有帮助。但为了让自己清楚,我想做的就是打开提取的 59kn 文件,并删除最后几行 00;s 哈哈。听起来很容易。我可以打开 HxD 并手动执行,但是只需双击一个不错的脚本就可以让我轻松很多。我每天都使用这些文件,并且必须手动检查它们,如果有一个工具可以将文件的每个部分分开,那就太好了,59kb 文件只是 16MB 文件的一部分。但很多其他数据是静态的,
  • 而且我在提取它时完全没有任何问题,我正在做的是提取超过 59 kb 的大小,这样每个文件的末尾都会用 00 填充,然后我想添加此脚本以删除它们 00。无论如何,谢谢你到目前为止的所有帮助。

标签: perl seek vary


【解决方案1】:

没有从文件中删除这样的事情。你必须要么

  1. 复制不包含不需要的位的文件,或者
  2. read 文件的其余部分,seek 返回,print 覆盖不需要的位,然后truncate 文件。

我选择了选项 1。

$ perl -e'
   binmode STDIN;
   binmode STDOUT;
   local $/; $file = <STDIN>;
   $file =~ s/\0{16}//;
   print $file;
' <file.in >file.out

我正在将整个文件加载到内存中。任何一个选项都可以分块完成,但它会使事情变得复杂,因为你的 NUL 可以跨越两个块。


在措辞不佳的更新中,您似乎要求避免更改前 0x840 字节。两种解决方案:

$ perl -e'
   binmode STDIN;
   binmode STDOUT;
   local $/; $file = <STDIN>;
   substr($file, 0x840) =~ s/\0{16}//;
   print $file;
' <file.in >file.out

$ perl -e'
   binmode STDIN;
   binmode STDOUT;
   local $/; $file = <STDIN>;
   print substr($file, 0, 0x840, '');
   $file =~ s/\0{16}//;
   print $file;
' <file.in >file.out

【讨论】:

  • 你应该告诉我为什么我的解决方案不够好。我只是偶然注意到你的更新。
  • 原帖已更新。当我运行它时,它试图运行,但光标闪烁。
  • 请耐心等待,这对我来说是一次学习的经历。我会编程,但我不是中级人,所以请耐心等待;)我正在学习,哈哈
  • 好的,把$file =~ s/\0{16}//;改成$str = "\0" x 16; $file =~ s/\Q$str//;
  • 哦,你想删除 16 个 NUL 的所有实例吗?将“g”标志添加到替换中,s/\0{16}//g
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-07
  • 2015-03-12
  • 1970-01-01
  • 2016-09-12
  • 1970-01-01
  • 2017-01-10
  • 1970-01-01
相关资源
最近更新 更多