• 标 题:翻译:Zendenc FLEXlm 7.2 破解信息[TT]
  • 作 者:newsearch
  • 时 间:2004-12-27,18:02
  • 链 接:http://bbs.pediy.com

作者:Nolan Blender
翻译:newsearch[TT]

引言

    该破解信息涵盖了使用默认加密保护的FLEXLM7.2包的破解。Globetrotter已经有了一个新的、 改进的防伪选项,它需要额外花钱-本文并不包括这些,如在写本文时并未分析“椭圆曲线加密技术ECC”("安全生成器"代码) 。
    本文的读者对象是那些想快速直接地从FLEXLM的最近版本中得到加密种子的有经验的破解者。如果对目前FLEXLM方法有清晰的理解将是很有帮助的,要求理解怎样使用IDA和SoftICE。

对象的URL/FTP

可能需要如下文件 (Calcseed.exe / Zendenc.exe) : (534k).

正文

     FLEXlm密钥取决于存储在许可证 软件中的两个秘密值:ENCRYPTION_SEED1 和 ENCRYPTION_SEED2。这些值由软件VENDOR选取并嵌入FLEXLM到产品中。如果这些值被恢复了,将不采取额外的安全措施(如vendor定义的检查, 它进行对应于许可证的额外检查;或用户加密滤波器,它在许可证密钥上应用了加密的一个额外层), 那么就可以为目标程序产生有效的许可证了。
    用于隐藏FLEXLM密钥值的方法变得越来越复杂了 ,这可能是回应于破解者已经能够提取密钥/在一些客户面前生成新的软件版本甚至看到(破解)软件到了自家门口!尽管其改进有较长的历史,但我仅涵盖最近的版本。

    目前,种子由发布给最终用户的特定子程序隐藏,该子程序在程序建立中产生密钥数据。其中一个函数(routine:例程/程序)产生VENDORCODE结构的一个版本, 该结构包含了正确的VENDOR密钥,但非正确的加密种子。另一个函数采用该数据并提取种子,但在job结构(Globetrotter用于存储 当前FLEXLM会话状态信息的一个全局数据空间)和VENDORCODE结构之间分割有效数据。在FLEXLM内的加密或验证函数使用之前,该数据将被重新编译。
    一个随机值(基于时间)将与job结构和VENDORCODE结构中的值进行与或运算,以使其更难于恢复加密种子。

    FLEXLM的早期版本(6.1-7.0)包含了一个执行弱点。通过用job结构的一个空指针传递到lm_new的恢复函数中,就可能在VENDORCODE结构中恢复正确的加密种子。最容易的技术(尽管还有其它技术)是用IDA搜索l_sg和FLEXLM签名,搜索lm_new种子恢复函数的调用(通常靠近l_sg函数的起始处,且是一个指针值调用)。使用SOFTICE加载程序,在译码函数调用处设置断点。

    job结构指针 ,即第一个参数由一个空指针(0)替换。VENDORCODE结构指针,即第三个参数将被检查并且程序将跳过对lm_new函数的调用。在调用后检查VENDORCODE结构,然后它将包含正确的种子。FLEXLM的后期版本校正了该问题,当job结构的一个空指针传递时,不会填充正确的种子。实际上,子程序不再试图修改种子。那么,在这种情况下怎样恢复种子呢?
    实践证明,在VENDORCODE和job结构之间分发数据的算法相当简单,它仅基于vendorname的第一个字符。因为lm_new.c由lmrand2产生,因此完全可能用逆向工程找到怎样提取种子,然后写程序重新编译来自job结构和VENDORCODE结构的数据,并用这种方法恢复种子。文章Nolflex2.htm(译者注:即该作者的另一篇文章“FLEXLM对象使用的信息隐藏方法 FLEXLM种子隐藏系统的一个解释”)有该方法的详细叙述。
    首先将ZENDENC.EXE程序加载进IDA中,然后在初次反编译完成后搜索一个要多次调用_time的函数,它将是lm_new函数。如果我们得到了该版本的正确签名,我们可以简单地在IDA中应用签名并定位l_sg;但是,因为我们没有(正确签名),因此我们不得不做得艰难些。一旦我们定位了要多次调用时间的函数,我们就在程序的其它部分中寻找函数的参考---在这种情况下,我们仅找到一个参考:

