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

HelloPort 以及其他的几个例子中 关于设置端口的属性的时候

HelloPort
System.FormatException: Base-64 字符串中的无效字符。
   在 System.Convert.FromBase64String(String s)
   在 xx.2.NS001.c000002.m000001(Int32 p0)
   在 xx.Connections.SerialPortInfo.get_Ports()
   在 xx.2.NS005.c000048.m00000e(Object sender, EventArgs e)
   在 System.Windows.Forms.Form.OnLoad(EventArgs e)

DeviceChat
************** 异常文本 **************
System.FormatException: Base-64 字符串中的无效字符。
   在 System.Convert.FromBase64String(String s)
   在 xx.2.NS001.c000002.m000001(Int32 p0)
   在 ss.Connections.SerialPortInfo.get_Ports()
   在 ss.2.NS005.c000048.m00000e(Object sender, EventArgs e)
   在 System.Windows.Forms.Form.OnLoad(EventArgs e)
点继续后可以出来界面
但是界面显示不正常

再进行分析 以helloport为例
private void cmdProperties_Click(object sender, System.EventArgs e)
    {
      this.serialConnection1.ShowPropertiesDialog();
      this.txtPortName.Text = this.serialConnection1.Options.PortName.ToString();
      this.lblSettings.Text = this.serialConnection1.Options.ToString();
    }




public override DialogResult ShowPropertiesDialog(IWin32Window owner)
{
    c000048 c = new c000048(this);
    return ((owner == null) ? c.ShowDialog() : c.ShowDialog(owner));
}

.method public hidebysig specialname rtspecialname instance void .ctor(class xx.Connections.SerialConnection connection) cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: call instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor()
    L_0006: br.s L_0013
    L_0008: br.s L_0016
    L_000a: br.s L_001d
    L_000c: ldarg.1 
    L_000d: stfld class xx.Connections.SerialConnection xx.2.NS005.c000048::f000011
    L_0012: ret 
    L_0013: ldarg.0 
    L_0014: br.s L_0008
    L_0016: call instance void xx.2.NS005.c000048::m000001()
    L_001b: br.s L_000a
    L_001d: ldarg.0 
    L_001e: br.s L_000c
}

.method public hidebysig specialname static class xx.Connections.SerialPortInfo[] get_Ports() cil managed
{
    .maxstack 14
    .locals init (
        [0] class [mscorlib]Microsoft.Win32.RegistryKey key,
        [1] string[] strArray,
        [2] int32 num,
        [3] string str)
    L_0000: ldsfld class [mscorlib]Microsoft.Win32.RegistryKey [mscorlib]Microsoft.Win32.Registry::LocalMachine
    L_0005: ldc.i4 0x1033c
    L_000a: br.s L_0068
    L_000c: br.s L_006f
    L_000e: br.s L_0076
    L_0010: ldloc.0 
    L_0011: callvirt instance string[] [mscorlib]Microsoft.Win32.RegistryKey::GetValueNames()
    L_0016: stloc.1 
    L_0017: ldloc.1 
    L_0018: ldlen 
    L_0019: conv.i4 
    L_001a: newarr xx.Connections.SerialPortInfo
    L_001f: stsfld class xx.Connections.SerialPortInfo[] xx.Connections.SerialPortInfo::f00000a
    L_0024: ldc.i4.0 
    L_0025: stloc.2 
    L_0026: br.s L_004d
    L_0028: ldloc.0 
    L_0029: ldloc.1 
    L_002a: ldloc.2 
    L_002b: ldelem.ref 
    L_002c: callvirt instance object [mscorlib]Microsoft.Win32.RegistryKey::GetValue(string)
    L_0031: callvirt instance string [mscorlib]System.Object::ToString()
    L_0036: callvirt instance string [mscorlib]System.String::ToUpper()
    L_003b: stloc.3 
    L_003c: ldsfld class xx.Connections.SerialPortInfo[] xx.Connections.SerialPortInfo::f00000a
    L_0041: ldloc.2 
    L_0042: ldloc.3 
    L_0043: newobj instance void xx.Connections.SerialPortInfo::.ctor(string)
    L_0048: stelem.ref 
    L_0049: ldloc.2 
    L_004a: ldc.i4.1 
    L_004b: add 
    L_004c: stloc.2 
    L_004d: ldloc.2 
    L_004e: ldloc.1 
    L_004f: ldlen 
    L_0050: conv.i4 
    L_0051: blt.s L_0028
    L_0053: call void xx.Connections.SerialPortInfo::m000001()
    L_0058: ldsfld class xx.Connections.SerialPortInfo[] xx.Connections.SerialPortInfo::f00000a
    L_005d: call void [mscorlib]System.Array::Sort<class xx.Connections.SerialPortInfo>(!!0[])
    L_0062: ldsfld class xx.Connections.SerialPortInfo[] xx.Connections.SerialPortInfo::f00000a
    L_0067: ret 
    L_0068: call string xx.2.NS001.c000002::m000001(int32)
    L_006d: br.s L_000c
    L_006f: callvirt instance class [mscorlib]Microsoft.Win32.RegistryKey [mscorlib]Microsoft.Win32.RegistryKey::OpenSubKey(string)
    L_0074: br.s L_000e
    L_0076: stloc.0 
    L_0077: br.s L_0010
}

 

