Если у вас есть необработанные байты (8-битные символы, которые невозможно распечатать) и вы хотите манипулировать ими как строкой .NET и превратить их обратно в байты, вы можете сделать это с помощью
Encoding.GetEncoding(1252)
вместо кодировки UTF8. Эта кодировка позволяет получить любое 8-разрядное значение и преобразовать его в 16-разрядный символ .NET и обратно, не теряя никакой информации.
В конкретном случае, который вы описали выше, с двоичным файлом вы не сможете "связываться с метаданными в заголовке" и работать правильно, если длина данных, с которыми вы связываетесь, не изменяется. Например, если заголовок содержит
{any}{any}ABC{any}{any}
и вы хотите изменить ABC на DEF, это должно работать так, как вы хотите. Но если вы хотите изменить ABC на WXYZ, вам придется записать поверх байта, следующего за «C», или вы (по сути) переместите все на один байт дальше вправо. В типичном двоичном файле это сильно испортит.
Если байты после «ABC» являются пробелами или нулевыми символами, есть большая вероятность, что запись больших замещающих данных не вызовет проблем - но вы все равно не можете просто заменить ABC на WXYZ в строке .NET, делая его длиннее - вам придется заменить ABC {what_follows_it} на WXYZ. Учитывая это, вы можете обнаружить, что проще оставить данные в виде байтов и записать замещающие данные по одному байту за раз.