千人千面 发表于 2022-9-22 14:33

通过反射注入去除Spire.Office的PDF水印

本帖最后由 千人千面 于 2022-9-22 14:44 编辑

上一篇帖子通过dnSpy逆向爆破了Spire.Xls的水印
然后有大佬@cdj68765 提供了更加简单粗暴的思路和方法,就是通过反射直接赋值激活信息。
我根据大佬提供的代码片段和思路写了一个简单的拓展类,每次New Workbook或者New Document的时候直接调用即可注入激活信息。
使用最新的Nuget包:Spire.Office 7.9.0
目前已知的激活信息有2个分别是:
Spire.Spreadsheet
Spire.DocViewer.Wpf
如果有大佬能提供更多的激活字符串:keai
下面是调用和拓展方法
Excel

Workbook wb = new Workbook();
wb.Crack();
//或者
Workbook wb = InjectLicense(new Workbook());

Word

Document dc = new Document();
dc.Crack();
//或者
Document dc = InjectLicense(new Document());


    public static class SpireOfficeHelpers
    {
      /// <summary>
      /// 注入激活信息
      /// </summary>
      /// <param name="workbook"></param>
      public static void Crack(this Workbook workbook)
      {
            InjectLicense(workbook);
      }
      /// <summary>
      /// 注入激活信息
      /// </summary>
      /// <param name="document"></param>
      public static void Crack(this Document document)
      {
            InjectLicense(document);
      }
      /// <summary>
      /// 注入激活信息,并返回该类型
      /// </summary>
      /// <typeparam name="T"></typeparam>
      /// <param name="t"></param>
      /// <returns></returns>
      public static T InjectLicense<T>(T t) where T : class
      {
            var InternalLicense = t.GetType().GetProperty("InternalLicense", BindingFlags.NonPublic | BindingFlags.Instance);
            var TypeLic = InternalLicense.PropertyType.Assembly.CreateInstance(InternalLicense.PropertyType.GetTypeInfo().FullName);
            foreach (var item in TypeLic.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (item.FieldType.IsArray)
                {
                  item.SetValue(TypeLic, new string[] { "Spire.Spreadsheet", "Spire.DocViewer.Wpf" });
                }
                else if (item.FieldType.IsEnum)
                {
                  item.SetValue(TypeLic, 3);
                }
            }
            InternalLicense.SetValue(t, TypeLic);
            return t;
      }
    }

pjy612 发表于 2023-1-17 12:45

这种库类型的感觉还是拿 HarmonyLib 直接 Patch 最快。。。


class SpireOfficePatch
{
    static object licenseCache;
   
   
    static bool Prefix_SpireOffice_LicenseProvider_GetLicense(LicenseContext context, Type type, object instance, bool allowExceptions, ref object __result, MethodInfo __originalMethod)
    {
      if (licenseCache != null)
      {
//有构建过 的 直接拦截返回
            __result = licenseCache;
            return false;
      }
      var declaringType = __originalMethod.DeclaringType;
      MethodInfo tempMethod = AccessTools.FirstMethod(declaringType, m => m.GetParameters().Any() && m.GetParameters().ParameterType == typeof(Stream) && m.ReturnType != typeof(void));
      if (tempMethod != null)
      {
            var licType = tempMethod.ReturnType;
//构建 license对象 然后 给关键点赋值 (这里就脱敏处理 不提供完整逻辑了            
var o = Activator.CreateInstance(licType);
            
//........给 license对象 o的 关键字段 反射赋值(这里就脱敏处理 不提供完整逻辑了   

            //直接缓存license对象 并拦截返回值 返回上面 自行构建的对象,这样 直接跳过后续的一大段验证逻辑。
            __result = licenseCache = o;
            return false;
               
            
      }
      return true;
    }

    internal static void Patch()
    {
      Harmony.CreateAndPatchAll(typeof(SpireOfficePatch),nameof(SpireOfficePatch));
    }
}

加个 HarmonyX 的 包,然后 程序入口找个地方调用 一次 SpireOfficePatch.Patch(); 就行了 基本通杀整个 Spire.Office 库...
而且 只需要分析好DLL之后 ,直接 在运行时 对 相关DLL进行 Hook,不用改动 原来的DLL。也不用处理强签名依赖啥的。

zxf123123 发表于 2022-10-7 20:50


去水印好点子厉害的大佬

lwp72495lwp 发表于 2022-9-22 14:57

学习了,感谢楼主

email123 发表于 2022-9-22 16:33

咋使用哦,不会哦,lz来个成品学习下{:1_893:}

zhang120300 发表于 2022-9-22 16:43

学习了。

XiaoZouYu 发表于 2022-9-22 17:04

正好要用这个,谢谢楼主

wsf994 发表于 2022-9-22 18:00

学习了。

zjkedy 发表于 2022-9-22 19:32

支持技术帖 ,:victory:

nuxingxp 发表于 2022-9-22 19:51

没看有懂呢,楼主。

sololdz 发表于 2022-9-23 07:34

学习了,感谢,研究研究

varm 发表于 2022-9-23 09:50

确实可用,感谢分享
页: [1] 2 3 4 5 6
查看完整版本: 通过反射注入去除Spire.Office的PDF水印