国外一款串口通信控件破解(三) 兼谈 .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
}
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,再测试没有发现任何问题
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,再测试没有发现任何问题