RSS 2.0 Feed
2007-01 Entries

郁闷之极,好像用VB写一个空OCX放到form上,然后thread调用起来,也有这个问题。哪位老大见过这个问题?貌似和Appartment有关?

posted @ | Feedback (8) | Filed Under [ Solution ]

本文是对sqlserver性能调整的一个简单的入门介绍(局限于索引部分),大多是图片。架构固然重要,但细节问题我们要首先处理好。我碰到一些项目,索引都没有用好,这时候你优化代码、优化程序结构,是意义不大的。根据我的经验,调整索引需要你对索引有一个清晰的认识,需要对业务需求有一个合理的取舍过程。 偶只希望对应用性能关注的各位同仁,能从我这个连环画里面,看到点、学到点东西。能够建立自己的数字观念,偶就很满足了。道理是相通的,虽然技巧不同、工具不同,但对于其他数据库,如Oracle/ DB2/ Informix,都是一样的。数字观念,拿数字说话,这是一个好的思维模式。(附一个小题目:你的客户要求你提供一个方案,希望满足到2010年最近3年的存储需求,你该如何做这个方案?) 全文连接,点本随笔的标题即可。

posted @ | Feedback (40) | Filed Under [ Solution ]

摘要:这个回复是针对我上一个post大家的热情回复而写的。安全问题容易被人忽视,倒不是说不重视,而是自己苦心研究出来的东西,很容易从其他人另一个角度被攻破。 尤其在.NET上,这种问题之所以出现,我认为是大家对于.NET的视角不同造成的。.net让快速开发确实达到了,但是也让程序员丧失了“警惕性”。 那位兄弟说的破解成本确实是问题。成本太高,破解没有意义了。但是致命的是,我接触到的这些国内ERP厂商,对于序列号控制这部分,实在是太脆弱了,脆弱到破解成本几乎就是0 - 虽然后面有大型应用、技术支持这个说法。 我印象中看卡巴斯基的书上说,最好的“提高破解难度”的方法是在native code中进行SEH处理,把核心代码放到catch里面。据说这样会让cracker晕倒……………… 至于加壳与否,我认为只要想做,有足够的耐心,把内存都dump出来,象dos下面破解,一样的。...[阅读全文]

posted @ | Feedback (15) | Filed Under [ VS.NET ]

摘要:业界对于Java/.NET程序的一个批评就是其安全性。由于IL的特点,各种reflector很容易把代码搞出来。混淆器,貌似一个很常用的功能吧?今天看某个软件,与我们的应用有些类似,所以想借鉴一下。安装好之后,发现有一个License Manager,两个按钮,一个是生成申请信息,一个是导入序列号。(通用的做法,我们的应用也是这么做的)用reflector打开后,ooh,大概80%的信息都被混淆掉了。field/method的名称,都成了稀奇古怪的文字。还有,我的File Disassembler plug-in居然不能用了,于是只能把所有的method/field信息都paste到notepad上面。(下面所有代码,出于众所周知的原因,我又做了第二次“混淆”,所有的变量/方法名称,都是随意写的) 映入眼帘的第一个method是.ctor,我们知道这个是缺省的构造方法。看代码,如下: public SomeConstructor(){      this.Abcdef123456();} 上面的方法就是被混淆过了,虽然没意义,但是我们能够“猜测”出来!进入上面的Abcdef123456方法,如下: private void Abcdef123456(){      this.fedcba654321 = new Container();      Button button1 = new Button();      Button button2 = new Button();      ...} 好熟悉吧!这就是InitializaComponent方法,查找所有的Abcdef123456,统一替换为这个新名字就可以了。同样的道理,通过看程序运行时候的界面、在查找代码,能更正90%以上的混淆名称,变成一个清晰的表达(虽然不一定和源代码相同) 继续看reflector的结果,有两个分别是Button1_Click和Button2_Click方法。先看第一个,里面有段代码如下:byte[] buffer1 = MD5.Encrypt(this.B33498573V + '\v' + this.J39475SDf, false);stream1.Write(buffer1, 0, buffer1.Length);byte[] buffer2 = MD5.Encrypt(new UnicodeEncoding().GetBytes(text1));stream1.Flush();if (SomeCondition == true){      SaveCPUandDISKInfo(this.B33498573V.Text , this.J39475SDf.Text);}InfoShow("\u751f\u6210"); 看起来似乎很麻烦?晕,居然还有MD5,还有一些复杂的逻辑判断。怎么搞?分析那个MD5怎么加密的吗?没意义!首先我们看最后面的InfoShow,我们都知道,这是Unicode编码方式下的文字,简单的用Console.WriteLine出来即可,上面的两个字是“生成”,于是我们猜测,这个和序列号可能相关。很自然的,我们会想到,对于注册的话,会有“成功”或者“失败”。前者转换为unicode是:\u6210\u529f。好吧,我们搜索“\u6210\u529f”。幸运!我们在Button2_Click方法中找到了这个字符串。这个方法代码如下:if (MD5.CheckRegisterKey(this.FileWillImported.Text)){    File.Copy();    ReadRegistry();    GetCPUandDISKinfoFromDatabase();    if(ResultFromUpline() == true){        SetCPUandDISKinfoIntoDatabase();    }    InfoShow("\u6210\u529f");}else{    InfoShow("\u975e\u6cd5");} 我们看到上面的代码,进行了一些复杂的操作,包括什么MD5/SHA/RSA等,最后成功才显示出来一个"\u6210\u529f"。作为游戏,我们继续寻找“失败”的unicode bytes,ooh,没有找到!但是从上面的代码我们可以看出,最后的else是有问题的。同样的Console.WriteLine一下,显示出来的是“非法”这两个汉字。 下面的工作就简单了,ildasm /out方式,把IL弄出来,直接调用SetCPUandDISKinfoIntoDatabase方法,屏蔽掉所有的判断即可。再用reflector看,该文件并没有任何对于非托管代码的refrence,安装目录下面也没有任何非托管dll,所以基本确定就是这样子了。 总结一下,我们用到的方法,都是20年前的方法。找到关键字符串,查找上下文可疑代码,把相关的判断信息都屏蔽掉,工作就完成了。那些花哨的各种“非对称算法”,没有任何意义。因为在加密解密工作中,流程的转向是重要的,流程本身,是无意义的。这里没有我们10年前看到的那些让人目眩的反侦查手法。 前段时间帮一朋友看过一个.net的应用,用usb key来做的,调用了自己写的Win32 API。同样的弊病,写了非常复杂的加密、解密、反跟踪、反调试处理,可惜的是,这一切都是在Win32中作的,.NET代码只是简单的做了CALL。屏蔽掉了200多行的IL,直接return true,唔,这个世界清净了……………… (再次声明,本文纯属对于.NET简单混淆的一个讨论,文中对于该软件的任何可以识别的特征,都进行了“混淆”)(对于破解和反汇编,可以看卡巴斯基本人写的那本黑客反汇编揭秘,本人对于汇编纯属文盲) 反过头来,我们考虑本文标题的内容,.NET或者J2EE代码应该如何保护?混淆是必要的,但太脆弱。反跟踪、反调试,我记着有高手在作,但是我不认为这能解决根本问题。不管多复杂的加密手段,被一些低级的代码调用的时候,总能很快的被搞定,如上面分析的那些代码。  ...[阅读全文]

posted @ | Feedback (11) | Filed Under [ VS.NET ]

摘要:很好的日子,2007年1月1日收到了确认通知。这是偶第二次通过Solution Architect的MVP,很是高兴。 ...[阅读全文]

posted @ | Feedback (11) | Filed Under [ Solution ]