吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 494|回复: 1
收起左侧

[求助] 求个教程

[复制链接]
ayhdnlp 发表于 2024-4-17 16:44
本帖最后由 ayhdnlp 于 2024-4-17 17:00 编辑

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

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

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

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

建议使用 VB-Decompiler 分析算法,然后编写算法注册机。


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 交叉查询引用,只有两处。一处是注册窗口初始化,还有一处是点击注册时调用。

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

  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 反汇编:

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

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

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

  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 即可。

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

  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

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

免费评分

参与人数 2吾爱币 +2 热心值 +2 收起 理由
ayhdnlp + 1 + 1 谢谢@Thanks!
xihawuzu + 1 + 1 热心回复!

查看全部评分

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-21 22:15

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表