翼度科技»论坛 编程开发 .net 查看内容

ServiceStack.Redis系列破解

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
ServiceStack.Redis免费版有个每小时6000次访问限制,网上目前的破解方式都是dnspy修改源码或者Github上下载源码修改,这样的方式不是不好,主要是不方便NUGET版本管理和更新。
 
反编译看了下注册逻辑,发现很简单就是LicenseKey类:
  1. public class LicenseKey
  2. {
  3.     public string Ref { get; set; }
  4.     public string Name { get; set; }
  5.     public LicenseType Type { get; set; }
  6.     public long Meta { get; set; }
  7.     public string Hash { get; set; }
  8.     public DateTime Expiry { get; set; }
  9. }
复制代码
  1. Expiry :过期时间
复制代码
  1. LicenseType :类型,无脑选择Business或者Enterprise就可以
复制代码
  1. Hash :一个RSA签名数据,来源是GetHashKeyToSign方法的数据
复制代码
  1.     public static string GetHashKeyToSign(this LicenseKey key)
  2.     {
  3.         return $"{key.Ref}:{key.Name}:{key.Expiry:yyyy-MM-dd}:{key.Type}";
  4.     }
复制代码
由于RSA签名是私钥签名,私钥肯定是找不到的,所以想写个注册机也不行了。
我们可以另辟蹊径,用打补丁的方式来HOOK校验签名的方法,让他直接返回true
这是他原始的校验方法:
  1.     public static bool VerifySha1Data(this System.Security.Cryptography.RSACryptoServiceProvider RSAalg, byte[] unsignedData, byte[] encryptedData)
  2.     {
  3.         using var sha = TextConfig.CreateSha();
  4.         return RSAalg.VerifyData(unsignedData, sha, encryptedData);
  5.     }
复制代码
这里我们采用HarmonyLib库来补丁,写过游戏Mod的应该很熟悉这个库:
  1. [HarmonyPatch]
  2. public class ServiceStackPath
  3. {
  4.     [HarmonyPrefix, HarmonyPatch(typeof(LicenseUtils), nameof(LicenseUtils.VerifySha1Data))]
  5.     private static bool VerifySha1DataPrefix(ref bool __result)
  6.     {
  7.         __result = true;
  8.         return false;
  9.     }
  10.     public static void Path()
  11.     {
  12.         var harmony = new Harmony("com.ServiceStack.Text.Path");
  13.         harmony.PatchAll();
  14.         var licenseKey = new LicenseKey()
  15.         {
  16.             Expiry = DateTime.Now.AddYears(50),
  17.             Type = LicenseType.Enterprise,
  18.             Ref = "9999",
  19.             Name = "Admin",
  20.             Meta = 9999
  21.         };
  22.         licenseKey.Hash = Convert.ToBase64String(GenerateRandomBytes(16));
  23.         var serializeToString = TypeSerializer.SerializeToString(licenseKey);
  24.         var key = $"{licenseKey.Ref}-{Convert.ToBase64String(Encoding.UTF8.GetBytes(serializeToString))}";
  25.         LicenseUtils.RegisterLicense(key);
  26.         //LicenseUtils.RegisterLicense("9999-e1JlZjo5OTk5LE5hbWU6QWRtaW4sVHlwZTpFbnRlcnByaXNlLE1ldGE6OTk5OSxIYXNoOndkcEtNQ21ZYmlnQTk1TXFrV25ldHc9PSxFeHBpcnk6MjA3NC0wMS0wM1QxNDo1MzoxOC4yMjk5MDU3KzA4OjAwfQ==");
  27.     }
  28.     private static byte[] GenerateRandomBytes(int length)
  29.     {
  30.         var randomBytes = new byte[length];
  31.         // 使用 RNGCryptoServiceProvider 生成安全的随机字节序列
  32.         using var rng = new RNGCryptoServiceProvider();
  33.         rng.GetBytes(randomBytes);
  34.         return randomBytes;
  35.     }
  36. }
复制代码
使用的时候在程序入口调用一次ServiceStackPath.Path()就可以了,或者按照官方的方式在config文件或者注册表里面写入上面的KEY他自己注册也行   Path方法中写了具体的KEY生成了逻辑,也可以启用最后一行的注释用生成好的KEY也是一样的。
这样貌似还可以顺便破解他其他收费的库的限制,随带一提直接Path掉LicenseUtils.ActivatedLicenseFeatures()方法的返回值让他返回All也是可行的,但是能直接通过原始注册的方式来实现还是用注册的方式来实现。
 
这样操作后后续升级版本也不用再破解
 
[code][/code]
来源:https://www.cnblogs.com/mldcy/Undeclared/17943283
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具