吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9269|回复: 69
上一主题 下一主题
收起左侧

[.NET逆向] 虚拟串口驱动专业版 Eltima Virtual Serial Port Driver Pro V11.0.1068 IL代码分析

  [复制链接]
跳转到指定楼层
楼主
zyyujq 发表于 2025-4-24 12:39 回帖奖励
虚拟串口驱动专业版 Eltima Virtual Serial Port Driver Pro 最新中文版本 V11.0.1068 IL代码分析


运行环境:WIN10、WIN11
涉及工具:dnSpy
教程类型:逆向限制,算法分析等
是否讲解思路和原理:是
以下为图文内容:









主程序 vspdpro.exe 的破解和汉化:

Virtual Serial Port Driver 版本从 V10.0.844开始到现在的V11.0.1068,主程序为 vspdpro.exe,

都采用 MS Visual C# / Basic.NET 代码编译,且没有混淆代码,容易逆向。

逆向详解:


1、安装后,使用 dnSpy 打开 主程序 vspdpro.exe

2、逆向主程序,dnSpy 打开程序后,可以选择C#、VB、IL代码形式查看源代码

在 vspd.Control 下有 IsDemoKey、IsProKey

A、进入 vspd.Control.IsDemo


public bool IsDemo

{
        [CompilerGenerated]
        get
        {
                return this.<IsDemo>k__BackingField;                //注释:此处鼠标右键选择编辑IL指令,即改为return false,返回否,不是演示版。
        }
        [CompilerGenerated]
        private set
        {
                if (this.<IsDemo>k__BackingField == value)
                {
                        return;
                }
                this.<IsDemo>k__BackingField = value;
                this.OnPropertyChanged("IsDemo");
        }
}


IsDemo.get 删除多余的IL指令,只留如下:
0        0000        ldc.i4.0          //注解:值0
1        0001        ret                //返回,上面值0,即 false


编辑IL指令后:
public bool IsDemo
{
        [CompilerGenerated]
        get
        {
                return false;
        }
        [CompilerGenerated]
        private set
        {
                this.<IsDemo>k__BackingField = value;
                this.OnPropertyChanged("IsDemo");
        }
}


B、进入 vspd.Control.IsPro

public bool IsPro
{
        [CompilerGenerated]
        get
        {
                return this.<IsPro>k__BackingField;                   //注释:此处鼠标右键选择编辑IL指令,即改为return true,返回是,是专业版。
        }
        [CompilerGenerated]
        private set
        {
                if (this.<IsPro>k__BackingField == value)
                {
                        return;
                }
                this.<IsPro>k__BackingField = value;
                this.OnPropertyChanged("IsPro");
        }
}

IsPro.get 删除多余的IL指令,只留如下:

0        0000        ldc.i4.1          //注解:值1
1        0001        ret               //返回,上面值1,即 true

C、点击 vspd.vm.Activator ,下有DaysLimit、IsExpired、IsGoodToWork、IsDemoKey、IsProKey,修改方法同上。



修改 IsExpired 返回 false (未过期),
修改 IsGoodToWork 返回 true(工作OK),
修改 IsDemoKey 返回 false(非演示),
修改 IsProKey 返回 true(是专业版)

进入 vspd.vm.Activator.IsDemoKey


public override bool IsDemoKey
{
        get
        {
                if (!this.license.demo)
                {
                        int? days = this.license.days;
                        int num = 0;
                        return days.GetValueOrDefault() > num & days != null;
                }
                return true;              //注解:将上面if语句删除,将此改为 false ,即 get { return false; } ,IsDemoKey直接返回 false (不是演示版)。
        }
}

在get语句内,鼠标右键选择编辑IL指令,删除多余的指令,修改为如下:

0        0000        ldc.i4.0          //注解:值0
1        0001        ret                //返回,上面值0,即 false

进入 vspd.vm.Activator.DaysLimit

public override long DaysLimit

{
    get
    {
        return (long)this.license.days.GetValueOrDefault();
    }
}

返回可以修改为3650,过期天数为十年:



public override long DaysLimit
{
    get
    {
        return 3650L;
    }
}

鼠标右键选择编辑IL指令,删除多余的指令,修改为如下:



0        0000        ldc.i4    3650      //注解:值3650 (十六进制 0xE42)
1        0001        ret                   //返回,上面值3650,即3650天,十年




D、进入 vspd.Utils.LicenseUpdater ,修改证书更新


public void UpdateLicense()
{
        string text;
        uint num;
        for (;;)
        {
                text = this.Activator.LicenseStatus;
                if (this.Activator.IsDemoKey && this.Activator.IsExpired && text != "+STARTING")
                {
                        text = "DEMO_IS_OVER";
                }
                num = <PrivateImplementationDetails>.ComputeStringHash(text);
                if (num <= 890022063U)
                {
                        if (num > 516577132U)
                        {
                                goto IL_6B;
                        }
                        if (num == 215374295U)
                        {
                                goto IL_DB;
                        }
                        if (num != 516577132U)
                        {
                                break;
                        }
                        if (!(text == "+BADTIME"))
                        {
                                break;
                        }
                        if (!new AlertWindow
                        {
                                FirstLine = Resources.IDSA_badlocaltime,
                                SecondLine = Resources.IDSA_setdatetime,
                                OkButtonText = Resources.IDSA_btn_tryagain
                        }.Run(this.parentWindow))
                        {
                                return;
                        }
                        this.Activator.ActivateOnline("reactivate");
                }
                else if (num <= 2646111894U)
                {
                        if (num == 1181904525U)
                        {
                                goto IL_12F;
                        }
                        if (num != 2646111894U)
                        {
                                break;
                        }
                        if (!(text == "+BACKWARDTIME"))
                        {
                                break;
                        }
                        if (!new AlertWindow
                        {
                                FirstLine = Resources.IDSA_time_backward,
                                SecondLine = Resources.IDSA_trial_blocked,
                                OkButtonText = Resources.IDSA_btn_activate,
                                CancelButtonText = Resources.IDSA_btn_ordernow
                        }.Run(this.parentWindow))
                        {
                                goto IL_20E;
                        }
                        this.Activator.ActivateOnline("demo");
                }
                else if (num != 3427124686U)
                {
                        if (num == 3457219322U)
                        {
                                goto IL_F0;
                        }
                        if (num != 3914721229U)
                        {
                                break;
                        }
                        if (!(text == "+WRONG_HID"))
                        {
                                break;
                        }
                        if (!new AlertWindow
                        {
                                Title = Resources.IDSA_title_reactivation_required,
                                FirstLine = Resources.IDSA_wrong_hid,
                                SecondLine = Resources.IDSA_failed_reactivate,
                                OkButtonText = Resources.IDSA_btn_tryagain,
                                CancelButtonText = Resources.IDSA_btn_upd_info
                        }.Run(this.parentWindow))
                        {
                                goto IL_372;
                        }
                        this.Activator.ActivateOnline("reactivate");
                }
                else
                {
                        if (!(text == "+STARTING"))
                        {
                                break;
                        }
                        Thread.Sleep(500);
                        this.Activator.UpdateStatus();
                }
        }
        goto IL_393;
        IL_6B:
        if (num != 609027880U)
        {
                if (num == 890022063U)
                {
                        if (text == "0")
                        {
                                goto IL_183;
                        }
                }
        }
        else if (text == "NO_AVAILABLE_ACTIVATIONS")
        {
                if (new AlertWindow
                {
                        Title = Resources.IDSA_title_cant_reactivate_anymore,
                        FirstLine = Resources.IDSA_max_hids,
                        SecondLine = Resources.IDSA_msg_maxhids_update.Replace("{update_info_button}", Resources.IDSA_btn_upd_info),
                        OkButtonText = Resources.IDSA_btn_activate,
                        CancelButtonText = Resources.IDSA_btn_upd_info
                }.Run(this.parentWindow))
                {
                        this.<UpdateLicense>g__ShowRegisterWindow|5_1();
                        return;
                }
                this.OpenChangeHidUrl();
                return;
        }
        goto IL_393;
        IL_DB:
        if (!(text == "ALREADY_ACTIVATED"))//已激活
        {
                goto IL_393;
        }
        goto IL_183;
        IL_F0:
        if (text == "DEMO_IS_OVER")
        {
                this.<UpdateLicense>g__ShowWizard|5_0(new WizardModel.Expired());
                return;
        }
        goto IL_393;
        IL_12F:
        if (text == "KEY_BANNED")
        {
                if (new AlertWindow
                {
                        FirstLine = Resources.IDSA_error_key_banned,
                        SecondLine = Resources.IDSA_support_email,
                        OkButtonText = Resources.IDSA_btn_activate,
                        CancelButtonText = Resources.IDSA_btn_ordernow
                }.Run(this.parentWindow))
                {
                        this.<UpdateLicense>g__ShowRegisterWindow|5_1();
                        return;
                }
                this.OpenPurchaseUrl();
                return;
        }
        goto IL_393;
        IL_183:
        if (this.Activator.IsDemoKey || this.Activator.DaysLimit > 0L)
        {
                this.<UpdateLicense>g__ShowWizard|5_0(new WizardModel.Message());
                return;
        }
        return;
        IL_20E:
        this.OpenPurchaseUrl();
        return;
        IL_372:
        this.OpenChangeHidUrl();
        return;
        IL_393:
        if (new AlertWindow
        {
                Title = Resources.IDSA_title_other_error,
                FirstLine = Resources.IDSA_need_activate,
                SecondLine = Resources.IDSA_error_details.Replace("{error}", text),
                OkButtonText = Resources.IDSA_btn_tryagain,
                CancelButtonText = Resources.IDSA_btn_ordernow
        }.Run(this.parentWindow))
        {
                this.<UpdateLicense>g__ShowRegisterWindow|5_1();
                return;
        }
        this.OpenPurchaseUrl();
}

