您的位置:首页 > 其它

dundas chart for webform 破解手记

2006-01-18 21:48 351 查看
破解的方法和步骤:

1) 利用 Reflector ( http://www.aisto.com/roeder/dotnet/) 观察;

2) 通过观察,很快发现一个特点,
a)所有字串信息都不是采用类似"dundas" 这样常规字符串形式存放,而是采用byte数组方式存放的;
b) 在输出信息前都调用了bu::a( )这个函数;

3) 仍然利用 Reflector ,很方便地就找到了bu::a( )。但是在反汇编这个函数的时候 Reflector 报错! 原因是这个函数被混淆处理过了所以Reflector 无法处理;

4) 利用 ildasm ,反汇编出 bu.a( ), 一堆让人晕头转向的中间语言代码!耐着性子看了几遍,大致明白这个函数功能:将一个byte数组转换成字符串。其中的指令暴露的玄机,如下所示:
……
IL_0022: ldc.i4 0x1469
IL_0027: sub
……
注意红色部分两句代码的含义是执行减法操作,减去0x1469。

5) 为了验证分析,构造一个简单的 IL 程序如下( 绝大部分代码是从 ildasm 窗口中直接复制出来的 )

——————————————————————————————————————————————
.assembly extern mscorlib {}

.assembly byref
{
.ver 1:0:0:0
}
.module byref.exe

.method static void main() cil managed
{
.entrypoint

// 以下数据从 DundasWebChart.dll 的 ildasm 窗口中复制出来的!
IL_0988: ldstr bytearray (AD 14 DE 14 D7 14 CD 14 CA 14 DC 14 89 14 AC 14
D1 14 CA 14 DB 14 DD 14 89 14 96 14 89 14 C0 14
D2 14 D7 14 CD 14 D8 14 E0 14 DC 14 89 14 AF 14
D8 14 DB 14 D6 14 DC 14 89 14 AE 14 D7 14 DD 14
CE 14 DB 14 D9 14 DB 14 D2 14 DC 14 CE 14 89 14
AE 14 CD 14 D2 14 DD 14 D2 14 D8 14 D7 14 76 14 // ..............v.
73 14 AE 14 DF 14 CA 14 D5 14 DE 14 CA 14 DD 14 // s...............
D2 14 D8 14 D7 14 89 14 B6 14 D8 14 CD 14 CE 14
89 14 AE 14 D7 14 CA 14 CB 14 D5 14 CE 14 CD 14
95 14 89 14 CF 14 D8 14 DB 14 89 14 DD 14 CE 14
DC 14 DD 14 D2 14 D7 14 D0 14 89 14 D9 14 DE 14
DB 14 D9 14 D8 14 DC 14 CE 14 DC 14 89 14 D8 14
D7 14 D5 14 E2 14 76 14 73 14 91 14 AC 14 92 14 // ......v.s.......
89 14 9B 14 99 14 99 14 9E 14 89 14 AD 14 DE 14
D7 14 CD 14 CA 14 DC 14 89 14 BC 14 D8 14 CF 14
DD 14 E0 14 CA 14 DB 14 CE 14 95 14 89 14 E0 14
E0 14 E0 14 97 14 CD 14 DE 14 D7 14 CD 14 CA 14
DC 14 97 14 CC 14 D8 14 D6 14 )
call string x(string)

call void [mscorlib]System.Console::Write(string)

ret
}

// 以下函数体代码就是bu::a, 为了适应这个验证程序,把函数声明换了。
//
// 顺便,可以看看这个函数是如何利用转跳类指令进行混淆的。
//
.method public static string x(string A_0) cil managed
{
// 代码大小 46 (0x2e)
.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: dup
IL_0009: ldlen
IL_000a: conv.i4
IL_000b: dup
IL_000c: ldc.i4.0
IL_000d: bgt.s IL_001b

IL_000f: pop
IL_0010: newobj instance void [mscorlib]System.String::.ctor(char[])
IL_0015: call string [mscorlib]System.String::Intern(string)
IL_001a: ret

IL_001b: ldc.i4.m1
IL_001c: add
IL_001d: dup
IL_001e: stloc.1
IL_001f: ldloc.0
IL_0020: ldloc.1
IL_0021: ldelem.u2
IL_0022: ldc.i4 0x1469
IL_0027: sub
IL_0028: conv.u2
IL_0029: stelem.i2
IL_002a: ldloc.0
IL_002b: ldloc.1
IL_002c: br.s IL_000b
}
——————————————————————————————————————————————

