Как бы я настроить этот метод для перезаписи большого буфера в двоичном файле? - PullRequest
0 голосов
/ 21 декабря 2018

Отредактировано в попытке исправить и уточнить мой первоначальный запрос.Извините, это сбивает с толку.

Я пытаюсь использовать этот метод, который я обнаружил при переполнении стека, для поиска 2 символов "YY" из 24-символьной строки, которая скомпилирована в "testBin.exe".Я хотел бы перезаписать «YY» и любые последующие данные строкой меньшей или одинаковой длины.testBin.exe выполняется нормально, если строка поиска и строка замены имеют одинаковую длину, если строка поиска меньше 24 символов, в которой ее значение перезаписывается, а строка замены добавляется к исходной строке, повреждая двоичный файл.

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

Вот шестнадцатеричное представление неизмененного testBin.exe с 24 символами Y.

Это замена символов один на один, если searchStringи replaceString имеют одинаковую длину.

Если я ищу только «YY», а не 24-символьную строку «YY», только «YY» перезаписывается.Добавлена ​​замена строки, и теперь у меня 46 символов.Я хотел бы найти первые 2 символа и перезаписать его замещающей строкой, в результате чего было получено всего 24 символа.

Ссылка: Как заменить строку в кодировке Юникод в двоичном файле?

Мой метод:

    // Works fine when searchString and replacementString are the 
    // same length.
    static string searchString = "YYYYYYYYYYYYYYYYYYYYYYYY";
    static string replacementString = "ZZZZZZZZZZZZZZZZZZZZZZZZ";

    // Corrupts the binary when the searchString is a lesser length than 
    // replacementString. 
    static string searchString = "YY";
    static string replacementString = "ZZZZZZZZZZZZZZZZZZZZZZZZ";

    public static void BinaryWriter(object state)
    {

        byte[] fileName = File.ReadAllBytes(@"testBin.exe"),
        oldBytes = Encoding.Unicode.GetBytes(searchString),
        newBytes = Encoding.Unicode.GetBytes(replacementString);

        int index = IndexOfBytes(fileName, oldBytes);

        if (index < 0)
        {
            return;
        }

        byte[] newFileBytes = 
            new byte[fileName.Length + newBytes.Length - oldBytes.Length];

        Buffer.BlockCopy(fileName, 0, newFileBytes, 0, index);
        Buffer.BlockCopy(newBytes, 0, newFileBytes, index, newBytes.Length);
        Buffer.BlockCopy(fileName, index + oldBytes.Length, newFileBytes, 
            index + newBytes.Length, fileName.Length - index - oldBytes.Length);

        File.WriteAllBytes(@"new_testBin.exe", newFileBytes);

        int IndexOfBytes(byte[] searchBuffer, byte[] bytesToFind)
        {
            for (int i = 0; i < searchBuffer.Length - bytesToFind.Length; i++)
            {
                bool success = true;

                for (int j = 0; j < bytesToFind.Length; j++)
                {
                    if (searchBuffer[i + j] != bytesToFind[j])
                    {
                        success = false;
                        break;
                    }
                }

                if (success)
                {
                    return i;
                }
            }

            return -1;
        }
    }

Ответы [ 2 ]

0 голосов
/ 22 декабря 2018

Я понял это.Это был простой способ.

Используя подстроку, я вычитал длину searchString, чтобы не перезаписывать буфер.Отлично работает!

Ссылка: https://www.dotnetperls.com/substring

        string searchString = "YY";
        string replacementString = "ZZZ";

        string update = replacementString.Substring(0, searchString.Length);

        byte[] fileName = File.ReadAllBytes(@"testBin.exe"),
        oldBytes = Encoding.Unicode.GetBytes(searchString),
        newBytes = Encoding.Unicode.GetBytes(update); 
0 голосов
/ 21 декабря 2018

Зачем ты это делаешь?Что вы ожидаете после замены?- работать как исполняемый файл?- потому что он не будет работать!

Ваш метод использует ReplaceTextInFile, но файл .exe представляет собой структурированный файл, а не простые двоичные необработанные символы.Некоторые ключевые позиции отмечены.

Пример: смещение 0: - смещение команды 100: некоторое смещение кода 200: смещение вашего текста 220: другой текст

Теперь, если вы замените «ваш текст» назаданное смещение, с более длинным символом, например, длиной более 40, чем вы заменяете следующую строку, которая может быть машинной инструкцией или данными или текстом.

Я выполнил поиск ".net exe fileструктура ", чтобы попытаться найти правильное направление для вас.Вот некоторые результаты, которые вы должны прочитать:

Формат файла сборки .NET

Анатомия сборки .NET - PE заголовки

Формат файла .NET

Какова структура файла .exe?Каково место в памяти его начального адреса?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...