替换二进制文件中的字节有问题

时间:2015-09-15 01:27:35

标签: c#

涉及两个程序。第一个有一个字符串,如“@@@@@@@@@@”。第二个是配置工具,用于查找“@@@@@@@@@@”并将该字符串替换为文本框中的用户输入。

现在我在更换部件时遇到了麻烦。这是代码。

    //This is code from first program:
    string myIP = "@@@@@@@@@@@@@@@@@@@@";
    string myPort = "%%%%%%%%";
    int port = Int32.Parse(myIP );
    tcpClient.Connect(myIP , port);

    //This is code from second program:
    //Get bytes from textbox: 
    byte[] byte_IP = new byte[60];
    byte_IP = System.Text.Encoding.ASCII.GetBytes(textBox1_ip.Text);
    //Get all bytes in the first program:
    byte[] buffer = File.ReadAllBytes(@"before.exe");
    //Replace string with textbox input, 0x1c00 is where the "@" starts:  
    Buffer.BlockCopy( byte_IP, 0, buffer, 0x1c00, byte_IP.Length);
    //Build a new exe:
    File.WriteAllBytes(@"after.exe", buffer);

然而,我得到“127.0.0.1 @。@。@。@。@。@。”在新的exe中。但我需要“1.2.7 ... 0 ... 0 ... 1 .........”作为有效主机进行处理。

1 个答案:

答案 0 :(得分:1)

首先,我想重申一下评论中已经说过的内容:有更简单的方法来处理这些问题。这是配置文件的用途或注册表设置。

但如果你绝对必须......

首先,您必须匹配框架所期望的编码。字符串是否存储为UTF8? UTF-16? ASCII?以错误的编码写入数据几乎每次都会变成纯垃圾。通常对于代码中的字符串,例如您正在寻找您,并且想要使用Encoding.UNICODE

接下来,您需要一些方法来处理不同长度的字符串。您定义的缓冲区需要足够大,以包含您希望能够设置的最宽字符串 - 15个字节用于点分数字IPv4地址 - 但您必须允许至少7个字符。在使用该值之前填充余数并删除该填充可能就足够了。

我认为用于测试的最小程序是:

class Program
{
    static void Main(string[] args)
    {
        var addr = "@@@.@@@.@@@.@@@".TrimEnd();
        Console.WriteLine("Address: [{0}]", addr);
    }
}

现在在你的修补程序中,你需要在文件中找到起始位置,并用新字符串的字节覆盖字节。这是一个Patch方法,它调用FindString方法,您必须自己编写:

static void PatchFile(string filename, string searchString, string replaceString)
{
    // Open the file
    using (var file = File.Open(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
    {
        // Locate the search string in the file (needs to be implemented)
        long pos = FindString(file, searchString);
        if (pos < 0)
            return;

        // Pad and limit replacement string, then convert to bytes
        string rep = string.Format("{0,-" + searchString.Length + "}", replaceString).Substring(0, searchString.Length);
        byte[] replaceBytes = Encoding.Unicode.GetBytes(rep);

        // Overwrite the located bytes with the replacement
        file.Position = pos;
        file.Write(replaceBytes, 0, replaceBytes.Length);
    }
}

希望这是有道理的。