自已编写Resharper v1.0注册机的流水帐(2) -- 分析算法、痛苦

本人写这个,仅供学习和研究之用,也算是自己的一个心得,注册后的插件,自己在家玩玩可以,但最好别拿去开发产品,更不要用于商业用途,JBuilder的教训是深刻的,作为公司觉得好还是去买正版吧,这点钱对公司来说还不算贵。如出现版权问题,本人概不负责。

自已编写Resharper v1.0注册机的流水帐(1) -- 上阵、分析、碰壁

四、注册机

       做注册机,就得搞清别人的算法,算法估计都在LicenseChecker类里面,现在看他的代码吧。。

       首先是构造函数:
   

public LicenseChecker(string publickey, string username, string company, string license)
{
    
// 搞定public key
      this.N = new BigInteger(publickey, 10);
      
this._username = username;
      
this._company = company;
      
try
      
{
        
// _code 就是最终的明文Lincense
            this._code = new BigInteger(Convert.FromBase64String(license));
      }

      
catch (FormatException)
      
{
            
this._code = LicenseChecker._zero;
            
return;
      }

    
// 将username转换为Biginteger,并与1进行位或运算
      byte[] buffer1 = LicenseChecker.GetBytesFromString(username);
      BigInteger integer1 
= new BigInteger(buffer1);
      integer1 
= BigInteger.op_BitwiseOr(integer1, BigInteger.op_Implicit(((int1)));

    
// 解码
      this._code = this._code.modPow(integer1, this.N);
}


唉,代码还是太。。。看来Reflector还要改进。不过看懂还是没有问题的,

1. 取得PublicKey,并将其以十进制转换为BigInteger类型

       2. License解码,并转换为BigInteger类型.

       3. username也转换为BigInteger类型,并与1做位或运算,实际上它就是真正的公钥。

       4. usernameBigIntegerpublicKeyBigIntegerLicense做模&&幂运算。

      

看到这里,我算是看懂了,又是BigInteger,又是publicKey,又是modPow运算,再明显不过了,这就是RSA算法嘛!!!太好玩了,兄弟们赶快去找公式,这个算法俺后面就不具体说了的。

       其中BigInteger类是算法的重点,C#中没有现成的类型,用Resharper自带的吧,But由于重载了很多运算符,resharper反编译出来的代码几乎不可读,咋办?

       俺想起了,JDK。。。在JDK 1.4BigInteger是标准库中的,JDK又是开源的,拿过来抄抄嘛:)

       但是一打开JDKBigInteger源代码,天,那么多,还继承至一个Number,而且Java是不支持运算符重载的:(算了,俺很懒,还是网上找找有没有现成的吧。

       Google就是牛,一下子就找到了,还是C#的。。。

       http://www.codeproject.com/csharp/BigInteger.asp

       直接拿过来用吧:)

 

       回头再看,在LicenseChecker构造函数中实际上就是已经把License解码成为“明文”了,并保存在_code字段中了,这个_code代表的“明文”里面又有一些什么信息呢?接着看。

       首先来看IsChecksumOK的源代码

public bool IsChecksumOK
{
      
get
      
{
            
if (this._code != LicenseChecker._zero)
            
{
                  
return (((this._code.IntValue() & 65535% 65521== this.UserHash());
            }

            
return false;
      }

}


这段代码不用多解释,但是很重要,_code65535进行位与运算,并被65521除余UserHash的值,这个UserHash在反编译的代码写的很清楚,虽然反编译的不咋的,但是改一改就可以直接拿来用了。

       这段代码虽少,但是却是算法的关健,实际上就告诉你了,“明文”是啥样子的。

       还有一个重要的属性是ExpirationDate,他的源代码如下:

public DateTime ExpirationDate
{
      
get
      
{
            DateTime time1;
        
// 以下两句是关健
            int num1 = (BigInteger.op_RightShift(this._code, 56).IntValue() & 65535);
            
if (num1 == 65535)
            
{
                  
return DateTime.MaxValue;
            }

            
try
            
{
                  time1 
= new DateTime((2003 + (num1 & 127)), ((num1 >> 7& 15), (num1 >> 11));
                  
return time1;
            }

            
catch (Exception)
            
{
                  
return DateTime.MinValue;
            }

            
return time1;
      }

}


这代码太有意思了,看了前两行就不用看了,实际上就是判断(_code >> 56 & 65535) = 65535,等于则返回最大的DateTime,这就是我们要的,我们就是要个无限大的注册时间嘛:)至于后面的带时间的注册信息,看都别看了。。哈哈。

       另外还有几个属性的源代码也是要看一下的,不过,我后面写了一个Check程序验证了几个试用版的号码,发现TypeVersion的值永远为0,所以像TypeVersion这些属性应当是为以后版本准备的,本版本不重要,所以我这里就不多说了。

       “明文”知道了,“密文”又是什么呢?呵呵,这还不简单,License就是加密后的密文嘛:)

       搞到这里,突然想起来CheckerLicener参数中的PublicKey是哪来的还不知道,往上找,找到EnterLicenseForm,发现没有,它自已倒还有一个SetPublic方法,看来,这个PublicKey还是从外面传进来的。

到底是从哪里传来的呢?俺不知道,唉,不了解Vs.net插件是怎么运行的嘛。。。

不过,事到如此,不了解也不行了,马上上网找了几篇讲Vs.net编写插件的文章,一边看一边用,最后又来分析Resharper的结构,花了一个上午,总算是在JetBrains.Resharper.Services.dllJetBrains.Resharper.Shell.Impl命名空间中的LicenseData类找到了它的身影。(唉,这么大一个LicenseData类,我以前怎么就没有看到:()

反编译,PublicKey就这样呈现在我们的面前

public static string PublicKey
{
      
get
      
{
            
return "3439664563558343388897268028516178220150974083190422162869";
      }

}

OKPublicKey知道了,就要来找PrivateKey了。

回来看看RSA算法,我发现CheckLicense中的modPow运算是把PublicKeyN用的,而将Username做为公钥使用的。

          // Iteger1username | 1的结果,NpublicKeybigint
          this._code = this._code.modPow(integer1, this.N);

       这就意味着,这个publickey,就是两个素数的积(即p * q),只要我算出这两个素数,就可以知道z(即(p-1) * (q-1)),从而就可以知道真正的密钥d了。

       但是MyGod,这个publicKey足有60位啊!!!估计pq的取值也在1*1029次方至1*1030次方之间,俺穷人的机器只有AMD 号称的XP 1700+啊。你要让我算多久啊。。。。

神啊救救我吧。。


自已编写Resharper v1.0注册机的流水帐(3) -- 大功告成:) 

posted on 2004-08-12 09:55  飞刀  阅读(6643)  评论(10编辑  收藏  举报

导航