国外一款串口通信控件破解(二) 兼谈 .net Attribute原理

4、测试
运行例子程序,基本代码如下
Pdf417 pdf = new Pdf417();
        pdf.Render(text.ToString(), g, rect);
发现
http://bbs.pediy.com/attachment.php?attachmentid=13236&stc=1&d=1208153975

查看混淆过后的dll,使用reflector查看
[LicenseProvider(typeof( . ))] //!!!type后面的类型,是混淆前的类型,混淆后这个类型被改名字了,自然是加载不到此类,运行失败了
public class Pdf417 : MarshalByRefObject, IDisposable
使用Editplus查看 反编译后的 IL代码,查找LicenseProviderAttribute 定位代码的位置

.custom instance void [System]System.ComponentModel.LicenseProviderAttribute::.ctor(class [mscorlib]System.Type) = ( 01 00 03 06 2E 06 )   

查看带有LicenseProviderAttribute的没有混淆的dll反编译后IL代码生成规则

Reflector下看
LicenseProvider(typeof(LicFileLicenseProvider)
public class xxx : DataBoundControl, ICallbackEventHandler, IPostBackEventHandler
IL代码,可以看到其实就是完整类名的ascii码。
.custom instance void [System]System.ComponentModel.LicenseProviderAttribute::.ctor(class [mscorlib]System.Type) = (
 01 00 77 53 79 73 74 65 6D 2E 43 6F 6D 70 6F 6E   // ..wSystem.Compon
65 6E 74 4D 6F 64 65 6C 2E 4C 69 63 46 69 6C 65   // entModel.LicFile
4C 69 63 65 6E 73 65 50 72 6F 76 69 64 65 72 2C   // LicenseProvider,
20 53 79 73 74 65 6D 2C 20 56 65 72 73 69 6F 6E   //  System, Version
3D 32 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72   // =2.0.0.0, Cultur
 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69   // e=neutral, Publi
 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 63   // cKeyToken=b77a5c
35 36 31 39 33 34 65 30 38 39 00 00 )             // 561934e089..

可见IL 十六进制代码 一大串,其实表示的就是某个类的完整名字。

这么看来,[LicenseProvider(typeof( . ))] 后面的 typeof 需要换成 xx.2.dll 自己的相关类的名字

查看混淆后的xx.2.dll,找到混淆后的用户license验证的类的名字

查找名称混淆后的.class private auto ansi beforefieldinit xx.2.NS006'.c000055
       extends [System]System.ComponentModel.LicenseProvider
{
  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [System]System.ComponentModel.LicenseProvider::.ctor()
    IL_0006:  ret
  } // end of method c000055::.ctor

说明此处的类名是xx.2.NS006.c000055 ,经这个类名完全转换成16进制表示的。
78 78 2e 32 2e 4e 53 30 30 36 2e 63 30 30 30 30 35 35

将.custom instance void [System]System.ComponentModel.LicenseProviderAttribute::.ctor(class [mscorlib]System.Type) = ( 01 00 03 06 2E 06 )   
替换为
.custom instance void [System]System.ComponentModel.LicenseProviderAttribute::.ctor(class [mscorlib]System.Type) = (01 00 12 78 78 2e 32 2e 4e 53 30 30 36 2e 63 30 30 30 30 35 35 00 00)   
注意 替换格式,前面加01 00 表示开始,最后一个00 00 表示结束,同时,01 00 后面跟着一个字符长度12(十进制18)
替换了五处,分别对应了五个组件。

这么修改后,不再出现上述错误提示。
继续测试组件,基本正常,但是出现了错误

 

http://bbs.pediy.com/attachment.php?attachmentid=13237&stc=1&d=1208153975

看来已经正常运行,是其他的问题导致的

System.TypeInitializationException: “xx.2.NS006.c000052”的类型初始值设定项引发异常。 ---> System.FormatException: Base-64 字符串中的无效字符。
   在 System.Convert.FromBase64String(String s)
   在 xx.2.NS001.c000002.m000001(Int32 p0)
   在 xx.2.NS006.c000052..cctor()
   --- 内部异常堆栈跟踪的结尾 ---
   在 xx.2.NS006.c000052.m000002()
   在 xx.2.NS006.c000055.GetLicense(LicenseContext context, Type type, Object instance, Boolean allowExceptions)
   在 System.ComponentModel.LicenseManager.ValidateInternalRecursive(LicenseContext context, Type type, Object instance, Boolean allowExceptions, License& license, String& licenseKey)
   在 System.ComponentModel.LicenseManager.ValidateInternal(Type type, Object instance, Boolean allowExceptions, License& license)
   在 System.ComponentModel.LicenseManager.Validate(Type type, Object instance)
   在 xx.Barcodes.Pdf417..ctor()

看来是读取license出错的,把这部分去掉就行了

找到xx.2.NS006.c000055.GetLicense(LicenseContext context, Type type, Object instance, Boolean allowExceptions)

只要让他直接返回 license就可以了
经过分析

  L_0056: newobj instance void  xx.2.NS006.c000054::.ctor()
    L_005b: stloc.s license
    L_005d: leave L_01ba
    L_0062: ldarg.1 
    L_0063: ldarg.2 
    L_0064: ldloc.0 
    L_0065: callvirt instance void [System]System.ComponentModel.LicenseContext::SetSavedLicenseKey(class [mscorlib]System.Type, string)
    L_006a: newobj instance void  xx.2.NS006.c000053::.ctor()
    L_006f: stloc.s license

经过分系 xx.2.NS006.c000054: 
 xx.2.NS006.c000053: 两个类一样
将GetLicense 函数此部分IL修改为 
 
.method public hidebysig virtual instance class [System]System.ComponentModel.License 
          GetLicense(class [System]System.ComponentModel.LicenseContext context,
                     class [mscorlib]System.Type 'type',
                     object 'instance',
                     bool allowExceptions) cil managed
  {
    // Code size       451 (0x1c3)
    .maxstack  48
    .locals init (string V_0,
             string V_1,
             string V_2,
             class [System]System.ComponentModel.LicenseException V_3,
             class [System]System.ComponentModel.License V_4,
             valuetype xx.2.NS006'.enum000051 V_5,
             valuetype xx.2.NS006'.enum000051 V_6)
      IL_0001:  newobj     instance void xx.2.NS006'.c000054::.ctor()
      IL_0002:  stloc.s    V_4
    IL_0003:  ldloc.s    V_4
    IL_0004:  ret
  } // end of method c000055::GetLicense

出现了新的异常
System.FormatException: Base-64 字符串中的无效字符。
   在 System.Convert.FromBase64String(String s)
   在 xx.2.NS001.c000002.m000001(Int32 p0)
   在 xx.2.NS006.c000054.get_LicenseKey()
   在 System.ComponentModel.LicenseManager.ValidateInternalRecursive(LicenseContext context, Type type, Object instance, Boolean allowExceptions, License& license, String& licenseKey)
   在 System.ComponentModel.LicenseManager.ValidateInternal(Type type, Object instance, Boolean allowExceptions, License& license)
   在 System.ComponentModel.LicenseManager.Validate(Type type, Object instance)
   在 xx.Barcodes.Pdf417..ctor()

找到  c000054
.method public hidebysig specialname virtual instance string get_LicenseKey() cil managed
{
    .maxstack 8
    L_0000: ldc.i4 0x1079e
    L_0005: br.s L_0008
    L_0007: ret 
    L_0008: br.s L_000c
    L_000a: br.s L_0007
    L_000c: br.s L_0010
    L_000e: br.s L_000a
    L_0010: call string xx.2.NS001.c000002::m000001(int32)
    L_0015: br.s L_000e
}

修改IL代码为
 .maxstack 8
    .locals init (
        [0] string CS$1$0000)
    L_0000: nop 
    L_0001: ldstr "Jetboy"
    L_0006: stloc.0 
    L_0007: br.s L_0009
    L_0009: ldloc.0 
    L_000a: ret

 

同时 C0053也有一个
.method public hidebysig specialname virtual instance string get_LicenseKey() cil managed
{
    .maxstack 6
    .locals init (
        [0] object obj2)
    L_0000: br.s L_0018
    L_0002: ldc.i4 0x10828
    L_0007: br.s L_001f
    L_0009: br.s L_0026
    L_000b: stloc.0 
    L_000c: ldloc.0 
    L_000d: brfalse.s L_0016
    L_000f: ldloc.0 
    L_0010: callvirt instance string [mscorlib]System.Object::ToString()
    L_0015: ret 
    L_0016: ldnull 
    L_0017: ret 
    L_0018: call class [mscorlib]Microsoft.Win32.RegistryKey xx.2.NS006.c000052::m000001()
    L_001d: br.s L_0002
    L_001f: call string xx.2.NS001.c000002::m000001(int32)
    L_0024: br.s L_0009
    L_0026: callvirt instance object [mscorlib]Microsoft.Win32.RegistryKey::GetValue(string)
    L_002b: br.s L_000b
}

修改为

修改为
  .maxstack 8
    .locals init (
        [0] string CS$1$0000)
    L_0000: nop 
    L_0001: ldstr "Jetboy"
    L_0006: stloc.0 
    L_0007: br.s L_0009
    L_0009: ldloc.0 
    L_000a: ret 

直接全部返回jetboy 字符串。

至此,条形码的程序搞定,可以运行,运行的条形码显示和 试用版本的一致
继续运行其他的例子程序,又发现新问题
posted @ 2008-08-02 11:43  jetwong  阅读(328)  评论(0编辑  收藏  举报