由破解11月6日最新版Componentart Web.UI控件来说CA控件的授权实现以及一些感想

 

Lost刚看完了,距离上一篇 解析Global.asax和AutoEventWireup属性 已经有段时间了,我今天再来写篇文章吧,介绍下ca控件的相关情况先。

ComponentArt是全球最知名的用户界面控件开发商之一,其.NET平台下的用户界面控件及数据可视化技术处于世界领先水平,他们一直为全球各个国家和地区的软件开发者提供优质而全面的程序界面技术。自2002年起,CompnentArt一直在进行ASP.NET平台Web用户界面技术的开发和研究,直至今日,他们的旗舰产品ComponentArt Web.UI已经被广泛应用到各种ASP.NET和ASP.NET AJAX应用程序中,其优良的品质和美妙的外观获得众多软件开发人员的信赖。(摘自某控件网的开发商介绍,当然该公司旗下还拥有一个非常优秀的图表控件ComponentArt Charting,那先进的图表制作向导, 高级的数据结构和灵活的图表模型我就不多说了。嘎嘎~)

作为一名Asp.Net开发人员不会不知道ComponentArt Web.UI了,这可以说是最早一批我们接触到的asp.net第三方控件了,伴随著Asp.Net的一路走来,ComponentArt Web.UI控件也从1.5到3.0、2006.1到2008.2紧跟.net的步伐,ComponentArt Web.UI也不乏成功应用,著名.net平台web2.0软件提供商Telligent旗下的CommunityServer就采用了ComponentArt Web.UI控件,而CommunityServer的用户包括微软、myspace、金蝶等软件大亨,还有人气非常高的微软MVP社区MSMVPS,大家肯定经常访问吧。

昨天下午,无意中发现11月6日ComponentArt Web.UI发布了2008.2.1204,立即下载下来,想看看有什么更新,可是苦找了n久都没发现一个有用的注册码(ComponentArt Web.UI每发布一次,ComponentArt.Licensing.Manager.exe算法都和以前不一致了),如是就想到一个前辈的破解方法(时间久了已经不知道是哪位前辈出的招了),破解如下:

1.从官方下载一个ComponentArt Web.UI 2008.1,从网上找一个注册码(3JKX6-YJW6X-GJJDP),下载ComponentArt Web.UI 2008.2版本(网上有三个,这个就看你的需要了)。

2.安装ComponentArt Web.UI 2008.1,只需要选择安装Licensing.Manager就可以了,安装后拷贝出ComponentArt.Licensing.Manager.exe程序,现在已经不需要2008.1了,可以卸载了。

3.安装ComponentArt Web.UI 2008.2,提取成功后,就可以在系统登录用户的临时目录(默认在“ C:\Documents and Settings\登录名\Local Settings\Temp”目录,为了较少c盘读写次数和系统垃圾我在环境变量里把用户TMP和TEMP变量更换到" d:\temp"目录下了,所以如果你也更改了,请不要忘记到你自定义目录里去),找一个名称类似于这种“ {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}”Guid类型的目录(可能有多个,请仔细查找),如果里面有dotnetinstaller.exe、corecomp.ini和另外一个Guid类型目录,则进入到该Guid目录里,用第一步得到的ComponentArt.Licensing.Manager.exe文件替换掉该目录下的文件。然后一路Next到License Keys选项,选择“Enter License Now”,点击Next;
4.这时就会运行刚才替换到的ComponentArt.Licensing.Manager.exe文件,输入第一步的注册码,确定后,完成安装,注意要选中SourceCode选项,因为这就是我们要研究的(如果直接选择“Complete”选项则会默认安装所有)。

