如何调整此方法以覆盖二进制文件中的大缓冲区?

时间:2018-12-20 22:54:40

标签: c# methods buffer

已进行编辑,以更正和阐明我的原始要求。抱歉,这很令人困惑。

我正在尝试使用在堆栈溢出中发现的这种方法来搜索在“ testBin.exe”中编译的24个字符串中的2个字符“ YY”。我想用较小或相同长度的字符串覆盖“ YY”及所有后续数据。如果搜索字符串和替换字符串的长度相同,则testBin.exe可以很好地执行;如果搜索字符串小于24个字符,则覆盖其中的值,并将替换字符串附加到原始字符串中,从而破坏二进制文件。

我希望替换字符串从发现搜索字符串的第一个实例开始覆盖数据。我意识到这具有破坏性,因此我在可执行文件中填充了较大的字符串作为占位符。只要总字符串长度保持不变,程序将照常执行。我已经使用这种方法几天了,我认为在Buffer.BlockCopy中没有看到什么,我只需要以某种方式省去搜索字符串的长度,这样它将覆盖整个字符串。任何帮助表示赞赏。

Here is a hex view of the unaltered testBin.exe with 24 Y characters.

This is a one-for-one replacement of characters if searchString and replacementString are the same length.

If I only search for "YY" and not the 24 char "YY" string only "YY" is overwritten. The replacementString is added and now I have 46 characters. I would like to search for the first 2 char and overwrite it with the replacementString resulting in 24 total chars.

参考:How can I replace a unicode string in a binary file?

我的方法:

    // 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 :(得分:1)

您为什么要这么做? 更换后您期待什么? -可执行文件? -因为它不起作用!

您的方法使用ReplaceTextInFile,但是.exe文件是结构化文件,而不是简单的二进制原始字符。标记了一些关键位置。

示例: 偏移量0:-命令 偏移量100:一些代码 偏移200:您的文字 偏移量220:其他文字

现在,如果您将给定偏移量的“您的文本”替换为更长的字符(例如长度为40),而不是替换下一个String(可以是机器指令,数据或文本)。

我搜索了“ .net exe文件结构”,试图为您找到正确的方向。 以下是一些结果,您应该阅读它:

.NET Assembly File Format

Anatomy of a .NET Assembly – PE Headers

The .NET File Format

What is the file structure of an .exe file? What is the memory location of its starting address?

答案 1 :(得分:0)

我知道了。这是简单的方法。

使用子字符串,我减去了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);