修改为空:
// vspd.Utils.LicenseUpdater
public void UpdateLicense()
{
}

编辑IL指令为一句
0        0000   ret      //返回空,不更新证书

E、自定义注册信息,注册名,进入 vspd.AboutWindow

public string Registered
{
        [CompilerGenerated]
        get
        {
                return this.<Registered>k__BackingField;        //此处改为 return "ChinaRadKe";
        }
}

删除多余IL指令,修改为:
0        0000        ldstr        "ChinaRadKe"
1        0005        ret

F、自定义注册信息,注册类型// vspd.AboutWindow

public string License
{
        [CompilerGenerated]
        get
        {
                return this.<License>k__BackingField;        //此处改为        return "Single License";
        }
}


删除多余IL指令,修改为 Site License 或 Single License:
0        0000        ldstr        "Single License"
1        0005        ret


G、汉化 vspd.Properties.Resources 资源,实现中文化。汉化资源可以使用 dnSpy 直接保存导出和导入。

下载 vspd.Properties.Resources, 在 dnSpy 打开的主程序 vspdpro.exe 中,删除原 vspd.Properties.Resources,

然后,导入下载的资源 vspd.Properties.Resources,汉化完成。

H、dll劫持hook


单纯破解主程序 vspdpro.exe 没有绕过服务程序的网络验证,仍然无法真正激活程序,超过14天试用期,主程序无法创建虚拟串口。

vspdpro_service.exe 的破解是巧妙的绕过验证:

激活证书在 C:\ProgramData\Electronic Team\VSPDPro\vspdpro.act

编写 WinHttp.dll 劫持 hook,劫持网络注册信息,代码很长,不再详述。
截取系统 WinHttp.dll 网络验证的返回值,将返回值修改为已经激活即可。

其中最关键的两个值 key_type errorCode,只要劫持这2个返回值即可:

key_type 授权类型:
0 = Single License 单机版许可授权
1 = Limited func (license_options) 表示根据功能授权,license_options的值表示功能的限制数量
2 = Limited time(key_options=days) 表示根据时间授权,key_options的值表示授权天数。
3 = OEM

errorCode 授权状态:
0 = ALREADY_ACTIVATED
DEMO_IS_OVER
NO_AVAILABLE_ACTIVATIONS
KEY_BANNED
+REACTIVATE
+STARTING