这样就完成ComponentArt Web.UI 2008.2的代码安装了,下面来简单说下破解原理,实际这是在安装中来了一个欺骗法,从运行ComponentArt Web.UI的安装程序就知道,CA控件的安装程序采用了InstallShield,这可是软件安装、配置软件包和升级解决方案领域内公认的标准,强大灵活而又简单易用哦,可惜的是现在还不支持直接调用.net(ComponentArt.Licensing.Manager.exe是.net程序,可以用Reflector一看就知道了,不过被混淆了,所以直接反编译ComponentArt.Licensing.Manager.exe里的算法,做注册机就不是很好实现了),所以在点击Enter License Now后的下一步时,安装程序会运行一个.net程序ComponentArt.Licensing.Manager.exe,该程序根据相应算法执行完注册码验证后把结果写入注册表后,WebUI的安装程序无法执行注册表内容的验证,而只是验证注册表是否用相应信息,然后进行源代码的安装。我们就是根据这个原理在安装途中进行掉包,让它验证注册码后将相应信息写入注册表,从而达到进行欺骗的目的。

由于操作过程很简单我就没有贴图了,当然如果你不想动手,或者想要操作过程中有什么问题,抑或需要相关文件的,直接和我联系、贴上邮箱都可以。

安装成功后到达安装目录里,就可以看到源代码文件夹了,里面有项目文件,大家现在就可以来研究研究CA控件的精髓了,不过个人觉得CA控件(当然并不局限于CA控件,应该可以说是ASP.net控件, web控件),最难的是美工和js(高水平的,现在工作的电脑那叫一个慢,这不,也凸显出js的重要了,打开几个网页就垮了,特别是国内的XXXX,我现在不敢访问了);而asp.net控件开发啃本书籍或研究下微软asp.net关于控件开发的源码、熟悉一下页面流程基本就掌握了,毕竟微软的服务还是很周到的。CA控件的JS写的非常好,对象设计的非常棒(js对象差不多和.net对象一致,极大的方便了编程),而且帮助文档特别好,果然是跟着微软走的。

看看CA控件安装后的源码,我们看看CA控件的License授权是怎么实现的吧?

CA控件用的是微软.net的License方式,该方式对所有组件和控件(包括 Windows 窗体控件和 ASP.NET 服务器控件)都应用相同的授权模型,它与 Microsoft ActiveX 控件的授权完全兼容,这个就不多说了,具体可以查看msdn。通过查看CA控件的源码我们发现了Licensing文件夹下的RedistributeLicenseProvider.cs文件,里面代码如下:

ContractedBlock.gif ExpandedBlockStart.gif RedistributableLicense实现
public class RedistributableLicenseProvider : System.ComponentModel.LicenseProvider
{
    
const string strAppKey = "This edition of ComponentArt Web.UI is licensed for XYZ application only.";
    
public override System.ComponentModel.License GetLicense(LicenseContext context, Type type, object instance, bool allowExceptions)
    {
        
if (context.UsageMode == LicenseUsageMode.Designtime)
        {
            
// 设计时不考虑是否能得到License 直接返回一个实例化的             
            return new ComponentArt.Licensing.Providers.RedistributableLicense(this"The App");
        }
        
else
        {
            
string strFoundAppKey;
            
// 运行时则要符合一定条件 
            HttpContext ctx = HttpContext.Current;
            strFoundAppKey 
= (string)ctx.Application["ComponentArtWebUI_AppKey"];
            
if (strAppKey == strFoundAppKey)
                
return new ComponentArt.Licensing.Providers.RedistributableLicense(this"The App");
            
else
                
return null;
        }
    }
}
public class RedistributableLicense : System.ComponentModel.License
{
    
private ComponentArt.Licensing.Providers.RedistributableLicenseProvider owner;
    
private string key;

    
public RedistributableLicense(ComponentArt.Licensing.Providers.RedistributableLicenseProvider owner, string key)
    {
        
this.owner = owner;
        
this.key = key;
    }
    
public override string LicenseKey
    {
        
get
        {
            
return key;
        }
    }
    
public override void Dispose()
    {
    }
}

