选择显示字体大小

urtracker 2.11版 license验证原理剖析

注    :原创,转载请注明出处。
作 者:草惜草
首 发: http://kokey.blogchina.com

序言:

   看了henryouly的文章以后深受启发,决定对urtracker最新的版本来个剖析。在此,特别感谢henryouly!

×××××××××××××××××××××××××××××××××××××××××××××
urtracker事务跟踪系统是一款功能强大而且易于使用的web方式的协同工作软件 。它用于帮助公司和团队跟踪工作中的问题,管理和记录这些问题的处理过程。
urtracker向您的团队提供了一个全功能的,高度可定制的软件工具用于报告和跟踪问题、需求、缺陷(bug)或者任务等事务。它拥有丰富的自定义字段、基于项目和角色的权限控制、简化的工作流、友好的用户界面,以及更多的其他特性。我们非常确信您将会喜欢上urtracker,因为我们相信她正是您所需要的。
 ××××××××××××××××××××××××××××××××××××××××××××
 工具介绍:
 
   要研究.net当然离不开reflector for .net 。(reflector is a class browser for .net components. it supports assembly and namespace views, type and member search, xml documentation, call and callee graphs, il, visual basic, delphi and c# decompiler, dependency trees, base type and derived type hierarchies and resource viewers. )
   如果想把代码保存下来,那就需要reflector的插件reflector.filedisassembler了。(the reflector.filedisassembler is a little add-in for the new version of lutz roeder's .net reflector that you can use to dump the decompiler output to files of any reflector supported language (c#, vb.net, delphi). this is extremely useful if you are searching for a specific line of code as you can use vs.net's "find in files" or want to convert a class from one language to another.

  下载地址:reflector for .net   http://www.aisto.com/roeder/do.net/
                      reflector.filedisassembler    http://www.denisbauer.com.nettools/filedisassembler.aspx
 
 正文:

严重声明:本文只作科研和学习用途。如果由本文产生的法律纠纷,一概与本人无关。

好了,了解了reflector咱们就可以动手研究urtracker了。

当然首先用reflector分析bin文件夹下的文件,一共有12个dll文件,从他们的名称你也可以猜出个八八九九,反正你不怕麻烦你就挨个用reflector试好了...^_^
最后找到了webtracker.dll 可疑,因为在reflector按f3,你可以搜索到很多关于license的东东。哈哈,探究之路开始了。
首先看看lealsoft.urtracker.bll下有个serverlicenseprovider类。

public class serverlicenseprovider : licenseprovider
{
      // methods
      static serverlicenseprovider();
      public serverlicenseprovider();
      protected virtual serverlicense createemptylicense(type type);
      protected virtual serverlicense createlicense(type type, string key);
      public override license getlicense(licensecontext context, type type, object instance, bool allowexceptions);
      protected virtual string getlicensedata(type type);
      protected virtual stream getlicensedatastream(type type);
      protected virtual bool validatelicense(serverlicense license, out string errormessage);
      protected virtual bool validatelicensedata(type type, string licensedata);

      // fields
      private static readonly serverlicensecollector licensecollector;

      // nested types
      private sealed class serverlicensecollector
      {
            // methods
            public serverlicensecollector();
            public void addlicense(type objecttype, serverlicense license);
            public serverlicense getlicense(type objecttype);
            public void removelicense(type objecttype);

            // fields
            private idictionary _collectedlicenses;
      }
}
 
看到没,有几个createlicense,getlicense,validatelicense ,validatelicensedata,getlicensedatastream这几个方法。好,打开看看都是什么东东。

protected virtual serverlicense createlicense(type type, string key)
{
      char[] charray1 = new char[1] { ':' } ;
      string[] textarray1 = key.split(charray1);
      return new urtrackerlicense(type, key, long.parse(textarray1[1], cultureinfo.invariantculture), long.parse(textarray1[2], cultureinfo.invariantculture), textarray1[3], long.parse(textarray1[4], cultureinfo.invariantculture), long.parse(textarray1[5], cultureinfo.invariantculture), textarray1[6]);
}
 
哇!就是新建license,urtrackerlicense后面有几个参数,什么也看不出,感觉是要用":"split开一个字符串。来,打开urtrackerlicense构造函数看看。
public urtrackerlicense(type type, string key, long startticks, long ticks, string username, long userindex, long clientcount, string mac) : base(type, key)
{
      this._foundmac = false;
      this._ticks = ticks;
      this._startticks = startticks;
      this._username = username;
      this._userindex = userindex;
      this._clientcount = clientcount;
      this._mac = mac;
      this._macarray = urtrackerlicense.getmacarray();
      this._foundmac = this._macarray.indexof(this._mac) > -1;
}
 
哦,看到ticks,startticks,username,userindex,clientcount,mac
难道这些就是所需参数"到期时间,使用开始时间,用户名,用户名索引,用户数,本机网卡地址"
有点意思了。呵呵。
找到了 urtrackerlicense 类,你就会知道我们猜测的没有错了。
public class urtrackerlicense : serverlicense
{
      // methods
      public urtrackerlicense(type type, string key, long startticks, long ticks, string username, long userindex, long clientcount, string mac);
      public static arraylist getmacarray();

      // properties
      public long clientcount { get; }
      public bool isexpired { get; }
      public string mac { get; }
      public long startticks { get; }
      public long ticks { get; }
      public long userindex { get; }
      public string username { get; }

      // fields
      private long _clientcount;
      private bool _foundmac;
      private string _mac;
      private arraylist _macarray;
      private long _startticks;
      private long _ticks;
      private long _userindex;
      private string _username;
}
 
继续,刚才找了createlicense,现在开始找validatelicensedata。
protected virtual bool validatelicensedata(type type, string licensedata)
{
      bool flag1 = false;
      char[] charray1 = new char[1] { ':' } ;
      string[] textarray1 = licensedata.split(charray1);
      if (textarray1.length == 7)
      {
            return (string.compare("urtracker1licensed", textarray1[0], true, cultureinfo.invariantculture) == 0);
      }
      return flag1;
}
 
哈哈,就是说刚才分析那个数组中textarray1[0],必须是urtracker1licensed!哈哈,这也进一步证实了我们要把注册信息字符串用":"分开的设想。
come on!离成功越来越近了!接着分析validatelicense。
protected virtual bool validatelicense(serverlicense license, out string errormessage)
{
      errormessage = null;
      urtrackerlicense license1 = (urtrackerlicense) license;
      if (license1.isexpired)
      {
            errormessage = "the license has expired.";
            return false;
      }
      return true;
}
 
哦,知道了!原来是判断urtrackerlicense的属性isexpired的真假!好,咱们看看属性isexpired。
public bool isexpired
{
      get
      {
            if ((datetime.today.ticks <= this._ticks) && (datetime.now.ticks >= this._startticks))
            {
                  return !this._foundmac;
            }
            return true;
      }
}
 
 知道了吧!就是判断当前时间要在ticks和startticks之间!然后再判断mac的值。
 现在查找mac的相关类或者方法。找到了getmacarray
 public static arraylist getmacarray()
{
      managementclass class1 = new managementclass("win32.networkadapterconfiguration");
      managementobjectcollection collection1 = class1.getinstances();
      arraylist list1 = new arraylist();
      using (managementobjectcollection.managementobjectenumerator enumerator1 = collection1.getenumerator())
      {
            while (enumerator1.movenext())
            {
                  managementobject obj1 = enumerator1.get_current();
                  if ((bool) obj1.get_item("ipenabled"))
                  {
                        list1.add(obj1.get_item("macaddress").tostring().replace(":", "").toupper());
                  }
                  obj1.dispose();
            }
      }
      return list1;
}

本新闻共2


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons