zyyujq 发表于 2022-2-3 21:53

万能补丁器编程引出的困境与思考

本帖最后由 yujunqiang 于 2022-2-3 22:01 编辑

运行环境:WIN11
涉及工具:VS2017编程之VB.NET
教程类型:补丁制作,编程算法分析等
是否讲解思路和原理:是

以下为程序界面图形:



春节无聊,捣鼓了一下,编个简单的万能补丁程序。

程序目的:
通过更新配置文件内容,可以为各种软件进行逆向补丁。

万能补丁器配置文件,可以设置任何可执行文件,第一行为可执行文件文件名,第二行为可执行文件版本,以下每2行十六进制码为对应的原始与补丁码
config.prg文件内容如下:
BarTend
R1 V11.2.160.168
8B D8 48 85 C0 75 08 8D 43 FF
31 C0 90 90 90 90 90 90 90 90
80 7F 60 00 74 10 45 33 C0 48 8B 57 58 48 8B 4D 98 E8 4F 1C 4F
80 7F 60 00 EB 10 45 33 C0 48 8B 57 58 48 8B 4D 98 E8 4F 1C 4F
04 00 00 85 C0 74 07 BB 01 00 00 00
04 00 00 85 C0 74 00 BB 01 00 00 00
0F B6 C0 85 C0 74 56
0F B6 C0 85 C0 74 00
F3 FF FF 83 F8 FF 75
F3 FF FF 83 F8 FF EB
48 01 00 00 C1 92 35 7C
00 00 10 00 C1 92 35 7C


VB.net代码如下:
Imports System.IO
Imports System.Text


Public Class Form1
    Dim TargetFileName As String
    Dim TargetFilePathName As String
    Dim OpenFileDialog1 As New OpenFileDialog
    Dim SourceHex() As String
    Dim TargetHex() As String
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
      Dim ConfigFile = Application.StartupPath & "\config.prg"
      Dim TargetFile As New StreamReader(ConfigFile, Encoding.UTF8)
      Dim i As Integer = 0
      Do While TargetFile.Peek() > 0
            ReDim Preserve SourceHex(i)
            ReDim Preserve TargetHex(i)
            SourceHex(i) = TargetFile.ReadLine       ‘读配置文件行数据
            TargetHex(i) = TargetFile.ReadLine
            i += 1
      Loop
      TargetFile.Dispose()      ’注销读文件流
      TargetFileName = SourceHex(0)   ‘程序文件名
      Dim TargetFileVer As String = TargetHex(0)   ’程序版本
      Me.Text = "万能补丁器 [" + TargetFileName + " " + TargetFileVer + "]"
    End Sub


    Private Sub Form1_Click(sender As Object, e As EventArgs) Handles Me.Click
      With OpenFileDialog1 '定义打开对话框属性
            .Filter = "可执行文件(*.exe)|*.exe"
            .FilterIndex = 1
            .Title = "打开可执行文件"
            .FileName = TargetFileName & ".exe"
            .InitialDirectory = My.Computer.FileSystem.CurrentDirectory '当前目录
      End With
      TargetFilePathName = Application.StartupPath & "\" & TargetFileName & ".exe"
      If OpenFileDialog1.ShowDialog = DialogResult.OK Then
            TargetFilePathName = OpenFileDialog1.FileName

            Dim fs As New FileStream(TargetFilePathName, FileMode.Open, FileAccess.ReadWrite)
            Dim FileLeng As Integer = fs.Length'打开的可执行文件字节长
            Dim PatchNum As Integer = SourceHex.Length - 1

            Dim SourceNum As Integer

            For j = 1 To PatchNum’补丁个数

                Dim SourceHexStr As String = Replace(SourceHex(j), " ", "")       ‘去掉有空格的十六进制字符串
                SourceNum = SourceHexStr.Length / 2       '二进制字符个数
                Dim Buffer(SourceNum - 1) As Byte
                Dim PatchBuffer(SourceNum - 1) As Byte

                For k = 597248 To FileLeng - SourceNum

                  fs.Position = k    '文件流定位
                  fs.Read(Buffer, 0, SourceNum)    '读SourceNum个字节到Buffer


                  '将字节流转换为字符串
                  Dim sb As StringBuilder = New StringBuilder()
                  For I = 0 To Buffer.Length - 1
                        sb.Append(Buffer(I).ToString("X2"))
                  Next
                  Dim RearStr As String = sb.ToString
                  sb.Clear()


                  If RearStr = SourceHexStr Then '读取程序的字节流字符串是否一致


                        Dim PatchStr As String() = Split(TargetHex(j), " ") '拆分目标十六进制字符串为字符串数组,以转换为字节数组
                        '   Console.WriteLine(TargetHex(j))
                        For i = 0 To Buffer.Length - 1
                            PatchBuffer(i) = CByte("&H" & PatchStr(i))
                        Next
                        ''
                        '检验字节转换是否正确
                        ' For I = 0 To PatchBuffer.Length - 1
                        '   sb.Append(PatchBuffer(I).ToString("X2"))
                        ' Next
                        ' Console.WriteLine(sb.ToString)
                        '十六进制比较相同则写要修改的字节


                        fs.Write(PatchBuffer, k, Buffer.Length)'将字节数组替换原来的数据


                        '   MessageBox.Show(SourceHex(j), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information)
                  End If




                Next
            Next
            fs.Dispose()
            MessageBox.Show("完成程序补丁!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information)
      End If


    End Sub
End Class

程序问题:
以上代码逻辑没有问题,或许是VB.NET托管代码问题,或许是目标字节数太大,或许循环太多,运行不能达到目的!
或许需要找到新的快捷的检索二进制流方法。

TOcV 发表于 2022-2-3 22:57

谢谢分享

大神3 发表于 2022-2-3 21:54

感谢楼主

RIQ0 发表于 2022-2-3 22:03

大佬无敌

红牛307148 发表于 2022-2-3 22:38

如果楼主能每天都分享一些,那就更好了

GRdlFyoXp 发表于 2022-2-3 22:39

实力型偶像!感谢分享

gEL1730 发表于 2022-2-3 22:41

正符合我的需要,谢谢楼主

豆芽153028 发表于 2022-2-3 22:50

谢谢分享

vpgPGJRwInb 发表于 2022-2-3 22:52

学习永不间断!

GRdlFyoXp 发表于 2022-2-3 22:54

谢谢分享
页: [1] 2 3 4 5 6 7 8
查看完整版本: 万能补丁器编程引出的困境与思考