VB6.0中提示:该部件的许可证信息没有找到,在设计环境中,没有合适的许可证使用该功能”的解决办法

OCX许可

用友U8产品使用了大量的OCX控件进行界面开发,其中有一大部分是使用VB6开发的。如果你想在项目中引用这些控件,往往你会发现一个提示,类似如下截图:
VB6.0中提示:该部件的许可证信息没有找到,在设计环境中,没有合适的许可证使用该功能”的解决办法_第1张图片

OCX许可注册表位置

如果你去百度,得到的回答是控件没有开发许可证。在深入研究,就会知道,一般ocx控件都会需要个注册表文件,将许可证信息写入到如下位置,VB6编译的时候可以选择是否需要许可证,需要时就会生成vbl文件,帮助分发给最终使用者:
VB6.0中提示:该部件的许可证信息没有找到,在设计环境中,没有合适的许可证使用该功能”的解决办法_第2张图片
经过一段时间的查询,发现这个许可证是在COM组件初始化的时候调用了某个特殊函数去判定的。一开始我以为是IDE的一种特殊控制,甚至想过去破解IDE,现在想想好傻。哈哈。

判定许可的关键函数

那么具体调用是哪个函数呢,这个说起来比较复杂,需要懂得一些COM组件的原理。这里把我找到的一个源代码贴上来,这样讲起来比较容易。代码来自微软的.Net源码,其中有个叫做AxHost的类,专门用来封装OCX控件。让控件可以放置在Form中进行设计。其中最关键的初始化代码如下:

private void CreateWithLicense(string license, Guid clsid) {
   if (license != null) {
       try {
           Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Creating object with license: " +
           clsid.ToString());
           UnsafeNativeMethods.IClassFactory2 icf2 = UnsafeNativeMethods.CoGetClassObject(ref clsid,
           INPROC_SERVER, 0, ref icf2_Guid);
           
           if (icf2 != null) {
               Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "\tClassFactory" + (icf2 !=
               null).ToString());
               //最关键的调用,CreateInstanceLic
               icf2.CreateInstanceLic(null, null, ref NativeMethods.ActiveX.IID_IUnknown, license,
               out instance);
               Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "\t" + (instance != null).ToString());
           }
       }
       catch (Exception t) {
           Debug.WriteLineIf(AxHTraceSwitch.TraceVerbose, "Failed to create with license: " +
           t.ToString());
       }
   }
   
   if (instance == null) {
       CreateWithoutLicense(clsid);
   }
}

代码中,最关键的调用就是CreateInstanceLic,这个函数是COM组件标准函数,隶属于lCassFactory接口下。感兴趣可以翻翻msdn文档。IDE也好,你自己写代码调用也好,首先需要调用的就是这个函数,这个函数有个返回值,就是instance。如果你传入的lic字符串不合法,你就只能得到null。换言之,你想初始化一个OCX控件,你首先需要调用CreateInstanceLic,然后才能得到实例。所以说所有的合法性判定,license校验都在这个函数里面。
那机智的你肯定在想,可否反编译干他!答:我帮你试试。下图是反编译vb6的OCX文件,你会发现连个鬼都找不到,IDA加载后只能看到不几个函数:
VB6.0中提示:该部件的许可证信息没有找到,在设计环境中,没有合适的许可证使用该功能”的解决办法_第3张图片
之所以会这样,主要因为VB6大部分功能是委托给MSVBVM60.dll去处理的,很多标准功能都是在这个dll内部实现的。所以如果想找到CreateInstanceLic,你必须去反编译MSVBVM60.dll。而这个dll本身比较复杂,是c++和汇编语言编写的混血儿,其实我以前也研究过一段时间,发现真的非常难。很多国外的大牛也在研究后做了很多工作,比如编写idc文件给IDA分析使用,我觉得这个非常好用,配合vb反编译程序,简直超爽。还有人专门整理了历史过程中发行MSVBVM60.dll的所有版本,这看似好像挺无聊的,但是他解决了一个很大的问题,就是符号文件。我们下面聊聊符号文件。

符号文件的作用

符号文件是反编译中比较有利的一个外挂,他可以在IDA反编译时,把所有函数的名称和参数对应到二进制中。方便分析人员快速定位。而vb6的这个dll我只找到了3个符号文件,必须配合非常旧的dll才能正确使用,所以最终也只用上了其中的一个叫做msvbvm60.dbg的文件。当你把他和dll挂接在一起后。IDA就可以进行自动分析,强大分析能力,简直让人佩服的五体投地。直接看截图吧:
VB6.0中提示:该部件的许可证信息没有找到,在设计环境中,没有合适的许可证使用该功能”的解决办法_第4张图片
就这代码给你反编译的,你都不好意思说看不懂。哈哈。利用F5提供的C代码查看功能,发现有个叫做CalcValue的函数,这个函数居然可以算出来一个license key,然后和你注册表里面的key,一个字一个字的判断,如果相等那么就可以使用这个控件。当我发现这里时,我激动地拿出ollydbg调试了一下,发现果真如此。这个算法咋形容呢?你还能再不负责任一点吗。
VB6.0中提示:该部件的许可证信息没有找到,在设计环境中,没有合适的许可证使用该功能”的解决办法_第5张图片

CalcValue破解

问题到此基本算清晰了,vb6调用CalcValue函数计算license key然后和注册表里面的进行判定(注意这个算法对大小写是敏感的)。如果key一致,校验成功。如果你像我一样使用ollydbg,那么只要挂接vb6.exe就可以秒破这些控件。但是出于简单化和后期傻瓜化的考虑,我还是认真分析了一下CalcValue函数的计算过程。并最终用excel实现了这个算法,让大家顺便也学学excel。这个函数唯一需要的参数是一个GUID字符串,是Typelib对应的GUID,至于这个号码怎么查询,我就不说了,你可以百度研究一下,很简单的。唯一需要的的工具叫做OleViewDotNetX86,Excel我放在CSharpU8项目中了。要特别注意的是,这个算法严格区分大小写,所以尤其注意TypeLib的GUID,有的GUID里面有小写字母,有的就全是大写字母,具体咋回事我也没有细研究,反正只要你字母写对了,key肯定正确。许可license一定都是小写。
VB6.0中提示:该部件的许可证信息没有找到,在设计环境中,没有合适的许可证使用该功能”的解决办法_第6张图片

你可能感兴趣的:(U8,控件,C#)