好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 zyyujq 于 2024-10-3 16:53 编辑
运行环境: WINDOWS、.NET 4.0
涉及工具: VS2017
编程语言: C#
以下为主题内容:万能程序补丁工具,C#源代码(主体代码)
[C#] 纯文本查看 复制代码 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 万能程序补丁工具
{
public partial class Form1 : Form
{
string TargetFileName = null;
//目标文件名
string TargetFilePathName = null;
//目标完整文件名
OpenFileDialog OpenFileDialog1 = new OpenFileDialog();
//声明打开对话框
string[] SourceHex = null;
//原始特征码
string[] PatchHex = null;
//补丁特征码
bool ConfBool = false;
public Form1()
{
InitializeComponent();
}
private byte[] ReplaceBytes(byte[] original, byte[] toReplace, byte[] replacement)
{
if (original == null) throw new ArgumentNullException(nameof(original));
if (toReplace == null) throw new ArgumentNullException(nameof(toReplace));
if (replacement == null) throw new ArgumentNullException(nameof(replacement));
using (var memoryStream = new MemoryStream())
{
int index = 0;
int searchLength = toReplace.Length;
while ((index = Array.IndexOf(original, toReplace[0], index)) >= 0)
{
// 寻找匹配项
if (searchLength <= original.Length - index)
{
bool match = true;
for (int i = 1; i < searchLength; i++)
{
if (original[index + i] != toReplace[i])
{
match = false;
break;
}
}
if (match)
{
// 在匹配前添加部分
memoryStream.Write(original, index, index - (int)memoryStream.Position);
// 添加替换字节
memoryStream.Write(replacement, 0, replacement.Length);
// 将索引设置为匹配后
index += searchLength;
continue;
}
}
// 没有匹配,写一个字节
memoryStream.WriteByte(original[index++]);
}
// 复制其余的字节
if (index < original.Length)
{
memoryStream.Write(original, index, original.Length - index);
}
return memoryStream.ToArray();
}
}
private void Form1_Load(object sender, EventArgs e)
{
string ConfigFile = Application.StartupPath + "\\config.prg";//dynamic ConfigFile = Application.StartupPath + "\\config.prg";
//目标特征码配置文件
OpenConfigFile(ConfigFile);
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
//鼠标左键对目标文件进行补丁
if (!ConfBool)
{
MessageBox.Show("没有默认配置文件 config.prg\r\n鼠标右键加载 *.prg 配置文件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
OpenFileDialog1.Filter = "可执行文件(*.exe)|*.exe|库文件(*.dll)|*.dll|所有文件(*.*)|*.*";
OpenFileDialog1.FilterIndex = 1;
OpenFileDialog1.Title = "打开目标文件";
OpenFileDialog1.FileName = TargetFileName;
OpenFileDialog1.InitialDirectory = System.IO.Directory.GetCurrentDirectory(); //首选当前目录
if (OpenFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
TargetFilePathName = OpenFileDialog1.FileName; //完整目标文件名
int Pos = TargetFilePathName.LastIndexOf(".");
string CrackFilePathName = TargetFilePathName.Substring(0, Pos) + "-PJ" + TargetFilePathName.Substring(Pos); //完整备份文件名
byte[] FSData = File.ReadAllBytes(TargetFilePathName); //目标文件读入字节数组
//Rename(TargetFilePathName, BakFilePathName) '目标文件改名备份
bool BytesChange = false;
int PatchNum = SourceHex.Length - 1; //补丁个数
byte[] SourceByte = null; //原始特征码字节数组
byte[] PatchByte = null; //补丁特征码字节数组
for (int i = 1; i <= PatchNum; i++)
{
string[] HexStr = SourceHex[i].Split(' '); //将十六进制特征码按空格拆分为字符串数组
int HexNum = HexStr.Length - 1; //字符串数组个数
Array.Resize(ref SourceByte, HexNum + 1);
Array.Resize(ref PatchByte, HexNum + 1);
for (int j = 0; j <= HexNum; j++)
{
// SourceByte[j] = byte.Parse("&H" + HexStr[j]); //原始特征码转换为字节数组
SourceByte[j] = Convert.ToByte(HexStr[j], 16);
}
HexStr = PatchHex[i].Split(' '); //将补丁的十六进制特征码按空格拆分为字符串数组
for (int k = 0; k <= HexNum; k++)
{
//PatchByte[k] = byte.Parse("&H" + HexStr[k]); //补丁特征码转换为字节数组
PatchByte[k] = Convert.ToByte(HexStr[k], 16);
}
int Index = IndexOf(FSData, SourceByte); //检索原始特征码在程序中的索引位置
//Console.WriteLine(i)
if (Index != -1) //特征码匹配
{
int P = 0;
int Indexs = Index + PatchByte.Length - 1;
for (int m = Index; m <= Indexs; m++)
{
FSData[m] = PatchByte[P]; //替换特征码
P += 1;
}
BytesChange = true;
}
//Console.WriteLine("2=" & i)
}
if (BytesChange)
{
File.WriteAllBytes(CrackFilePathName, FSData);
MessageBox.Show("程序保存在相同目录下,文件为:\r\n" + Path.GetFileName(CrackFilePathName), "完成程序补丁", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("prg文件特征码补丁,不符合本程序!", "程序补丁失败", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
catch (Exception ex)
{
MessageBox.Show("配置文件中错误:\r\n1、原始特征码和补丁特征码不匹配,不符合设定!\r\n2、特征码十六进制空格或位数不符合设定!\r\n\r\n" + ex.StackTrace, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
if (e.Button == MouseButtons.Middle)
{
Form About = new About();
About.Show();
}
if (e.Button == MouseButtons.Right)
{
//鼠标右键打开或更改配置文件
//定义打开对话框属性
OpenFileDialog1.Filter = "目标配置文件(*.prg)|*.prg";
OpenFileDialog1.FilterIndex = 1;
OpenFileDialog1.Title = "更改目标配置文件";
OpenFileDialog1.InitialDirectory = Environment.CurrentDirectory;
//首选当前目录
if (OpenFileDialog1.ShowDialog() == DialogResult.OK)
{
TargetFilePathName = OpenFileDialog1.FileName;
OpenConfigFile(TargetFilePathName);
}
}
}
/// <summary>打开或更改配置文件</summary>
/// <param name="ConfigFilePathName">配置文件含完整目录全称</param>
private void OpenConfigFile(string ConfigFilePathName)
{
if (File.Exists(ConfigFilePathName))
{
try
{
StreamReader TargetFile = new StreamReader(ConfigFilePathName, Encoding.UTF8);
int i = 0;
SourceHex = null;
PatchHex = null;
while (TargetFile.Peek() > 0)
{
Array.Resize(ref SourceHex, i + 1);
Array.Resize(ref PatchHex, i + 1);
SourceHex[i] = TargetFile.ReadLine().Trim();
//读行
PatchHex[i] = TargetFile.ReadLine().Trim();
i += 1;
}
TargetFile.Dispose();
//注销文件流
TargetFileName = SourceHex[0];
//目标文件名
string TargetFileVer = PatchHex[0];
//目标版本
this.Text = "万用特征码补丁器 [" + TargetFileName + " " + TargetFileVer + "]";
ConfBool = true;
}
catch (Exception ex)
{
ConfBool = false;
MessageBox.Show("配置文件错误:\r\n配置文件非法或不符合设定!\r\n\r\n" + ex.StackTrace, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
this.Text = "万用特征码补丁器 [无配置文件 Config.prg]";
ConfBool = false;
}
}
/// <summary>报告指定的 System.Byte() 在此实例中的第一个匹配项的索引。</summary>
/// <param name="srcBytes">被执行查找的 System.Byte()。</param>
/// <param name="searchBytes">要查找的 System.Byte()。</param>
/// <returns>如果找到该字节数组,则为 searchBytes 的索引位置;如果未找到该字节数组,则为 -1。如果 searchBytes 为 null 或者长度为0,则返回值为 -1。</returns>
private int IndexOf(byte[] SrcBytes, byte[] SearchBytes)
{
if (SrcBytes == null || SearchBytes == null || SrcBytes.Length == 0 || SearchBytes.Length == 0 || SrcBytes.Length < SearchBytes.Length) return -1;
for (int i = 0; i <= SrcBytes.Length - SearchBytes.Length - 1; i++)
{
Console.WriteLine(SearchBytes[0]);
if (SrcBytes[i] == SearchBytes[0])//先比较首字节
{
if (SearchBytes.Length == 1) return i; //搜索字节只一位
bool flag = true;
//比较首字节后面的其它字节
for (int j = 1; j <= SearchBytes.Length - 1; j++)
{
if (SrcBytes[i + j] != SearchBytes[j])
{
flag = false;
break; //只要其中有一个字节不匹配则退出循环
}
}
if (flag) return i; //搜索到匹配的字节,返回字节位置索引
}
}
return -1;
}
}
}
C#完整源码压缩包,含完整工程、项目、资源:
万能程序补丁工具源代码.rar
(325.01 KB, 下载次数: 175)
最新上传(2024-10-03):
万能程序补丁和谐特征码文件.rar
(119.55 KB, 下载次数: 132)
特征码补丁文件示例:BarTender 2019 R10、BarTender 2021 R1、BarTender 2021 R8、BarTender 2021 R9、BarTender 2022 R1、BarTender 2022 R4、RibbonCreator 2021 X64 V1.1.01等,自己手刀PJ的软件
|
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|