激活原理:

vspdpro.act 注册激活信息:
Act data:
{
activationDate: 2025-01-01
errorCode: ALREADY_ACTIVATED
firstActivation: 2025-01-01
hid: hid
key_type: 0
license_key_code:11111-22222-33333-44444-55555
licenseName: Single
nextActivation: 2120-01-01
product_id: 73
product_name: Virtual Serial Port Driver PRO
product_version: 9
registed_name: China Red Ke
serverDate: 2025-01-01
serverTime: 1577836800 (时间秒、时间戳)
}


证书信息字段:
hid=hid
license_key_code:11111-22222-33333-44444-55555
licenseName=Single
product_id=73
product_name=Virtual Serial Port Driver PRO
product_version=9
serverDate=2025-01-01
activationDate=2025-01-01
nextActivation=2120-01-01
firstActivation=2025-01-01
errorCode=ALREADY_ACTIVATED
key_type=0
registed_name=China Red Ke
license_options=
key_options=
serverTime=1577836800 (时间秒、时间戳)
activation_param=
hash=977e5de9c47e4dbb03e25aafa5b0f806


1、注册信息返回代码“ALREADY_ACTIVATED”字符,代表已经激活;
2、注册信息返回激活数据 Act data 合法,代表激活信息正常;
3、注册信息密钥类型 key_type,代表用户激活类型,必须与许可证密钥码 license_key_code 计算相应;
        0 表示激活用户, 代码 errorCode 为: ALREADY_ACTIVATED
        3 表示OEM用户,代码 errorCode 为: +WRONG_OEM
4、注册信息返回激活开始、结束时间、服务器时间相应合法,代表已经激活正常;
5、以上所有注册信息的哈希验证合法,代表已经激活正常;


服务程序 vspdpro_service.exe 代码中,根据激活文件内容由此产生逻辑布尔值判断:
1、act file: true 验证激活文件是有效的
2、Activation expired: false 验证激活已过期是无效的
3、External Status: ALREADY_ACTIVATED 验证外部状态是已经激活
4、IsGoodToWork: true 验证运行状态好,转向正常虚拟工作
5、IsTimeBackward: false 验证时光倒流是无效的
6、IsExpired: false 验证激活已过期是无效的
7、DaysLimit: 4 验证试用软件天数限制
8、NumberLimit: 2147483647 验证试用软件时间限制(与天数相应)
9、IsExpired: false 验证激活已过期是无效的

注册证书状态有以下内容:

1、+STARTING 表示演示结束,给出字符串“DEMO_IS_OVER”
2、+BACKWARDTIME 表示本机时间与服务器时间倒置,表示修改本机时间到过去的非法行为
3、+BADTIME 表示本机时间不正确
4、+WRONG_HID 表示工作正常,错误隐藏
5、NO_AVAILABLE_ACTIVATIONS 表示没有可用的激活
6、DEMO_IS_OVER 表示演示结束
7、ALREADY_ACTIVATED 表示已经激活
8、KEY_BANNED 表示密钥被禁止


