Как отредактировать шестнадцатеричное значение двоичного файла с помощью С#

Итак, вот моя проблема. У меня есть двоичный файл, который я хочу изменить. Конечно, я могу использовать редактор шестнадцатеричных, чтобы отредактировать его, но мне нужно сделать программу для редактирования этого конкретного файла. Скажите, что я знаю определенный гексагон, который я хочу редактировать, я знаю его адрес и т.д. Скажем, что это 16-битный двоичный код, а адрес 00000000, он в строке 04 и имеет значение 02. Как я могу создать программа, которая изменит значение этого шестнадцатеричного кода, и только этот шестнадцатеричный щелчок кнопкой?

Я нашел ресурсы, которые говорят о похожих вещах, но я не могу на всю жизнь найти помощь по точному вопросу.

Любая помощь будет оценена, и, пожалуйста, не просто скажите мне ответ, если есть, но попробуйте и объясните немного.

Ответ 1

Я думаю, что это лучше всего объяснить с помощью конкретного примера. Вот первые 32 байта исполняемого файла, как показано в шестнадцатеричном редакторе Visual Studio:

00000000  4D 5A 90 00 03 00 00 00  04 00 00 00 FF FF 00 00
00000010  B8 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00

Теперь файл представляет собой просто линейную последовательность байтов. Строки, которые вы видите в шестнадцатеричном редакторе, просто там, чтобы сделать чтение более легким. Когда вы хотите манипулировать байтами в файле с помощью кода, вам нужно определить байты по их позициям на основе 0. В приведенном выше примере позиции ненулевых байтов заключаются в следующем:

Position  Value
--------  ------
  0        0x4D
  1        0x5A
  2        0x90
  4        0x03
  8        0x04
 12        0xFF
 13        0xFF
 16        0xB8
 24        0x40

В представленном выше представлении шестнадцатеричного редактора числа слева представляют позиции первого байта в соответствующей строке. Редактор отображает 16 байт на строку, поэтому они увеличивают на 16 (0x10) в каждой строке.

Если вы просто хотите взять один из байтов в файле и изменить его значение, наиболее эффективным подходом, который я вижу, будет открытие файла с помощью FileStream, поиск подходящей позиции и перезапись байта. Например, следующее изменит 0x40 в позиции 24 на 0x04:

using (var stream = new FileStream(path, FileMode.Open, FileAccess.ReadWrite)) {
    stream.Position = 24;
    stream.WriteByte(0x04);
}

Ответ 2

Ну, первое, наверное, должно было бы понять конверсии. Вероятно, шестнадцатеричный до десятичного значения не так важен (если, конечно, вам не нужно сначала менять значение с десятичной дроби, а формула простого преобразования), но шестнадцатеричный для двоичного значения будет важен для каждого шестнадцатеричного символа (0-9, AF ) соответствует конкретному двоичному выходу.

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

Надеюсь, что это поможет!

С уважением,
Деннис М.