汇编这个程序并运行,结果如下:

Dundas Chart - Windows Forms Enterprise Edition
Evaluation Mode Enabled, for testing purposes only
(C) 2005 Dundas Software, www.dundas.com

原来Dundas 对信息加密的方法和解密的方法是这样简单! 例如 0x14D1 - 0x1469 = 0x68 ,再将0x68作为 BCD 码,即十进制值为 68 。正好是 ASCII 码中 ‘D’的码值!

6)下来就好办了,找那个水印!很容易就定位到DundasWebChart -> Dundas.Charting.WebContrl -> ChartPicture::Paint( …) ,这与网上很多分析吻合!

7)接着利用 Refelctor 直接分析ChartPicture::Paint这个函数(如果能用Refelctor 就用它好了,毕竟,Refeletor 可以转换成C#, VB这样高级语言,分析起来方便得多!)。分析这个函数不难。注意其中得代码,非常有趣!如下所示:

finally
{
this.OnAfterPaint(new ChartPaintEventArgs(this.a, this.a, new ElementPosition(0f, 0f, 100f, 100f)));
foreach (ChartArea area9 in this.a)
{
area9.a();
area9.d();
}
// 注意这里!只有把 this.e = true 改成 this.e = false 就不会输出水印了!
this.e = true;
if (this.e)
{
StringFormat format1 = new StringFormat();
format1.Alignment = StringAlignment.Center;
format1.LineAlignment = StringAlignment.Center;
SolidBrush brush1 = new SolidBrush(Color.FromArgb(40, 0, 0, 0xaf));
SolidBrush brush2 = new SolidBrush(Color.FromArgb(40, 200, 200, 200));
Font font1 = new Font(ChartPicture.a(), 8f);
SizeF ef3 = this.a.GetRelativeSize(new SizeF(2f, 2f));
// 水印字符串
string text1 = bu.a("\u14ad\u14de\u14d7\u14cd\u14ca\u14dc\u1489\u14ac\u14d1\u14ca\u14db\u14dd\u1489\u1496\u1489\u14aa\u14bc\u14b9\u1497\u14b7\u14ae\u14bd\u1489\u14ae\u14d7\u14dd\u14ce\u14db\u14d9\u14db\u14d2\u14dc\u14ce\u1489\u14ae\u14cd\u14d2\u14dd\u14d2\u14d8\u14d7\u1476\u1473\u14ae\u14df\u14ca\u14d5\u14de\u14ca\u14dd\u14d2\u14d8\u14d7\u1489\u14b6\u14d8\u14cd\u14ce\u1489\u14ae\u14d7\u14ca\u14cb\u14d5\u14ce\u14cd\u1495\u1489\u14cf\u14d8\u14db\u1489\u14dd\u14ce\u14dc\u14dd\u14d2\u14d7\u14d0\u1489\u14d9\u14de\u14db\u14d9\u14d8\u14dc\u14ce\u14dc\u1489\u14d8\u14d7\u14d5\u14e2\u1476\u1473\u1491\u14ac\u1492\u1489\u149b\u1499\u1499\u149e\u1489\u14ad\u14de\u14d7\u14cd\u14ca\u14dc\u1489\u14bc\u14d8\u14cf\u14dd\u14e0\u14ca\u14db\u14ce\u1495\u1489\u14e0\u14e0\u14e0\u1497\u14cd\u14de\u14d7\u14cd\u14ca\u14dc\u1497\u14cc\u14d8\u14d6");
this.a.a(text1, font1, brush2, new RectangleF(0f, 0f, 100f, 100f), format1);
this.a.a(text1, font1, brush1, new RectangleF(0f, 0f, 100f - ef3.Width, 100f - ef3.Height), format1);
}

8)再往下就是常规套路了:去除public key , 改代码,重新汇编……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: