您的位置:首页 > 其它

[转] DundasChart 4.0 破解

2006-07-21 15:21 190 查看
DundasChart 企业版4.0 破解手记

现在发现很多人关注Dundas Chart For .NET,顺便研究并将
思路及过程分享如下:

1.工具准备
.net Framework SDK 1.1
ASP.NET环境
ILDASM反编译工具
ilasm重新编译工具

2.安装Dundas Chart For .NET,访问示例程序,发现试用版限制仍然是水印,确定打击目标

3.打开ildasm,载入DundasWebChart.dll文件,如果有Reflector 4.0之类更好,看看程序
架构,初步诊断特性如下:
* 控件使用.net控件License模型控制注册信息
* 所有字符串全部加密

使用"转储",导出IL源代码备用.

4.根据惯例,直接找到Dundas.Charting.WebControl.ChartLicenseProvider,分析CheckKey,IsKeyValid
等方法,由于没有License,可以直接将有关的函数返回值从false改为true,例如
.method family hidebysig newslot virtual
instance bool IsKeyValid(string key,
class [mscorlib]System.Type type) cil managed
{
// 代码大小 151 (0x97)
.maxstack 4
.locals init (string V_0,
class ax V_1,
string[] V_2,
string V_3,
char[] V_4,
string[] V_5,
int32 V_6)
IL_0000: ldarg.1
IL_0001: brfalse IL_0095
IL_0006: ldstr ""
IL_000b: call string aG::a$PST06000FA9(string)
IL_0010: stloc.0
.try
{
IL_0011: newobj instance void ax::.ctor()
IL_0016: stloc.1
IL_0017: ldloc.1
IL_0018: ldarg.1
IL_0019: callvirt instance string ax::b(string)
IL_001e: stloc.0
IL_001f: leave.s IL_0032
} // end .try
catch [mscorlib]System.Object
{
IL_0021: pop
IL_0022: ldstr bytearray (16 00 33 00 39 00 3F 00 34 00 29 00 3F 00 7A 00 // ..3.9.?.4.).?.z.
2A 00 28 00 35 00 3E 00 2F 00 39 00 2E 00 7A 00 // *.(.5.>./.9...z.
31 00 3F 00 23 00 7A 00 33 00 29 00 7A 00 33 00 // 1.?.#.z.3.).z.3.
34 00 2C 00 3B 00 36 00 33 00 3E 00 74 00 7A 00 // 4.,.;.6.3.>.t.z.
19 00 35 00 34 00 2E 00 3B 00 39 00 2E 00 7A 00 // ..5.4...;.9...z.
2E 00 32 00 3F 00 7A 00 39 00 35 00 34 00 2E 00 // ..2.?.z.9.5.4...
28 00 35 00 36 00 7A 00 37 00 3B 00 34 00 2F 00 // (.5.6.z.7.;.4./.
3C 00 3B 00 39 00 2E 00 2F 00 28 00 3F 00 7A 00 // <.;.9.../.(.?.z.
3C 00 35 00 28 00 7A 00 37 00 35 00 28 00 3F 00 // <.5.(.z.7.5.(.?.
7A 00 3E 00 3F 00 2E 00 3B 00 33 00 36 00 29 00 // z.>.?...;.3.6.).
74 00 ) // t.
IL_0027: call string aG::a$PST06000FA9(string)
IL_002c: newobj instance void [mscorlib]System.InvalidOperationException::.ctor(string)
IL_0031: throw
} // end handler
IL_0032: ldloc.0
IL_0033: ldc.i4.1
IL_0034: newarr [mscorlib]System.Char
IL_0039: stloc.s V_4
IL_003b: ldloc.s V_4
IL_003d: ldc.i4.0
IL_003e: ldc.i4.s 44
IL_0040: stelem.i2
IL_0041: ldloc.s V_4
IL_0043: callvirt instance string[] [mscorlib]System.String::Split(char[])
IL_0048: stloc.2
IL_0049: ldloc.2
IL_004a: stloc.s V_5
IL_004c: ldc.i4.0
IL_004d: stloc.s V_6
IL_004f: br.s IL_0064
IL_0051: ldloc.s V_5
IL_0053: ldloc.s V_6
IL_0055: ldelem.ref
IL_0056: stloc.3
IL_0057: ldloc.3
IL_0058: callvirt instance string [mscorlib]System.String::Trim()
IL_005d: pop
IL_005e: ldloc.s V_6
IL_0060: ldc.i4.1
IL_0061: add
IL_0062: stloc.s V_6
IL_0064: ldloc.s V_6
IL_0066: ldloc.s V_5
IL_0068: ldlen
IL_0069: conv.i4
IL_006a: blt.s IL_0051
IL_006c: ldloc.2
IL_006d: ldlen
IL_006e: conv.i4
IL_006f: ldc.i4.2
IL_0070: blt.s IL_0093
IL_0072: ldloc.2
IL_0073: ldc.i4.0
IL_0074: ldelem.ref
IL_0075: ldsfld string Dundas.Charting.WebControl.Chart::b
IL_007a: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_007f: brfalse.s IL_0093
IL_0081: ldloc.2
IL_0082: ldc.i4.1
IL_0083: ldelem.ref
IL_0084: ldarg.0
IL_0085: call instance string Dundas.Charting.WebControl.ChartLicenseProvider::a()
IL_008a: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_008f: brfalse.s IL_0093
IL_0091: ldc.i4.1
IL_0092: ret
IL_0093: ldc.i4.0 <==返回false,改为true
IL_0094: ret
IL_0095: ldc.i4.0 <==返回false,改为true
IL_0096: ret
} // end of method ChartLicenseProvider::IsKeyValid

这样相当于在任何情况下都返回注册码是对的.

修改ldc.i4.0为ldc.i4.1,保存,
去掉组件的public key,在导出的il文件头
.publickey = (00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 // .$..............
00 24 00 00 52 53 41 31 00 04 00 00 01 00 01 00 // .$..RSA1........
43 D9 8F 8A 90 67 EF 3B CD 44 2A DE 2D D4 8C C6 // C....g.;.D*.-...
A6 FA CB CE B1 C4 2D E2 84 7B 0A 46 40 96 C0 2E // ......-..{.F@...
EB F6 FD 87 E3 88 9B EE D3 2B 9A BD 15 25 A1 1A // .........+...%..
28 22 32 CD 4C 46 CC 81 23 F8 CC 08 A1 13 CD 43 // ("2.LF..#......C
54 29 64 62 20 96 9F F4 44 73 48 D1 C2 18 74 67 // T)db ...DsH...tg
08 34 C7 A7 E8 9E A8 95 6F C0 0E 0F 84 FD 3D F6 // .4......o.....=.
FB 3E BF 21 77 44 38 AF 9E 76 04 14 FD E0 6B C2 // .>.!wD8..v....k.
C3 AF 35 FF 3D D8 75 78 63 0E D1 3F E1 2C BD BC ) // ..5.=.uxc..?.,..

保存,然后运行汇编程序编译
ilasm /dll /RESOURCE=DundasWebChart.res DundasWebChart.il
生成的dll控件覆盖到
C:\Program Files\Dundas Software\Charting\WebControl\Samples\bin
目录下面,为了编译看到效果,需要修改DundasChartSamples.dll的引用public key,
类似方法使用ildasm导出DundasChartSamples.dll的il文件,
找到
.assembly extern DundasWebChart
{
//去掉.publickey信息,保证不会出现assemblly引用的版本校验错误
.ver 4:0:0:1652
}
重新使用ilasm汇编生成新的DundasChartSamples.dll
或者可以使用VS.net重新编译测试project,不过我不太喜欢安装这个东东,太大了,还是用
editplus该代码很方便.

很失望,水印依然存在,此路不通!!

5.转向第2种方法,直接找到水印字符串,不就可以很方便的定位水印代码了吗?
由于字符串加密,加密方法来自于
aG.a$PST06000FA9(string A_0){
}
研究发现该加密算法不可逆或者太复杂,转而寻择规律,为了便于研究
写了下面的解密算法il文件,注意到IL文件中的字符串全部是用bytearray表示的,很难处理
-----------------------------------------------------------------------

// Microsoft (R) .NET Framework IL Disassembler. Version 1.1.4322.573
// Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

// PE Header:
// Subsystem: 00000003
// Native entry point address: 0000231e
// Image base: 00400000
// Section alignment: 00002000
// File alignment: 00000200
// Stack reserve size: 00100000
// Stack commit size: 00001000
// Directories: 00000010
// 0 [0 ] address [size] of Export Directory:
// 22d0 [4b ] address [size] of Import Directory:
// 4000 [328 ] address [size] of Resource Directory:
// 0 [0 ] address [size] of Exception Directory:
// 0 [0 ] address [size] of Security Directory:
// 6000 [c ] address [size] of Base Relocation Table:
// 0 [0 ] address [size] of Debug Directory:
// 0 [0 ] address [size] of Architecture Specific:
// 0 [0 ] address [size] of Global Pointer:
// 0 [0 ] address [size] of TLS Directory:
// 0 [0 ] address [size] of Load Config Directory:
// 0 [0 ] address [size] of Bound Import Directory:
// 2000 [8 ] address [size] of Import Address Table:
// 0 [0 ] address [size] of Delay Load IAT:
// 2008 [48 ] address [size] of CLR Header:

// Import Address Table
// mscoree.dll
// 00002000 Import Address Table
// 0000230e Import Name Table
// 0 time date stamp
// 0 Index of first forwarder reference
//
// 0 _CorExeMain

// Delay Load Import Address Table
// 没有数据。
// CLR Header:
// 72 Header Size
// 2 Major Runtime Version
// 0 Minor Runtime Version
// 1 Flags
// 6000001 Entrypoint Token
// 2098 [238 ] address [size] of Metadata Directory:
// 0 [0 ] address [size] of Resources Directory:
// 0 [0 ] address [size] of Strong Name Signature:
// 0 [0 ] address [size] of CodeManager Table:
// 0 [0 ] address [size] of VTableFixups Directory:
// 0 [0 ] address [size] of Export Address Table:
// 0 [0 ] address [size] of Precompile Header:
// Code Manager Table:
// default
// Export Address Table Jumps:
// 没有数据。