RedistributableLicenseProvider类继承LicenseProvider,重写了GetLicense()方法,获得一个继承于License的RedistributableLicense类实例(该文件的注释说在Global.asax的Application_Start方法里为Application["ComponentArtWebUI_AppKey"]赋上和strAppKey 相等的值),在控件类里通过LicenseProviderAttribute标记该类指定RedistributableLicenseProvider来对该控件进行授权。

而控件类是通过WebControl(是所有CA控件的基类)来确定是否可以授予License的,WebControl主要代码如下:

ContractedBlock.gif ExpandedBlockStart.gif WebControl部分代码
internal System.ComponentModel.License License = null;
//该方法进行判断是否被授予许可证    
public virtual bool IsLicensed()
ExpandedBlockStart.gifContractedBlock.gif
{
  
if (License != nullreturn true
  
try
ExpandedSubBlockStart.gifContractedSubBlock.gif  
{
    
//确定是否可以为当前实例授予许可证,如果不能则会抛出异常
    
//LicenseManager.Validate()会调用RedistributableLicenseProvider类的GetLicense()来得到License,如果返回null 则会抛出异常
    License = LicenseManager.Validate(this.GetType(), this);
    
return true
  }

  
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif  
{
    
return false
  }

}
  
protected override void OnPreRender(EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif
{
  
base.OnPreRender(e);
  
//如果被授予License 调用ComponentArtPreRender()
  if (IsLicensed()) ComponentArtPreRender(e); 
}
    
protected override void Render(HtmlTextWriter output)
ExpandedBlockStart.gifContractedBlock.gif
{
  
// 如果未被授予License 调用RenderRedistributableWarning()不进行控件的呈现操作
  if (!IsLicensed())
ExpandedSubBlockStart.gifContractedSubBlock.gif  
{
    RenderRedistributableWarning(output); 
    
return
  }
 
  ComponentArtRender(output); 
  
}


protected void RenderRedistributableWarning(HtmlTextWriter output)
ExpandedBlockStart.gifContractedBlock.gif
{
  output.Write(
"<div style=\"background-color:#3F3F3F;border:1px;border-style:solid;border-bottom-color:black;border-right-color:black;border-left-color:lightslategray;border-top-color:lightslategray;color:cornsilk;padding:2px;font-family:verdana;font-size:11px;\">");
  
string productName = this.GetType().ToString().Replace("ComponentArt.Web.UI."""); 
  output.Write(
"<b>ComponentArt " + productName + "</b> :: ");
  output.Write(
"Unlicensed version. <br><br>"); 
  output.Write(
"This version is licensed for single application use only. <br><br>"); 
  output.Write(
"You can download the free trial version <a href=http://www.ComponentArt.com/ target=_blank><font color=silver>here</font></a>."); 
  output.Write(
"</div>"); 
}

具体过程和呈现逻辑我在注释中都说得很清楚了,下面我们看看安装包安装后自带的Componentart Web.UI.dll的license是如何进行管理的,通过.NET Reflector我们发现ComponentArt.Licensing.Providers命名空间下面虽然存在了RedistributableLicenseProvider类和RedistributableLicense类,但在控件类上却没有应用这两个类,而用的是RegistryFileLicenseProvider类和License类(该类继承于System.ComponentModel.License类)进行授权操作,还有一个TokenEncoding类是用来对Token进行解密的(我们这里就不进行讨论了,如果想做CA控件的注册机可以仔细分析这个类的代码了,只是该代码进行混淆了,但基本能看清楚)。RegistryFileLicenseProvider类代码如下:

ContractedBlock.gif ExpandedBlockStart.gif RegistryFileLicense实现
public class RegistryFileLicenseProvider : LicenseProvider
{
    
private string licenseFileName = "ComponentArt.Web.UI.lic";//License文件名
    private string registryRoot = @"SOFTWARE\ComponentArt\Web.UI for ASP.NET\2008.2";//注册表路径
    private string registryTokensNode = "Tokens";//注册表项
    
//是否得到Token
    
//通过解密Token字符串数组得出TokenItem结构,判断TokenItem结构的LicenseGuid和要被授权的Type的Guid是否相等
    private bool findLicenseToken(string[] tokens, string key, Type type)
    {
        
if (tokens == null)
        {
            
return false;
        }
        
bool flag = false;
        
foreach (string str in tokens)
        {
            TokenEncoding.TokenItem item 
= TokenEncoding.TokenDecrypt(str);
            
if (item.LicenseGuid.ToUpper() == type.GUID.ToString().ToUpper())
            {
                flag 
= true;
                key 
= item.LicenseKey;
            }
        }
        
return flag;
    }
    
public override System.ComponentModel.License GetLicense(LicenseContext context, Type type, object instance, bool allowExceptions)
    {
        
//运行时不检查
        if (context.UsageMode == LicenseUsageMode.Designtime)
        {
            
return new ComponentArt.Licensing.Providers.License(this"");
        }
        
string key = "";
        
string[] tokens = this.getTokenStringArrayFromRegistry();
        
bool flag = this.findLicenseToken(tokens, key, type);
        
if (!flag)
        {
            
//如果注册表项没有正确得到Token 则从License文件继续操作
            tokens = this.getTokenStringArrayFromFile();
            flag 
= this.findLicenseToken(tokens, key, type);
        }
        
if (flag)
        {
            
//正确得到Token 返回License
            return new ComponentArt.Licensing.Providers.License(this, key);
        }
        
return null;
    }
    
//从License文件获取Token字符串数组
    private string[] getTokenStringArrayFromFile()
    {
       
    }
    
//从注册表获取Token字符串数组
    private string[] getTokenStringArrayFromRegistry()
    {
        
    }
}

具体的授权原理和上述分析一致,那我们再看下WebControl是如何来确定是否可以授予许可证的,WebControl主要代码如下:

ContractedBlock.gif ExpandedBlockStart.gif WebControl部分代码
internal System.ComponentModel.License License = null;
private LicenseDice licenseDiceResult = LicenseDice.NotThrown;       
//该方法进行判断是否显示是demo版本警告 
private bool displayDemoWarning()
ExpandedBlockStart.gifContractedBlock.gif
{
    
//回传则不显示 否则打乱了人家操作 可不够UE的
    if (((this.Context != null&& (this.Page != null)) && (this.Context.Request != null))
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
foreach (string str in this.Context.Request.Params.AllKeys)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (((str != null&& str.StartsWith("Cart_")) && (str.IndexOf("_Callback"> 0))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return false;
            }

        }

    }

    
if (this.licenseDiceResult == LicenseDice.NotThrown)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{        
        Random random 
= new Random();
        
//不是每次都判断 概率
        if (random.Next(30== 3)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (!this.IsLicensed())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
//没有授予License 显示demo
                this.licenseDiceResult = LicenseDice.NotLicensed;
                
return true;
            }

            
this.licenseDiceResult = LicenseDice.Licensed;
            
return false;
        }

        
this.licenseDiceResult = LicenseDice.Licensed;
        
return false;
    }

    
if (this.licenseDiceResult == LicenseDice.Licensed)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
return false;
    }

    
return true;
}