.text:004010E7 cmp dword_49E5EC, 0
.text:004010EE jnz short loc_4010FA
.text:004010F0 mov dword_49E5EC, offset sub_40D572

    在4010FA处的指令执行后,在49E5EC处的值将指向lm_new译码函数。下一步是查找49E5EC的参考,因为它是函数被调用的地方,或其值被拷贝进寄存器供调用。通过检查该处的参考,我们找到该调用的一个可能位置:

.text:0043900D mov eax, [ebp+arg_8]
.text:00439010 push eax
.text:00439011 mov ecx, [ebp+arg_4]
.text:00439014 push ecx
.text:00439015 mov edx, [ebp+arg_0]
.text:00439018 push edx
.text:00439019 call dword_49E5EC

    在439019处是指针调用,因此这极可能是出现调用译码函数的地方。
它不会像在l_sg中一样被验证,但这是一个安全的赌注,假如我们有命名函数的FLEXLM7.1的签名的话。但是,我们需要一个“假的”许可证以得到该函数的调用。 用那种方法,我们可以使该函数被调用。

 FEATURE Zend_Encoder zend 9.9 permanent uncounted VENDOR_STRING=blah\ HOSTID=ANY SIGN=123412341234
  
    我想,我通过查找检查调用得到了FEATURE名字,并看看在那里传入了什么 ,还有其它许多方法也可得到FEATURE;如果你了解FLEXLM的话,我确信你熟悉这一切了。下一步是在license.dat文件中放入假的许可证,在SOFTICE中加载ZENDENC.EXE,可能的话加载一个自做的符号表。
    程序加载后在入口处中断,在439019处设置断点,在该点检查堆栈---我使用 dd esp进行。因为参数被从右到左压入堆栈, 且有三个参数传递到译码函数,我们可以判定给函数传入了什么;esp包含了指向job结构的指针,esp+4包含了指向含有vendor名字的一个字符串指针,esp+8包含了指向VENDORCODE结构的一个指针。我在我的机子里记录了如下值---也许你得到了不同的值:

302B70 - ptr to job结构
302CBC - ptr to vendor名称
12CF98 - ptr to vendorcode结构

    通过检查包含的文件,我们确定在vendorcode+4和vendorcode+8处的值是用作data[0]和data[1]的值,后面具有加密种子。我们可以用dd (12CF98+4)得到加密种子数据值的基础值,并用dd (302b70+8)得到在job结构中种子隐藏区的值。程序每次运行的这些值都将不同,因此同时记录两套值。
   下面是我在运行中得到的:

vendorcode+4 是data[0] : DCE0A0A2
vendorcode+8 是data[1] : FC58117B
job+8 : D3B4B0C2
job+c : 81042659
job+10 : D493C07C

运行calcseed恢复如下:

ENCRYPTION_SEED1 : FA5410DE
ENCRYPTION_SEED2 : DAECA107

    我已经提供了calcseed.exe, 它是 Nolflex2.htm论文的具体实现,并有其执行计算以获取种子的叙述。其中,encseed[0]和encseed[1]是实际的加密种子。Selector值是当job数组被当做字符数组时从job数组中提取的值索引,仅提供给感兴趣的。与或值(XOR)是获取的值,用于与数据值进行与或运算以得到加密种子。

结束语

    本文是叙述FLEXLM的另一篇论文,由Globetrotter奇才---Nolan Blender所写。到现在为止,你应该知道用它干什么了吧,坐下来并学习它!-CrackZ
=============================================================
    译者注:这是网上一篇关于FLEXLM破解的很有名的文章。是FLEXLM破解专家Nolan Blender早期写的,据国外的文章讲对9.0版本都适用(我没有试过)。这篇文章不是最新的,但个人认为原理讲得很好,权作教学资料。另外,本文将“routine”(本意为:例程/程序)翻译为“函数”,是读了作者的几篇文章和其它一些资料认定的。可能作者采用了Fortran语言的习惯。对否,请高手斧正。
    原文出处:http://www.woodmann.com/crackz/Tutorials/Nolflex3.htm