.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 1:0:5000:0
}
.assembly crack
{
// --- 下列自定义属性会自动添加,不要取消注释 -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(bool,
// bool) = ( 01 00 00 01 00 00 )
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module crack.exe
// MVID: {8D741680-6BD0-4E43-8D74-C76A766CA6B3}
.imagebase 0x00400000
.subsystem 0x00000003
.file alignment 512
.corflags 0x00000001
// Image base: 0x07650000
//
// ============== CLASS STRUCTURE DECLARATION ==================
//
.class public auto ansi beforefieldinit Crack
extends [mscorlib]System.Object
{
} // end of class Crack

// =============================================================

// =============== GLOBAL FIELDS AND METHODS ===================

// =============================================================

// =============== CLASS MEMBERS DECLARATION ===================
// note that class flags, 'extends' and 'implements' clauses
// are provided here for information only

.class public auto ansi beforefieldinit Crack
extends [mscorlib]System.Object
{
.method private hidebysig static void Main(string[] argv) cil managed
{
.entrypoint
// 代码大小 18 (0x12)
.maxstack 1
.locals init (string V_0) //这下面就是加密的水印字符串了
IL_0000: ldstr bytearray (1E 00 2F 00 34 00 3E 00 3B 00 29 00 7A 00 19 00 // ../.4.>.;.).z...
32 00 3B 00 28 00 2E 00 7A 00 77 00 7A 00 1B 00 // 2.;.(...z.w.z...
09 00 0A 00 74 00 14 00 1F 00 0E 00 7A 00 1F 00 // ....t.......z...
34 00 2E 00 3F 00 28 00 2A 00 28 00 33 00 29 00 // 4...?.(.*.(.3.).
3F 00 7A 00 1F 00 3E 00 33 00 2E 00 33 00 35 00 // ?.z...>.3...3.5.
34 00 57 00 50 00 1F 00 2C 00 3B 00 36 00 2F 00 // 4.W.P...,.;.6./.
3B 00 2E 00 33 00 35 00 34 00 7A 00 17 00 35 00 // ;...3.5.4.z...5.
3E 00 3F 00 7A 00 1F 00 34 00 3B 00 38 00 36 00 // >.?.z...4.;.8.6.
3F 00 3E 00 76 00 7A 00 3C 00 35 00 28 00 7A 00 // ?.>.v.z.<.5.(.z.
2E 00 3F 00 29 00 2E 00 33 00 34 00 3D 00 7A 00 // ..?.)...3.4.=.z.
2A 00 2F 00 28 00 2A 00 35 00 29 00 3F 00 7A 00 // *./.(.*.5.).?.z.
35 00 34 00 36 00 23 00 57 00 50 00 72 00 19 00 // 5.4.6.#.W.P.r...
73 00 7A 00 68 00 6A 00 6A 00 6E 00 7A 00 1E 00 // s.z.h.j.j.n.z...
2F 00 34 00 3E 00 3B 00 29 00 7A 00 09 00 35 00 // /.4.>.;.).z...5.
3C 00 2E 00 2D 00 3B 00 28 00 3F 00 76 00 7A 00 // <...-.;.(.?.v.z.
2D 00 2D 00 2D 00 74 00 3E 00 2F 00 34 00 3E 00 // -.-.-.t.>./.4.>.
3B 00 29 00 74 00 39 00 35 00 37 00 )
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: call string Crack::enc(string)
IL_000c: call void [mscorlib]System.Console::WriteLine(string)
IL_0011: ret
} // end of method Crack::Main

.method private hidebysig static string
enc(string A_0) cil managed
{
// 代码大小 43 (0x2b)
.maxstack 4
.locals init (char[] V_0,
int32 V_1)
IL_0000: ldarg.0
IL_0001: call instance char[] [mscorlib]System.String::ToCharArray()
IL_0006: dup
IL_0007: stloc.0
IL_0008: ldlen
IL_0009: conv.i4
IL_000a: stloc.1
IL_000b: ldloc.1
IL_000c: dup
IL_000d: ldc.i4.m1
IL_000e: add
IL_000f: stloc.1
IL_0010: ldc.i4.0
IL_0011: ble.s IL_001f
IL_0013: ldloc.0
IL_0014: ldloc.1
IL_0015: ldloc.0
IL_0016: ldloc.1
IL_0017: ldelem.u2
IL_0018: ldc.i4.s 90
IL_001a: xor
IL_001b: conv.u2
IL_001c: stelem.i2
IL_001d: br.s IL_000b
IL_001f: ldloc.0
IL_0020: newobj instance void [mscorlib]System.String::.ctor(char[])
IL_0025: call string [mscorlib]System.String::Intern(string)
IL_002a: ret
} // end of method aG::a

.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// 代码大小 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Crack::.ctor

} // end of class Crack

// =============================================================

//*********** 反汇编完成 ***********************
// WARNING: Created Win32 resource file C:\Program Files\Dundas Software\Charting\WebControl\bin\crack\crack.res
-----------------------------------------------------------------------

运行ilasm crack.il就可以调试解密结果了,在这个工具的帮助下,研究发现
加密串和明文是一一对应的,例如
1E 00 2F 00 34 00 3E 00 3B 00 29 00 74 00 解密= Dundas.

从水印中关键字是"Evaluation",多次尝试,发现加密文就是

1F 00 2C 00 3B 00 36 00 2F 00 => Evalu

在导出的IL文件中查找,只发现一个,直接定位到
Dundas.Charting.WebControl.ChartPicture
public void Paint(Graphics graph, bool cursorsOnly, RenderingType renderingType, XmlTextWriter svgTextWriter, Stream flashStream, string documentTitle, bool resizable, bool preserveAspectRatio);
方法,现在工作完成98%了,研究以下代码,发现处理水印的程序是这样写的
bool ifTrial=true;
if(ifTrial){
//显示水印代码程序处理
}
原来无论license判断结果如何,都会显示水印!难怪上面方法不可行
太容易了,找到bool ifTrial=true;

IL_0a7d: ldc.i4.0
IL_0a7e: stfld bool Dundas.Charting.WebControl.ChartPicture::c
修改为
IL_0a7d: ldc.i4.1
IL_0a7e: stfld bool Dundas.Charting.WebControl.ChartPicture::c
保存,重新编译

ilasm /dll /RESOURCE=DundasWebChart.res DundasWebChart.il

覆盖到C:\Program Files\Dundas Software\Charting\WebControl\Samples\bin目录,
效果太明显了,水印没有了

原来所谓....的过程就是这样的,没有你想象中的那么难吧!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: