C#读写二进制文件,可以修改部分单机游戏存档。学以致用
以单机游戏【仙剑奇侠传三】为例,使用的版本是方块游戏1.04版。打开仙剑奇侠传三游戏“新的开始”,等待剧情过后,景天单人自由活动时,保存到第一个存档。将在仙剑三主目录的save文件夹下生成一个二进制存档文件。个人测试电脑存档文件路径为“H:\CubeLibrary\apps\1000039\save\pal00.arc”。为了防止修改数据错误,我们先备份一个文件pal00bak.arc,用于测试使用
初始景天一级的精 88/88、气17/17、神29/29【数据代表当前数据和上限数据。比如:当前精88/精上限88】。
读取二进制文件,进行抓包,找出所有的 88,17,29数据
我们发现有3组疑似数据,如上图所示。
将上面的精气神三组数据修改掉,为新的字节数组赋值。比如篡改精气神的值以依次为250、150、200。
保险一点,全部都修改掉。
buffer[1352] = 250;//精
buffer[1356] = 150;//气
buffer[1360] = 200;//神
buffer[1640] = 250;//精
buffer[1644] = 150;//气
buffer[1648] = 200;//神
buffer[1688] = 250;//精
buffer[1692] = 150;//气
buffer[1696] = 200;//神
新建控制台程序:ReadWriteBinaryFileDemo
相关的C#源程序如下:
using System;
using System.IO;
namespace ReadWriteBinaryFileDemo
{
class Program
{
static void Main(string[] args)
{
try
{
string fileName = @"H:\CubeLibrary\apps\1000039\save\pal00bak.arc";
int fileSize = (int)new FileInfo(fileName).Length;
Console.WriteLine($"仙剑三存档文件大小:{fileSize}字节");
byte[] bufferWrite = new byte[fileSize];
using (FileStream fileStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
//以二进制方式读文件
//创建一个二进制数据流读入器,和打开的文件关联
using (BinaryReader binaryReader = new BinaryReader(fileStream))
{
// 把文件指针重新定位到文件的开始
binaryReader.BaseStream.Seek(0, SeekOrigin.Begin);
//读取所有数据
byte[] buffer = binaryReader.ReadBytes(fileSize);
binaryReader.Close();
//在刚保存一级的时候 景天【当前】精88 气17 神29。 景天【上限】精88 气17 神29
//我们使用抓包的方式 过滤出来。然后尝试修改
for (int i = 0; i < buffer.Length; i++)
{
if (buffer[i] == 88)
{
Console.WriteLine($"当前索引:{i},景天精{buffer[i]}");
}
else if (buffer[i] == 17)
{
Console.WriteLine($"当前索引:{i},景天气{buffer[i]}");
}
else if (buffer[i] == 29)
{
Console.WriteLine($"当前索引:{i},景天神{buffer[i]}");
}
}
//检索 精气神对应数据所在的包的附近40个字节
for (int i = 1352 - 8; i < 1352 + 32; i++)
{
Console.Write(buffer[i] + " ");
}
Console.WriteLine();
for (int i = 1640 - 8; i < 1640 + 32; i++)
{
Console.Write(buffer[i] + " ");
}
Console.WriteLine();
for (int i = 1688 - 8; i < 1688 + 32; i++)
{
Console.Write(buffer[i] + " ");
}
//这里篡改精气神的值以依次为250、150、200
buffer[1352] = 250;//精
buffer[1356] = 150;//气
buffer[1360] = 200;//神
buffer[1640] = 250;//精
buffer[1644] = 150;//气
buffer[1648] = 200;//神
buffer[1688] = 250;//精
buffer[1692] = 150;//气
buffer[1696] = 200;//神
//将篡改过的数据【新的精气神数据】 写入的新的字节数组中
Array.Copy(buffer, 0, bufferWrite, 0, fileSize);
}
fileStream.Close();
}
using (FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
{
//以二进制方式写文件
//创建一个二进制数据流写入器,和打开的文件关联
using (BinaryWriter binaryWriter = new BinaryWriter(fileStream))
{
binaryWriter.Write(bufferWrite);
binaryWriter.Flush();
binaryWriter.Close();
}
fileStream.Close();
}
Console.WriteLine($"重新写入文件成功...");
}
catch (Exception ex)
{
Console.WriteLine($"读写文件时出现异常:{ex.Message}");
}
Console.ReadLine();
}
}
}
程序运行如图:
我们将原来的存档文件pal00.arc重命名为pal00_raw.arc。将修改后的文件 pal00bak.arc 重命名为pal00.arc。
重新打开 仙剑奇侠传三 游戏,点击“旧的回忆”,读取存档一,点击右上角的人物头像,惊喜的发现 精气神变成250,150,200了。
大功告成。
其他物品数量,金钱都可以修改二进制文件的某些值 即可。
比如精888=3*256+120,转化为两个字节为3,120。只要抓包找出连续数组元素的值为buffer[i]=3 && buffer[i+1]=120 即可。