我有一个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
查找地址的方法(因为在十六进制编辑器中我可以做到)或通过十六进制查找地址字符串格式。
答案 0 :(得分:1)
BinaryReader
重载直接读取一个整数,该整数取一个Int32
的值,并查看它是否与您要查找的值匹配。 BinaryReader.ReadInt32()将流位置前进4个字节,因此您需要跟踪读取位置,每次读取时将其递增1,并手动设置BaseStream
位置。
对FileAccess.ReadWrite
和FileShare.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)
{
}
希望有帮助。