首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > .NET > C#.NET > .NET程序的序列号控制
【标  题】:.NET程序的序列号控制
【关键字】:.NET
【来  源】:http://blog.joycode.com/juqiang/archive/2007/01/10/91279.aspx

.NET程序的序列号控制

业界对于Java/.NET程序的一个批评就是其安全性。由于IL的特点,各种reflector很容易把代码搞出来。混淆器,貌似一个很常用的功能吧?今天看某个软件,与我们的应用有些类似,所以想借鉴一下。安装好之后,发现有一个License Manager,两个按钮,一个是生成申请信息,一个是导入序列号。(通用的做法,我们的应用也是这么做的)
用reflector打开后,ooh,大概80%的信息都被混淆掉了。field/method的名称,都成了稀奇古怪的文字。还有,我的File Disassembler plug-in居然不能用了,于是只能把所有的method/field信息都paste到notepad上面。(下面所有代码,出于众所周知的原因,我又做了第二次“混淆”,所有的变量/方法名称,都是随意写的)

映入眼帘的第一个method是.ctor,我们知道这个是缺省的构造方法。看代码,如下:

public SomeConstructor()
{
      this.Abcdef123456();
}

上面的方法就是被混淆过了,虽然没意义,但是我们能够“猜测”出来!
进入上面的Abcdef123456方法,如下:

private void Abcdef123456()
{
      this.fedcba654321 = new Container();
      Button button1 = new Button();
      Button button2 = new Button();
      ...
}

好熟悉吧!这就是InitializaComponent方法,查找所有的Abcdef123456,统一替换为这个新名字就可以了。同样的道理,通过看程序运行时候的界面、在查找代码,能更正90%以上的混淆名称,变成一个清晰的表达(虽然不一定和源代码相同)

继续看reflector的结果,有两个分别是Button1_Click和Button2_Click方法。
先看第一个,里面有段代码如下:
byte[] buffer1 = MD5.Encrypt(this.B33498573V + '\v' + this.J39475SDf, false);
stream1.Write(buffer1, 0, buffer1.Length);
byte[] buffer2 = MD5.Encrypt(new UnicodeEncoding().GetBytes(text1));
stream1.Flush();
if (SomeCondition == true)
{
      SaveCPUandDISKInfo(this.B33498573V.Text , this.J39475SDf.Text);
}
InfoShow("\u751f\u6210");

看起来似乎很麻烦?晕,居然还有MD5,还有一些复杂的逻辑判断。怎么搞?分析那个MD5怎么加密的吗?没意义!
首先我们看最后面的InfoShow,我们都知道,这是Unicode编码方式下的文字,简单的用Console.WriteLine出来即可,上面的两个字是“生成”,于是我们猜测,这个和序列号可能相关。很自然的,我们会想到,对于注册的话,会有“成功”或者“失败”。前者转换为unicode是:\u6210\u529f。好吧,我们搜索“\u6210\u529f”。幸运!我们在Button2_Click方法中找到了这个字符串。这个方法代码如下:
if (MD5.CheckRegisterKey(this.FileWillImported.Text)){
    File.Copy();
    ReadRegistry();
    GetCPUandDISKinfoFromDatabase();
    if(ResultFromUpline() == true){
        SetCPUandDISKinfoIntoDatabase();
    }
    InfoShow("\u6210\u529f");
}
else{
    InfoShow("\u975e\u6cd5");
}

我们看到上面的代码,进行了一些复杂的操作,包括什么MD5/SHA/RSA等,最后成功才显示出来一个"\u6210\u529f"。作为游戏,我们继续寻找“失败”的unicode bytes,ooh,没有找到!但是从上面的代码我们可以看出,最后的else是有问题的。同样的Console.WriteLine一下,显示出来的是“非法”这两个汉字。

下面的工作就简单了,ildasm /out方式,把IL弄出来,直接调用SetCPUandDISKinfoIntoDatabase方法,屏蔽掉所有的判断即可。
再用reflector看,该文件并没有任何对于非托管代码的refrence,安装目录下面也没有任何非托管dll,所以基本确定就是这样子了。

总结一下,我们用到的方法,都是20年前的方法。找到关键字符串,查找上下文可疑代码,把相关的判断信息都屏蔽掉,工作就完成了。那些花哨的各种“非对称算法”,没有任何意义。因为在加密解密工作中,流程的转向是重要的,流程本身,是无意义的。这里没有我们10年前看到的那些让人目眩的反侦查手法。

前段时间帮一朋友看过一个.net的应用,用usb key来做的,调用了自己写的Win32 API。同样的弊病,写了非常复杂的加密、解密、反跟踪、反调试处理,可惜的是,这一切都是在Win32中作的,.NET代码只是简单的做了CALL。屏蔽掉了200多行的IL,直接return true,唔,这个世界清净了………………

(再次声明,本文纯属对于.NET简单混淆的一个讨论,文中对于该软件的任何可以识别的特征,都进行了“混淆”)
(对于破解和反汇编,可以看卡巴斯基本人写的那本黑客反汇编揭秘,本人对于汇编纯属文盲)

反过头来,我们考虑本文标题的内容,.NET或者J2EE代码应该如何保护?混淆是必要的,但太脆弱。反跟踪、反调试,我记着有高手在作,但是我不认为这能解决根本问题。不管多复杂的加密手段,被一些低级的代码调用的时候,总能很快的被搞定,如上面分析的那些代码。

 

Web 服务器上慎用杀毒软件:【上一篇】
Apple's new iPhone:【下一篇】
【相关文章】
  • 下载PDF 格式的ASP.NET AJAX 备忘表
  • .NET程序的序列号控制 - 2
  • ZT:ASP.Net与ASP的区别
  • 实际项目开始asp.net2.0 ado.net的编程(1)
  • ASP.NET2.0 连接 SQL SERVER2000 问题
  • ASP.NET定时执行任务
  • ASP.Net2.0 GridView 多列排序,显示排序图标,分页
  • ASP.NET 数据绑定常用代码
  • 合作项目二:“礼物”网---网络项目(拟.NET开发)
  • asp.net2005中,在shtml页面中,通过asp.net页面调用数据库数据~
  • 【随机文章】
  • 详细讲解第三层交换技术
  • 各种排序算法java实现,好文,做个备份
  • 打开新窗口链接的几种办法
  • ASP.NET发送ICQ信息DIY
  • 第一个sqlite3程序
  • 给参加印度NIIT认证兄弟们的一封信!CU的兄弟们加油啊!
  • 供应链铸剑
  • 标程:并查集API
  • WMI 查询
  • 计算机网络知识点总结
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.