Маскировать определенные пути к файлам в двоичных файлах

#binary

#двоичный

Вопрос:

У меня есть двоичный файл, содержащий некоторые пути к файлам. Если путь начинается с определенной строки, остальная часть пути к файлу [x20-x7f] должна быть замаскирована, оставляя общую структуру и размер файла нетронутыми!

Итак, со списком путей для поиска это:

 /usr/local/bin/
/home/joe/
  

Затем подобное вхождение в двоичные данные:

 ^@^@^@^@/home/joe/documents/hello.docx^@^@^@^@
  

Должно быть изменено на это:

 ^@^@^@^@/home/joe/********************^@^@^@^@
  

Каков наилучший способ сделать это? Есть ли способ в sed, perl или awk? Или мне нужно написать программу на C или PHP, где я нахожу строку и записываю strlen() количество символов маски вместо нее?

Ответ №1:

perl является хорошим выбором для работы с двоичными данными. Для sed и awk только реализации GNU обычно могут работать с двоичными данными, другие будут перегружены нулевым байтом или длинными последовательностями между двумя символами новой строки или строками без завершения.

 perl -pi.back -e 's{(/usr/local/bin|/home/joe)/K[x20-x7f] }{
  $amp; =~ s/./*/rg}ge' binary-file
  

Вам понадобится не слишком старая версия perl для /r флага (возвращает результат подстановки вместо применения его к переменной) и K (сбросьте начало соответствующей строки).

По умолчанию perl -p работает с одной строкой за раз, поскольку символ новой строки не является частью [x20-x7f] , это нормально.

Комментарии:

1. Это решение сработало прямо из коробки! Отлично подходит для анонимизации личной информации в файлах журналов. (Там не хватает / bin , но это детали!)

2. @forthrin. Спасибо, теперь я убрал конечную / строку из чередования, чтобы она применялась к обоим путям.

Ответ №2:

Вот некоторый код perl, который работает, хотя я уверен, что его можно оптимизировать. Это фильтр, поэтому он считывает все стандартные $data значения, затем для каждой строки в массиве @dirs он заменяет шаблон. Однако замена — это не фиксированная строка, а вызов функции replace($dir,$1) , который вычисляется из-за e модификатора команды substitute .

 #!/usr/bin/perl
use strict;
sub replace{
    my ($dir,$rest) = @_;
    $rest =~ s/./*/g;
    return $dir.$rest;
}
my @dirs = ('/usr/local/bin/','/home/joe/');
my $data = join("",<STDIN>);
foreach my $dir (@dirs){
    $data =~ s|$dir([x20-x7f] )|replace($dir,$1)|ge;
}
print $data;
  

Функции присваивается 2 аргумента: каталог и захваченная часть шаблона. Он возвращает их объединенными после замены каждого символа в захваченной строке.