详细定义如下:
public const string APE_OK = “0”;
public const string APE_ALREADY = “ALREADY_ACTIVATED”;
public const string APE_DEMO_IS_OVER = “DEMO_IS_OVER”;
public const string APE_MAX_HIDS = “NO_AVAILABLE_ACTIVATIONS”;
public const string APE_KEY_BANNED = “KEY_BANNED”;
public const string APE_BAD_KEY = “CANT_FIND_KEY_CODE”;
public const string APE_BAD_REQ_NOHID = “NO_REQUEST_HID”;
public const string APE_BAD_REQ_NOKEY = “NO_REQUEST_KEY_CODE”;
public const string APE_BAD_REQ_NOPID = “NO_REQUEST_PRODUCT_ID”;
public const string APE_BAD_REQ_NOVER = “NO_REQUEST_PRODUCT_VERSION”;
public const string APE_UNK_PRODUCT = “UNKNOWN_PRODUCT”;
public const string APE_UNK_VERSION = “KEY_NOT_FOR_THIS_VERSION”;
public const string APE_UNK_LICENSE = “UNKNOWN_LICENSE”;
public const string APE_SRV_ERR_SAVE = “CANT_SAVE_ACTIVATION_RECORD”;
public const string APE_SRV_ERR_UPD = “CANT_UPDATE_ACTIVATION_RECORD”;
public const string APE_STARTING = “+STARTING”;
public const string APE_WRONG_HID = “+WRONG_HID”;
public const string APE_WRONG_PRODUCT_VERSION = “+WRONG_PRODUCT_VERSION”;
public const string APE_WRONG_OEM = “+WRONG_OEM”;
public const string APE_REACTIVATE = “+REACTIVATE”;
public const string APE_GRACE = “+GRACE”;
public const string APE_GRACE_EXPIRED = “+GRACE_EXPIRED”;
public const string APE_OFFLINE = “OFFLINE”;
public const string APE_BAD_LOCALTIME = “+BADTIME”;
public const string APE_TIME_BACKWARD = “+BACKWARDTIME”;
public const string APE_CORRUPTED_DATA = “+CORRUPTED”;
public const string APE_OUTDATED = “+OUTDATED”;
public const string APE_CANNOT_SAVE_FILE = “+CANNOT_SAVE_DATA”;
public const string AKEY_demo = “demo”;
public const string AKEY_reactivate = “reactivate”;


官方证书类型:
Trial Version License
Single License (Standard/PRO version)
SDK License
Site License
Source License

详细逆向资源本地下载 :  
  

VSPD.rar (1.51 MB, 下载次数: 1176)


官方原版安装文件下载:虚拟串口驱动专业版 Eltima Virtual Serial Port Driver Pro 最新原版中文版本 V11.0.1068

https://cdn.electronic.us/products/vspd/windows/download/vspd.exe


但美国或许禁止了中国IP下载,上面地址可能无法下载。

免费评分

参与人数 17威望 +1 吾爱币 +37 热心值 +13 收起 理由
六卖神剑 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
笙若 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ldy2333 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ezios + 1 + 1 谢谢@Thanks!
siriusmht + 1 + 1 谢谢@Thanks!
foxwolf + 1 谢谢@Thanks!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
lonchide + 1 热心回复!
vicky526356 + 1 + 1 感谢楼主,跟着步骤来成功了。工控牛马的工具又升级了。
ZCShou + 1 【注意】作者破解商业软件后售卖。。。
apull + 1 + 1 谢谢@Thanks!
Carinx + 1 + 1 谢谢@Thanks!
610100 + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
jinronghuan + 1 + 1 谢谢@Thanks!
yahan + 1 + 1 谢谢@Thanks!
xiaolitao + 1 谢谢@Thanks!
lookat + 1 + 1 谢谢@Thanks!

查看全部评分

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

推荐
renpeng009 发表于 2025-4-24 13:59
国内可以下载,速度飞快
推荐
pwdobwq 发表于 2025-4-25 10:21
suifenging 发表于 2025-4-25 09:31
楼主,这是你的博客吧,https://blog.csdn.net/zyyujq?type=blog

别搭理他,有几年了,汉化破解记得要钱的。
推荐
yearnxiao 发表于 2025-4-27 16:21
3#
niuboy 发表于 2025-4-24 12:56
感谢大佬分享
4#
花开一夏又一夏 发表于 2025-4-24 13:13
谢谢。。。
5#
liyitong 发表于 2025-4-24 13:15
官方原版安装文件lanzou下载地址:
https://liyitong.lanzout.com/iHAWK2uc36ji
6#
mhdythaha 发表于 2025-4-24 13:24
感谢分享
7#
4leafcolver 发表于 2025-4-24 13:26
一直在用virtual serial port driver,有空学习一下楼主的
8#
Parsley 发表于 2025-4-24 13:51
感谢分享!!
9#
6xing 发表于 2025-4-24 14:21
我的是Configure Virtual Serial Port Driver界面咋不一样,不过也不用这么复杂的
10#
fibx 发表于 2025-4-24 15:26
多谢大佬分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2026-2-14 15:53

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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