//该方法进行判断是否被授予许可证
public virtual bool IsLicensed()
ExpandedBlockStart.gifContractedBlock.gif
{
    
if (this.License != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
return true;
    }

    
try
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{        
        
//确定是否可以为当前实例授予许可证,如果不能则会抛出异常
        
//LicenseManager.Validate()会调用RedistributableLicenseProvider类的GetLicense()来得到License,如果返回null 则会抛出异常
        this.License = LicenseManager.Validate(base.GetType(), this);
        
return true;
    }

    
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
return false;
    }

}
  
protected override void OnPreRender(EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif
{
    
base.OnPreRender(e);
    
if (!this.displayDemoWarning())
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
this.ComponentArtPreRender(e);
    }

}
      
protected override void Render(HtmlTextWriter output)
ExpandedBlockStart.gifContractedBlock.gif
{
    
//判断是否显示demo输出 
    if (this.displayDemoWarning())
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
this.RenderDemoWarning(output);
    }

    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
this.ComponentArtRender(output);
        
if (this.IsBrowserSearchEngine() && this.RenderSearchEngineStamp)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this.RenderCrawlerStamp(output);
        }

    }

}

protected void RenderDemoWarning(HtmlTextWriter output)
ExpandedBlockStart.gifContractedBlock.gif
{
    output.Write(
"<div style=\"background-color:#3F3F3F;border:1px;border-style:solid;border-bottom-color:black;border-right-color:black;border-left-color:lightslategray;border-top-color:lightslategray;color:cornsilk;padding:2px;font-family:verdana;font-size:11px;\">");
    output.Write(
"<b>ComponentArt " + base.GetType().ToString().Replace("ComponentArt.Web.UI."""+ "</b> :: ");
    output.Write(
"Demo version. <br><br>");
    output.Write(
"Please reload the page to continue with your evaluation. <br><br>");
    output.Write(
"You can purchase the full version <a href=http://www.ComponentArt.com/ target=_blank><font color=silver>here</font></a>.");
    output.Write(
"</div>");
}

private enum LicenseDice
ExpandedBlockStart.gifContractedBlock.gif
{
    NotThrown,
    Licensed,
    NotLicensed
}

这样我们就弄清楚了CA控件未注册版和注册版的License授予的实现细节以及一些呈现逻辑,知道原理后你就会轻而易举的定制你自己的License了,或者去掉License,其实仔细一想就会发现,就是通过上面的方法只能是破解安装了不带License检查的CA源码,但是实际上你写到注册表上的信息并不能通过官方dll的License检查,因为我们写入到注册表上的信息是错的,首先版本就不对,但我有点不明白的是安装程序怎么不去检查检查注册表中的版本信息呢?这样做确实有点让人想不明白?破解的也太简单了吧?不过我们头说的好,企业只负责做这个功能,而不管别人能不能破解了,剩下的就是法律的事情了,他们有法律来保护他们的知识产权,确实很有道理。说到底,可能也是企业觉得大公司用它的东西,不敢不给他钱,小公司就算给他打知名度了,所以就不能限制得太死了,就算这样,也比微软的windows策略好些吧,呵呵。

话说到InstallShield,InstallScript至今也不能直接调用.net的dll或者程序,这可不能不说是一种遗憾啊,为了能调用.net,只能把.net程序注册成Com组件然后才能用InstallScript进行调用。不过到现在随着飞信和Silverlight的应用,技术方面已经不是什么问题了,难道依旧是这个版权问题,仍然不得而知了。

 

PS:本文破解仅供研究、学习,请不要用于商业目的,对此本人不负任何责任。如果用于商业开发,请购买正版软件。


作者:Dean

出处:http://deanme.cnblogs.com/

 

转载于:https://www.cnblogs.com/DeanMe/archive/2008/11/15/1334031.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
漂亮的ComponentArtWebUI及Demo源码 产品特征: 先进的用户界面控件套装:为高级Web应用程序开发提供了16个优质的用户界面控件。 专为ASP.NET而设计:为三个先进且更强大的框架而设计:ASP.NET 1.0, ASP.NET 2.0和ASP.NET AJAX。 强大的客户端呈现技术:行业中最先进的Web用户界面技术。 深入整合ASP.NET AJAX:最理想的完全应用AJAX框架的控件。 全面的帮助文档和技术支持:提供了完善的产品在线帮助文档和全面的技术支持资源。 企业级服务和培训:为企业级项目开发定制专门的产品咨询和培训服务。 灵活的产品授权:针对开发者,服务和企业级应用提供不同的授权方式。 ComponentArt Web.UI 2007.1 更新信息 ComponentArt Web.UI 2007.1 版本中发布了三个最新的控件: ToolBar for ASP.NET ComboBox for ASP.NET Dialog for ASP.NET 以下为Web.UI组件2007.1版本中新增的功能特征: ComponentArt Grid 可以在Callback模式中缓存页面 (CallbackCachingEnabled和CallbackCacheSize属性)。 可在Callback模式中预加载页面到缓存中 (CallbackCacheLookAhead属性)。 页面在滑动条经过时可提取页面 (SliderFetchDelay属性)。 客户端滚动事件。 客户端beforeCallback事件。 ColumnResizeRedistributeWidth属性用于控制缩放状态。 ComponentArt Menu 引入(已选)checking和(未选)unchecking项的概念。允许菜单项成为复选框或者单元按钮。 引入(图标透明度)IconVisibility的概念。可使图标只在该项被选中或该项根目录时显示。 添加更多对上下文菜单扩展的控制:(TopGroupExpandDirection, TopGroupExpandOffsetX, TopGroupExpandOffsetY)。 增加了ExpandDisabledItems的布尔值属性。 改进了IE7中的元素覆盖运算法则,优化其执行性能。 ComponentArt MultiPage 增加了IE转换效果 (Transition, TransitionDuration属性)。 Web.UI 2007.1 版本没有进行整体框架的改变,只是在Web.UI 2006.2的基础上进行了改进,所以通过最新的ComponentArt.Web.UI.dll可以很方便的对之前的应用程序进行编译。 ComponentArt Web.UI是全球知名的ASP.NET用户界面控件包,它提供了ComponentArt独特的界面呈现技术,支持强大的AJAX技术,可以为您提供最先进的ASP.NET Web用户界面。ComponentArt Web.UI专为ASP.NET框架设计,它包含16个支持AJAX技术的优质用户界面控件,并可应用在ASP.NET 1.0, ASP.NET 2.0, ASP.NET AJAX框架中。 2008年327,专注于ASP.NET Web.UI及Charting控件开发的ComponentArt又发布了Web.UI的最一代版本:2008.1。该版本有四个框架平台:ASP.NET 1.0、ASP.NET 2.0、ASP.NET Ajax,还有当然是最新的.NET框架支持的ASP.NET 3.5了。 2008.1不仅对其代码的运行效率进行了优化,还最增了一个大家期盼已久的成员:Upload。上传空间虽已不是罕见的东东,可是ComponentArt提供的这款不会让你和你的开发团队失望的。 更主要的是ASP.NET 3.5的版本的发布的,同样,特性和功能都具备的同时,也加入了对LINQ的高度支持。这样,ASP.NET 3.5的开发人员也可以享用到这份大餐喽~ Advanced User Interface Control Suite: Includes 19 Premium User Interface controls for development of sophisticated web applications. Built for ASP.NET: Available in four progressively more powerful framework builds: ASP.NET 1.0, ASP.NET 2.0, ASP.NET AJAX and ASP.NET 3.5. Powerful Client-side Rendering Technology: Featuring the most advanced web user interface technology in the industry. Deepest ASP.NET AJAX Integration: The first true controls to fully exploit the most advanced AJAX framework available. Comprehensive Documentation and Support: Featuring complete product documentation online and all-inclusive technical support resources. Enterprise Consulting and Training: Customized consulting and training services are offered to support Enterprise development projects involving larger teams of developers. Flexible Licensing: Available at Developer, Subscription and Enterprise levels. ComponentArt Web.UI 包含以下用户界面控件 Calendar (历) Grid (表格) Rotator (旋转器) TabStrip (标签) CallBack (回调) Menu (菜单) SiteMap (地图) ToolBar (工具条) ComboBox (组合框) MultiPage (分页) Snap (抓取) TreeView (树形列表) Dialog (对话框) NavBar (导航条) Splitter (框架分离) WebChart Lite (图表) 如果涉及到安装序列号,请填写:3JKX6-YJW6X-GJJDP app_data为应用到的Sql和Access数据库文件 documentation下为官方的相关文档 DllCode下为控件的源码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值