ayhdnlp 发表于 2024-4-17 16:44

求个教程

本帖最后由 ayhdnlp 于 2024-4-17 17:00 编辑

我有个软件,厂家已经倒闭不干了,但是他有注册码,每次重装系统都用找厂家激活,可厂家已经倒闭了,所以导致软件无法激活,是本地注册的,能通过OD看到注册码,想把他改成直接免注册的,求个教程,纯小白,追激活码,也是误打误撞看到的,来求下本论坛大神给个教程,越详细越好,复杂了可能看不懂,我知道论坛不能求破,所以才想要个教程,自己弄!这个是注册界面后面 是我在OD中找到的注册码
这个是软件的下载链接 拜托了,链接: https://pan.baidu.com/s/1K9UNj3YFUepsDvrCbNUKfw 提取码: gdek
或者给个教程,怎么配注册机也可以我下载的有这个, 用他配上也行

爱飞的猫 发表于 2024-4-18 06:53

本帖最后由 爱飞的猫 于 2024-4-18 08:52 编辑

这个程序是 VB6 的,没有编译到机器码,全程都在 VB 虚拟机里打转。要做内存注册机的话,需要写代码注入到进程,判断什么时候可以得到注册码(例如 HOOK `rtcMsgBox` 函数,调用时爬堆栈得到真码)。

