如何通过字符串格式的十六进制值查找地址?

时间:2019-02-05 19:24:06

标签: c# winforms binary hex byte

我有一个int key1 = -1466731422;,当我在十六进制编辑器中搜索它时,它从.exe返回十六进制值62 74 93 A8
我想做的是在该newKey1上覆盖一个key1,用户可以选择它。
假设我们要为key1覆盖int newKey1 = -1566731422,到目前为止,我所做的是:

private void btnGravar_Click(object sender, EventArgs e)
{
    FixHex(key1, newKey1); //transform the int key in hex string

    br = new BinaryReader(File.OpenRead(element.FileName));            
    try
    {                
        for (long i = 0; i <= br.BaseStream.Length; i++)
        {
            if (br.BaseStream.ReadByte() == (byte)Convert.ToInt32(key1, 16))
            {
                progressBar.Value = progressBar.Maximum;
                br.Close();
                bw = new BinaryWriter(File.OpenWrite(element.FileName));
                bw.BaseStream.Position = i;
                bw.Write(newKey1);
                bw.Close();

                MessageBox.Show("Key updated", "Success");
                break;
            }
            else
            {
                progressBar.Value += 1;
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}        

它没有用,哦。我的for循环找不到匹配项,因此我认为它将解决,这是一种通过int key查找地址的方法(因为在十六进制编辑器中我可以做到)或通过十六进制查找地址字符串格式。

2 个答案:

答案 0 :(得分:1)

  1. 由于您要查找整数值(需要四个字节),因此无需读取单个字节。使用BinaryReader重载直接读取一个整数,该整数取一个Int32的值,并查看它是否与您要查找的值匹配。
  2. 您正在尝试编写字符串。它不是字符串,而是小尾数形式的四个字节的序列。您需要写这四个字节来替换现有的四个字节。

BinaryReader.ReadInt32()将流位置前进4个字节,因此您需要跟踪读取位置,每次读取时将其递增1,并手动设置BaseStream位置

FileAccess.ReadWriteFileShare.ReadWrite使用 BinaryReader BinaryWriter ,您可以找到该值并一口气覆盖它:

注意:由于缺少有关文件结构的信息,因此这里没有方法可以验证可能的误报。这取决于你。

int valOriginal = -1466731422;
int valSubstitute = -1566731422;
int valLength = BitConverter.GetBytes(valOriginal).Length;

using (var reader = new BinaryReader(
    File.Open("[File Path]", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))) {
    int position = 0;
    while (position < (reader.BaseStream.Length - valLength))
    {
        reader.BaseStream.Position = position;
        if (reader.ReadInt32() == valOriginal)
        {
            using (var writer = new BinaryWriter(
                File.Open("[File Path]", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))) {
                writer.BaseStream.Position = position;
                writer.Write(valSubstitute);
            };
            break;
        }
        position += 1;
    }
};

答案 1 :(得分:0)

正如其他人所说,您不是在以正确的方式比较正确的事物。 您想要比较的事物的比较方式取决于您在BinaryReader中读取的数据的格式以及“ key1”的类型。

在描述中,您说“ key1”是一个整数,但是尝试将其像字符串一样转换。我只是假设它是一个int。如果不正确,可以发表评论。

从描述中也不清楚文件中数据的格式。我将假设它是整数。如果不是整数,请添加注释。读取整数看起来像:

int testVal = br.ReadInt32();

这为您提供了一个整数,并且由于它们都是整数,因此您可以将其作为整数进行比较:

if(testVal == key1)
{/*do your other stuff*/}

循环而不是在文件末尾比循环遍历每个字节更好,例如:

while(br.BaseStream.Position != br.Basestream.Length)

将其放在一起可能类似于:

while(br.BaseStream.Position != br.Basestream.Length)
{        
    int testVal = br.ReadInt32();

    if(testVal == key1)
    {/*do your other stuff*/}
}

另一个注意事项:由于每次调用此方法时都会“新建” BinaryReader,并且在“ if”中关闭BinaryReader,因此您可能会在BinaryReader周围考虑一个using并在此声明。这将确保在发生异常的情况下正确处置BinaryReader。下面的变体将允许对BinaryReader进行适当的处​​理,但仍会捕获任何异常(并且,对于一般的Exception皱着眉头):

try
{
    using(var br = new BinaryReader(File.OpenRead(element.FileName)))
    {
        while(br.BaseStream.Position != br.Basestream.Length)
        {        
            if(br.ReadInt32() == key1)
            {/*do your other stuff*/}
        }
    }
}
catch(Exception ex)
{
}

希望有帮助。