制作 GL Studio v3.02 的 license
按:好像没什么技术含量,仅供参考!
手头的这个软件,试用版license已经过期,故不得不自己动手找一个不过期的license。
license中签名的长度是12个字符,可断定没使用公钥保护,不需打补丁就可以找出关键
参数,做出正确的license。
1、确定版本号(用lmtools.exe或lmver.exe都可以)
FLEXlm v9.2.0 (lmgr.lib)
2、生成Vendor Key(用lmkg.exe)
/* Version 9 keys */
#define VENDOR_KEY1 0x109922eb
#define VENDOR_KEY2 0x9ca04eba
#define VENDOR_KEY3 0xc3934b79
#define VENDOR_KEY4 0xdbcfd49c
#define VENDOR_KEY5 0x623a63f1
#define CRO_KEY1 0x14b920e3
#define CRO_KEY2 0xda822c3c
#define VENDOR_NAME "DISTI"
3、找FEATURE
这个很好找,在试用版license里面就有。或者在IDA里面也能找到。有两个:
glStudio
glStudioRuntime
4、找ENCRYPTION_SEED
反汇编主程序glStudio.exe,其中有一段是进行license检查的代码:
.text:004642CA push offset aAcquiringLicen ; "Acquiring License..."
.text:004642CF call sub_476F60
.text:004642D4 add esp, 4
.text:004642D7
.text:004642D7 loc_4642D7: ; CODE XREF: _main+328j
.text:004642D7 push edi
.text:004642D8 push offset a3_0 ; "3.0"
.text:004642DD push offset aGlstudio ; "glStudio"
.text:004642E2 mov ecx, offset unk_653090
.text:004642E7 call ds:?Checkout@License@disti@@QAEXPAD0_N@Z ; disti::License::Checkout(char *,char *,bool)
.text:004642ED mov ecx, offset unk_653090
.text:004642F2 call ds:?Valid@License@disti@@QAE_NXZ ; disti::License::Valid(void)
.text:004642F8 test al, al
.text:004642FA jnz short loc_46430A
.text:004642FC push offset aGlStudioDevelo ; "GL Studio Development license not found"...
.text:00464301 call ds:?fl_message@@YAXPBDZZ ; fl_message(char const *,...)
.text:00464307 add esp, 4
上面这段代码调用了glstudio3_0_2_vc71.dll中的几个函数。
反汇编glstudio3_0_2_vc71.dll,寻找两个关键函数lc_checkout、l_sg。
这两个函数的原型(见lm_ckout.c):
API_ENTRY
lc_checkout(
LM_HANDLE_PTR job, /* Current license job */
const LM_CHAR_PTR feature, /* The feature to be checked in */
const LM_CHAR_PTR version, /* Feature's version */
int nlic, /* Number of licenses to checkout */
int flag, /* Checkout flag */
const VENDORCODE_PTR key, /* The vendor's key */
int dup_group) /* Duplicate license grouping criteria */
{
void
l_sg(
LM_HANDLE * job,
char * vendor_id,
VENDORCODE * key) /*- l_sg means "signature vendor_key5" */
lc_checkout的定位比较简单,因为它有7个参数,在feature出现的地方就可以找到它。
.text:10079F20 _lc_checkout proc near ; CODE XREF: sub_10037C9A+54p
.text:10079F20 ; sub_10037C9A+A9p ...
.text:10079F20
.text:10079F20 var_8 = dword ptr -8
.text:10079F20 var_4 = dword ptr -4
.text:10079F20 arg_0 = dword ptr 8
.text:10079F20 arg_4 = dword ptr 0Ch
.text:10079F20 arg_8 = dword ptr 10h
.text:10079F20 arg_C = dword ptr 14h
.text:10079F20 arg_10 = dword ptr 18h
.text:10079F20 arg_14 = dword ptr 1Ch
.text:10079F20 arg_18 = dword ptr 20h
.text:10079F20
.text:10079F20 push ebp
.text:10079F21 mov ebp, esp
.text:10079F23 sub esp, 8
.text:10079F26 mov [ebp+var_4], 0
.text:10079F2D mov eax, [ebp+arg_0]
.text:10079F30 push eax
.text:10079F31 call sub_100862CE
.text:10079F36 add esp, 4
.text:10079F39 mov ecx, [ebp+arg_0]
.text:10079F3C mov edx, [ecx+3FCh]
.text:10079F42 or dh, 40h
.text:10079F45 mov eax, [ebp+arg_0]
.text:10079F48 mov [eax+3FCh], edx
.text:10079F4E push 95h
.text:10079F53 push offset aLm_ckout_c ; "lm_ckout.c" // 看看,多好的提示
.text:10079F58 mov ecx, [ebp+arg_0]
.text:10079F5B push ecx
.text:10079F5C call __initp_misc_winxfltr_0
.text:10079F61 add esp, 0Ch
.text:10079F64 mov edx, [ebp+arg_0]
.text:10079F67 add edx, 494h
.text:10079F6D push 0
.text:10079F6F push edx
.text:10079F70 call _setjmp3
.text:10079F75 add esp, 8
.text:10079F78 test eax, eax
.text:10079F7A jz short loc_10079F87
.text:10079F7C mov eax, [ebp+arg_0]
.text:10079F7F mov eax, [eax+14h]
.text:10079F82 jmp loc_1007A057
在IDA中搜索立即数0x6f7330b8,可找到l_sg。
.text:1007DABB _l_sg proc near ; CODE XREF: sub_10073B7E+C63p
.text:1007DABB ; sub_1007BC9F+C4p ...
.text:1007DABB
.text:1007DABB var_24 = dword ptr -24h
.text:1007DABB var_20 = dword ptr -20h
.text:1007DABB var_1C = dword ptr -1Ch
.text:1007DABB var_14 = byte ptr -14h
.text:1007DABB var_13 = word ptr -13h
.text:1007DABB var_11 = byte ptr -11h
.text:1007DABB var_10 = dword ptr -10h
.text:1007DABB var_C = dword ptr -0Ch
.text:1007DABB var_8 = dword ptr -8
.text:1007DABB var_4 = dword ptr -4
.text:1007DABB arg_0 = dword ptr 8
.text:1007DABB arg_4 = dword ptr 0Ch
.text:1007DABB arg_8 = dword ptr 10h
.text:1007DABB
.text:1007DABB push ebp
.text:1007DABC mov ebp, esp
.text:1007DABE sub esp, 24h
.text:1007DAC1 mov [ebp+var_14], 0
.text:1007DAC5 xor eax, eax
.text:1007DAC7 mov [ebp+var_13], ax
.text:1007DACB mov [ebp+var_11], al
.text:1007DACE mov [ebp+var_C], 6F7330B8h // 这个是比较重要的特征参数
.text:1007DAD5 mov [ebp+var_4], 0
.text:1007DADC mov [ebp+var_8], 0
.text:1007DAE3 mov [ebp+var_10], 3
.text:1007DAEA mov ecx, [ebp+arg_0]
.text:1007DAED mov edx, [ecx+6Ch]
.text:1007DAF0 mov eax, [edx+0F54h]
.text:1007DAF6 and eax, 8000h
.text:1007DAFB test eax, eax
.text:1007DAFD jz short loc_1007DB22
.text:1007DAFF cmp dword_10213CB4, 0
.text:1007DB06 jz short loc_1007DB22
.text:1007DB08 mov ecx, [ebp+arg_8]
.text:1007DB0B push ecx
.text:1007DB0C mov edx, [ebp+arg_4]
.text:1007DB0F push edx
.text:1007DB10 mov eax, [ebp+arg_0]
.text:1007DB13 push eax
.text:1007DB14 call dword_10213CB4 // 在这个地方下断
.text:1007DB1A add esp, 0Ch // 单步运行到这里
然后就是动态跟踪,找到以下参数:
输入dd [esp+8]
4D917F04 data[0]
4D9C696B data[1]
输入dd [esp+4]
DISTI vendor_id
输入dd [esp]
341F91CA job+08
00E80685 job+0c
004D0000 job+10
使用工具calcseed.exe,输入上述信息,可计算得到:
#define ENCRYPTION_SEED1 0x0000face
#define ENCRYPTION_SEED2 0x000deca1
ENCRYPTION_SEED3、ENCRYPTION_SEED4是SDK中的默认值,不需要改动,对计算license没有影响。
至此,分析已经基本完成,可以使用SDK计算license了。
5、写注册机
按照上面的信息,编辑lm_code.h,修改makefile,编译lmcrypt.c,大功告成!
注意:要将
#define ENCRYPTION_SEED1 0x0000face
#define ENCRYPTION_SEED2 0x000deca1
#define ENCRYPTION_SEED3 0x22334455
#define ENCRYPTION_SEED4 0x33221100
这几行放到lm_code.h文件中,
#define VENDOR_KEY5 。。。
后面即可。
后记:
第一次碰FlexLM,没想到运气真好,照着tulipfan[CCG]的大作
“制作Compuware.SoftIce.Driver.Suite.3.0.1.StinkyD的license”就轻松地搞定了它。
原计划花一个星期的时间,实际上只用了两天,总共10小时不到,还包括搜集资料和学习的
时间。
感谢tulipfan[CCG]!
--------------------------------------------------------------------------------
附录:FlexLM SDK 使用说明
以下以FLEXnet v10.1为例,简单介绍FlexLM SDK的使用流程。
这个流程也基本适用于 FlexLM SDK 的早期版本。
1、安装FlexLM SDK
刚安装完的SDK肯定是不能用的。若不信可运行i86_n3\lmwin.exe看看,肯定一个
feature都不能checkout,呵呵。
2、怎样才能让demo运行起来呢?
首先用工具lmkg.exe计算出一组vendor key。以下是一个例子:
/* Version 10 keys */
#define VENDOR_KEY1 0x321cd48b
#define VENDOR_KEY2 0xe6e4652c
#define VENDOR_KEY3 0x2076c1a2
#define VENDOR_KEY4 0xbbb34234
#define VENDOR_KEY5 0x0b165dca
#define CRO_KEY1 0x363cd683
#define CRO_KEY2 0xa0c607aa
#define VENDOR_NAME "demo"
然后在命令行下运行i86_n3\lmrand1.exe,生成一组随机数种子。
#define LM_SEED1 0xcdfeb228
#define LM_SEED2 0x1b111a77
#define LM_SEED3 0xfe02cc3d
最后修改 machind\m_code.h 中相应的行。
(注意:如果VENDOR_NAME不是demo,还要修改makefile中相应行。)
注意:
A.从v10.0以后,CRO_KEY1、CRO_KEY2改名为TRL_KEY1、TRL_KEY1。
B.关于LM_STRENGTH的可能定义值
可根据需要定义以下之一,推荐使用公钥保护,强度更高。
不使用公钥保护
LM_STRENGTH_DEFAULT: 签名长 12 字符
使用公钥保护(ECC)
LM_STRENGTH_113BIT, LOW: 签名长 58 字符
LM_STRENGTH_163BIT, MEDIUM: 签名长 84 字符
LM_STRENGTH_239BIT, HIGH: 签名长 120 字符
兼容v7.1以前的版本(不做变动)
LM_STRENGTH_LICENSE_KEY
3、写一个调用Visual C++ 6.0的脚本编译SDK
@echo off
set MSVCDir="C:\Program Files\Microsoft Visual Studio\VC98"
set PATH=%MSVCDir%\Bin;%PATH%
@call vcvars32.bat
@call build.bat
echo ............. Done!
pause
4、生成licences
lmcrypt counted.lic
lmcrypt uncounted.lic
lmcrypt expired.lic
pause
注意:需要先修改lic文件中除签名字符串以外的其它各项,然后再用以上命令
生成新的lic文件。上面的命令只更改签名字符串。
5、测试lincense
首先用i86_n3\lmtools.exe配置一个license server,可参考FlexLM编程指南。
然后运行i86_n3\lmwin.exe,看看所有的feature是不是都能checkout。
我这里是没有问题的,不知道你那里怎么样呢?
6、在自己的软件中调用FlexLM
仿照lmvendor.c调用API即可,很简单了。
[课程]FART 脱壳王!加量不加价!FART作者讲授!