建议使用 (https://down.52pojie.cn/?query=VB) 分析算法,然后编写算法注册机。

---

VB 部分的代码:

```vb
Private Sub Proc_10_0_416FE0
'Data Table: 4014A4
Dim var_90 As Long
loc_416F1F: var_98 = CStr(Space(&HFF))
loc_416F36: var_94 = CStr(Space(&HFF))
loc_416F99: var_90 = GetVolumeInformation("c:\", var_94, Len(var_94), var_8C, 0, 0, var_98, Len(var_98))
loc_416FD2: var_88 = CStr(Right("00000000" & Hex(var_8C), 8))
loc_416FDE: Exit Sub
End Sub

Private Sub Proc_10_1_419820(arg_C) '419820
'Data Table: 4014A4
loc_4196A8: var_A8(0) = CByte("&h" & Mid(arg_C, 1, 2))
loc_4196E3: var_A8(1) = CByte("&h" & Mid(arg_C, 3, 2))
loc_41971E: var_A8(2) = CByte("&h" & Mid(arg_C, 5, 2))
loc_419759: var_A8(3) = CByte("&h" & Mid(arg_C, 7, 2))
loc_41980E: var_88 = CStr(CVar(CStr(Right("0000" & Hex(CRCB(var_A8(0))), 4))) & Right("0000" & Hex(CRCB(var_A8(2))), 4))
loc_41981C: Exit Sub
End Sub

Private Sub Command2_Click() '4191F0
'Data Table: 402FDC
Dim var_B0 As TextBox
loc_419084: var_88 = Proc_10_1_419820(Proc_10_0_416FE0())
loc_4190B5: var_D4 = Trim(CVar(Me.Text2.Text))
loc_4190C0: var_E4 = Ucase(var_D4)
loc_4190D8: If (Ucase(var_88) = var_E4) Then
loc_4190E7:   var_B0 = Me.Global.App
loc_419100:   var_100 = Me.Global.App
loc_419119:   var_114 = Me.Global.App
loc_419164:   SaveSetting("DITAI", "XLB" & CStr(App.Major) & "." & CStr(App.Minor) & "." & CStr(App.Revision), "FLAG1", var_88)
loc_4191A6:   MsgBox("恭喜你注册成功!", &H40, "注册成功", var_D4, var_E4)
loc_4191B6:   Call Command1_Click()
loc_4191BE: Else
loc_4191DF:   MsgBox("序列号不正确,请重新输入!", &H10, "错误", var_D4, var_E4)
loc_4191EF: End If
loc_4191EF: Exit Sub
End Sub
```

`Proc_10_0_416FE0` 是获取机器码,`Proc_10_1_419820` 是计算对应的序列号。

序列号计算这里的反编译代码漏了个参数。观察反汇编的 P-Code:

```
loc_419764: LitI4 2
loc_419769: LitI4 0
loc_41976E: FLdRfVar var_A8
loc_419771: Ary1LdRf
loc_419772: ImpAdCallI2 CRCB()
      
' ...
      
loc_419781: LitI4 2
loc_419786: LitI4 2
loc_41978B: FLdRfVar var_A8
loc_41978E: Ary1LdRf
loc_41978F: ImpAdCallI2 CRCB()
```

应当为 `CRCB(&var_A8(0), 2)` 和 ``CRCB(&var_A8(2), 2)``(其实我是直接在调试器看传参的,手动看也没差多少)。

这个 CRCB 是 CRC.DLL 的一个导出函数,用查表来加速运算。实际上就是标准的 CRC16 算法(初始值为 `0`)。

这些搞清楚后,就可以写算法注册机了。

将序列号分为两半,每一半转换为对应的字节(两字节),求对应的 CRC16 值,然后拼接字符串。

下面是 CRC16 的 Python 代码,你可以试试将其改写为完整的算法注册机:

```
def crc16(data: bytes, crc: int = 0):
    """
    不查表的 CRC16 实现,等价于 CRC.DLL 提供的 CRCB 函数。
    :param data: 计算 CRC16 的内容
    :param crc: 初始 CRC16 值,默认为 0
    :return: 对应的 CRC16 值
    """
    for byte in data:
      crc ^= byte << 8
      for _ in range(8):
            if crc & 0x8000:
                crc = (crc << 1) ^ 0x1021
            else:
                crc <<= 1
    return crc & 0xFFFF

print(hex(crc16(b"\x44\x0D"))) # 0x10a5
print(hex(crc16(b"\x23\x9C"))) # 0x1180
```

---

如果想完全跳过注册验证,可以对照反编译的代码和 P-Code 来魔改。

首先对计算序列号的函数 `Proc_10_1_419820` 交叉查询引用,只有两处。一处是注册窗口初始化,还有一处是点击注册时调用。

直接看前者即可,可以看到如下序列号检测代码:

```vb
loc_41EC18: If (Len(var_98) > 1) Then                            // 必须成立
loc_41EC2E:   If (var_98 = Call Proc_10_1_419820(var_A4)) Then   // 必须成立
loc_41EC31:   Call Command1_Click()
loc_41EC36:   Exit Sub
loc_41EC37:   End If
loc_41EC37: End If
```

第一个条件,查看对应的 P-Code 反汇编:

```vb
loc_41EC12: F501000000            LitI4 1
loc_41EC17: DB                  GtI4
loc_41EC18: 1CAF02                BranchF loc_41EC37
```

将 loc_41EC12 入栈的值修改为负数即可永远成立,如 `F501000080`。

第二个条件是检查字符串是否匹配:

```vb
loc_41EC26: 6C68FF                ILdRf var_98
loc_41EC29: 6C58FF                ILdRf var_A8
loc_41EC2C: FB30                  EqStr
loc_41EC2E: 1CAF02                BranchF loc_41EC37
```

将 loc_41EC26 的对应字节码改成下面那行一样的 ILdRf var_A8 即可。

最后,将补丁好后的程序重新用反编译工具打开,查看更改:

```vb
loc_41EC18: If (Len(var_98) > -2147483647) Then
loc_41EC2E:   If (Call Proc_10_1_419820(var_A4) = Call Proc_10_1_419820(var_A4)) Then
loc_41EC31:   Call Command1_Click()
loc_41EC36:   Exit Sub
loc_41EC37:   End If
loc_41EC37: End If
```

当然,因为不确定是否有完整性校验,因此还是建议手动算号注册。

页: [1]
查看完整版本: 求个教程