Вывод всех символов ASCII из исполняемого файла

При частой работе с различными шестнадцатеричными и бинарными файлами требуется выделить некие особые последовательности символов (сигнатуры, подписи, блоки данных), которые представлены в виде ASCII символов.

В этом рецепте я покажу код, который покажет все ASCII последовательности в некотором исполняемом файле. Этот код вы можете использовать для изучения исполняемых файлов на предмет наличия разных интересных вещей и закономерностей, а также как очень ценный инструмент по выделению plain-данных из самого файла.

Итак, код рецепта:

import std.algorithm;
import std.ascii;
import std.conv;
import std.file;
import std.range;
import std.string;
import std.stdio;




auto getASCII(dstring source)
{
	return source
				.filter!(a => a.to!dchar.isPrintable)
				.map!(a => [a])
				.join;
}

void main(string[] arguments)
{
	File file;
	scope(exit) {
		(cast(dstring) std.file.read(arguments[0])) 
			.splitLines
			.map!(a => getASCII(a))
			.filter!`a != ""`
			.each!(a => a.writeln);
	}
}

Запускаем файл рецепта, указывая в качестве опции командной строки файл, который будет подвергнут изучению. Программа считывает файл в бинарном режиме, разбивает его на строки с помощью splitLines, затем каждая строка обрабатывается функцией getASCII (профильтровывает строку, оставляя только печатаемые, т.е видимые на экране, символы ASCII), после чего происходит отсеивание только непустых строк и вывод их в терминал.

Функция getASCII получая на вход строку осуществляет фильтрацию печатаемых символов, переводя их в dchar и выделяя только те, что имеют визуальное представление в экране терминала (с помощью isPrintable). После того, как отработал алгоритм filter, с помощью анонимной функции тождественности, отображающей символ в одномерный массив с символом (функция a => [a]). Отображение дает набор массивов символов, которые затем склеиваются с помощью алгоритма join в единый массив, который будет являться строкой-источником для дальнейшей обработки.

Использовать эту миниатюрную программу очень просто, но стоит учесть, что будут выведены абсолютно все символы из бинарного файла, которые хоть как-то соответствует кодировке ASCII, и поэтому дальнейший поиск данных остается на плечах пользователя этого скромного рецепта.

 

aquaratixc

Программист-самоучка и программист-любитель

Добавить комментарий