m000001函数比较复杂,使用IDA反汇编dll使用流程图方式查看, 

发现 居然是 读取资源文件,然后使用Assembly的 publickey进行运算,狂晕! 

L_0023: ldstr "{3bb6587d-6d4f-422f-8bad-7c2976ba6ac3}"   加载资源 
    L_0028: callvirt instance class [mscorlib]System.IO.Stream [mscorlib]System.Reflection.Assembly::GetManifestResourceStream(string)
    L_002d: stsfld class [mscorlib]System.IO.Stream xx.2.c000002::f000001
    L_0032: ldloc.1 
    L_0033: callvirt instance class [mscorlib]System.Reflection.AssemblyName [mscorlib]System.Reflection.Assembly::GetName()
    L_0038: callvirt instance uint8[] [mscorlib]System.Reflection.AssemblyName::GetPublicKeyToken()
    L_003d: stloc.2

下面是一大堆解密函数..........................................

没办法,因为我对il重新编译的时候使用了自己生成的SNK文件,这里GetPublicKeyToken自然不一样了,
这是导致是数据解密失败的原因。

官方的dll的 publicToken就是 98fd87b7d0f115c7
使用我自己的SNK文件后 publicToken就是  1282414f5ff9b4b1

这个3bb6587d-6d4f-422f-8bad-7c2976ba6ac3资源文件的内容基本上应该不可逆的了
需要的应该是把  L_0038: callvirt instance uint8[] [mscorlib]System.Reflection.AssemblyName::GetPublicKeyToken()替换成自己的函数,它返回的是原始的官方的dll的 publicToken就是 98fd87b7d0f115c7
自己构造函数

.method public hidebysig static uint8[] 
          GetPublicTokenBytes() cil managed
  {
    // 代码大小       63 (0x3f)
    .maxstack  3
    .locals init ([0] uint8[] 'ret',
             [1] uint8[] CS$1$0000)
    IL_0000:  nop
    IL_0001:  ldc.i4.8
    IL_0002:  newarr     [mscorlib]System.Byte
    IL_0007:  stloc.0
    IL_0008:  ldloc.0
    IL_0009:  ldc.i4.0
    IL_000a:  ldc.i4     0x98
    IL_000f:  stelem.i1
    IL_0010:  ldloc.0
    IL_0011:  ldc.i4.1
    IL_0012:  ldc.i4.s   0xfd
    IL_0014:  stelem.i1
    IL_0015:  ldloc.0
    IL_0016:  ldc.i4.2
    IL_0017:  ldc.i4.s   0x87
    IL_0019:  stelem.i1
    IL_001a:  ldloc.0
    IL_001b:  ldc.i4.3
    IL_001c:  ldc.i4     0xb7
    IL_0021:  stelem.i1
    IL_0022:  ldloc.0
    IL_0023:  ldc.i4.4
    IL_0024:  ldc.i4.s   0xd0
    IL_0026:  stelem.i1
    IL_0027:  ldloc.0
    IL_0028:  ldc.i4.5
    IL_0029:  ldc.i4.s   0xf1
    IL_002b:  stelem.i1
    IL_002c:  ldloc.0
    IL_002d:  ldc.i4.6
    IL_002e:  ldc.i4     0x15
    IL_0033:  stelem.i1
    IL_0034:  ldloc.0
    IL_0035:  ldc.i4.7
    IL_0036:  ldc.i4.s   0xc7
    IL_0038:  stelem.i1
    IL_0039:  ldloc.0
    IL_003a:  stloc.1
    IL_003b:  br.s       IL_003d

    IL_003d:  ldloc.1
    IL_003e:  ret
  } // end of method c000002::GetPublicTokenBytes

 

将原来程序读取PublicToken的修改为

L_0023: ldstr "{3bb6587d-6d4f-422f-8bad-7c2976ba6ac3}"
    L_0028: callvirt instance class [mscorlib]System.IO.Stream [mscorlib]System.Reflection.Assembly::GetManifestResourceStream(string)
    L_002d: stsfld class [mscorlib]System.IO.Stream Demo.c000002::f000001
    L_0032: nop  //jetboy ldloc.1 
    L_0033: nop  //jetboy callvirt instance class [mscorlib]System.Reflection.AssemblyName [mscorlib]System.Reflection.Assembly::GetName()
    L_0038: call       uint8[] xx.2.c000002::GetPublicTokenBytes()  // jetboy callvirt instance uint8[] [mscorlib]System.Reflection.AssemblyName::GetPublicKeyToken()
L_003d: stloc.2

重新ilasm组装 il文件,ok,再测试没有发现任何问题
posted @ 2008-08-02 11:44  jetwong  阅读(175)  评论(0编辑  收藏  举报