newsoft88 发表于 2009-11-15 20:50:18

让软件自己来Emulator你的ROCKEY4加密锁

【文章标题】: 让软件自己来Emulator你的ROCKEY4加密锁
【文章作者】: newsoft88
【作者邮箱】: [email protected]
【作者主页】: http://newsoft88.ys168.com
【软件名称】: 某行业分析软件
【软件大小】: 3M
【下载地址】: 自己搜索下载
【加壳方式】: 压缩壳
【保护方式】: 加密狗
【编写语言】: VC++
【使用工具】: OD、IDA、PEID等
【操作平台】: WINXP
【软件介绍】: 一款行业软件,使用锁加密,就是常说的飞天加密锁
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
   对于飞天锁,R4其实有很多DUMP数据工具,但也有人知道那模拟器比DUMP要难找得的多,原因不说大家自明,昨天看了一款用ROCKEY锁的软件,所以我一般

不去找什么模拟器,因为我没有原锁,所以总是扣数据,要不就放弃了!·
这款软件加的压缩壳没什么,找个机机撬开,,OK后,使用载入;原头如下:
E8 2B070000      call    00511C60             ;(initial cpu selection)
E9 37FDFFFF      jmp   00511271


    直接运行后,没有任何提示所有功能全不好用,点一些功能会出错退出!
   
    对于这种情况,我们首先确定下是什么锁,即我们的对手是什么,因为该软件看不到驱动,只是个绿色文件,所以单从表面看不出,所以我们就要让OD辛苦

一下,查看个究竟了!

    我们用OD载入程序,下断CreaFileA,这个是正常看狗较灵的断点! F9运行,几次断点时看堆栈,直到出现如下字符时,我们就知道用的是什么锁了!

    00608593|.FF15 2C925200 call    dword ptr [<&KERNEL32.GetVersion>;kernel32.GetVersion
00608599|.6A 00         push    0                              ; /hTemplateFile = NULL
0060859B|.3D 00000080   cmp   eax, 80000000                  ; |
006085A0|.68 80000000   push    80                               ; |Attributes = NORMAL
006085A5|.6A 03         push    3                              ; |Mode = OPEN_EXISTING
006085A7|.6A 00         push    0                              ; |pSecurity = NULL
006085A9|.6A 00         push    0                              ; |ShareMode = 0
006085AB|.68 000000C0   push    C0000000                         ; |Access = GENERIC_READ|GENERIC_WRITE
006085B0|.0F83 D0010000 jnb   00401486                         ; |
006085B6|.68 50A05700   push    0057A050                         ; |\\.\rockeynt
006085BB|.8B3D 44925200 mov   edi, dword ptr [<&KERNEL32.Creat>; |kernel32.CreateFileA
006085C1|.FFD7          call    edi                              ; \CreateFileA

   \\.\rockeynt 看这个就知道,飞天的产品了!

下面我们来回忆下飞天ROCK的几个重要函数,这种我们将要进行的动作非常相关:

   WORD Rockey(WORD function, WORD* handle, DWORD* lp1,DWORD* lp2, WORD* p1, WORD* p2, WORD* p3, WORD* p4, BYTE* buffer)
(1) 查找锁
      输入参数:
      function = 1 (函数功能号)
      *p1 = pass1
      *p2 = pass2
      *p3 = pass3
      *p4 = pass4
      返回:
      *lp1 为锁的硬件 ID

   返回为 0 表示成功, 其它为错误码
(10)读用户 ID
       function = 10
       *handle = 锁的句柄
       返回:
       *lp1 = 用户 ID
       返回为 0 表示成功, 其它为错误码

(5) 读锁
      输入参数:
      function = 5
      *handle = 锁的句柄
      *p1 = pos
      *p2 = length
      buffer = 缓冲区的指针
      返回:
      buffer 中添入读入的内容
      返回为 0 表示成功, 其它为错误码

WORD Rockey(WORD function, WORD* handle, DWORD* lp1,DWORD* lp2, WORD* p1, WORD* p2, WORD* p3, WORD* p4, BYTE* buffer)
(16) 计算3 (模块字, ID 高位, ID 低位, 随机数)
       function = 16
       *handle = 锁的句柄
       *lp1 = 计算起始点
       *lp2 = 模块号
       *p1 = 输入值1
       *p2 = 输入值2
       *p3 = 输入值3
       *p4 = 输入值4
       返回:
       *p1 = 返回值1
       *p2 = 返回值2
       *p3 = 返回值3
       *p4 = 返回值4
       返回为 0 表示成功, 其它为错误码


   其他函数从略,我们只说主要的,了解上面的函数后,我开始在OD进行调试,通过调试,我断在读狗代码的中心区,看下面的:
我们一节一节来看,

000680A34|.51            push    ecx
000680A35|.8D5424 1C   lea   edx, dword ptr
000680A39|.52            push    edx
000680A3A|.8D4424 34   lea   eax, dword ptr
000680A3E|.50            push    eax
000680A3F|.8D4C24 34   lea   ecx, dword ptr
000680A43|.51            push    ecx
000680A44|.8D5424 2C   lea   edx, dword ptr
000680A48|.52            push    edx
000680A49|.6A 01         push    1
000680A4B|.E8 F007F5FF   call    00601240

//这个CALL就是读狗的CALL,其实一下就能看清楚,他调用了多次在本节中,根据ROCK函数的输入变量要求,所以在调用他前总是有很多参数的!

PUSH 1 ,就是该调用的功能号,从此看出,我们知道该函数是查找狗;(不太清楚的童鞋去参看ROCKEY的SDK函数介绍吧!)

000680A50|.83C4 24       add   esp, 24
000680A53|.66:85C0       test    ax, ax

该判断是找狗后的看有没有加密锁,没有狗则返回错误号!有狗就是0了,所以我们将来模拟他时就强制返回了0;

000680A56|.0F85 1C040000 jnz   000680E78
000680A5C|.8D4424 40   lea   eax, dword ptr
000680A60|.50            push    eax
000680A61|.8D4C24 18   lea   ecx, dword ptr
000680A65|.51            push    ecx
000680A66|.8D5424 20   lea   edx, dword ptr
000680A6A|.52            push    edx
000680A6B|.8D4424 14   lea   eax, dword ptr
000680A6F|.50            push    eax
000680A70|.8D4C24 1C   lea   ecx, dword ptr
000680A74|.51            push    ecx
000680A75|.8D5424 34   lea   edx, dword ptr
000680A79|.52            push    edx
000680A7A|.8D4424 34   lea   eax, dword ptr
000680A7E|.50            push    eax
000680A7F|.8D4C24 2C   lea   ecx, dword ptr
000680A83|.51            push    ecx

这里,3号功能,打开锁,和他对应的是关闭锁,就是在最后了!

000680A84|.6A 03         push    3         //打开加密狗;
000680A86|.E8 B507F5FF   call    00601240    //读狗CALL
000680A8B|.83C4 24       add   esp, 24
000680A8E|.66:85C0       test    ax, ax      //确定AX是不是0以确定是不是有狗;


000680A91|.0F85 E1030000 jnz   000680E78//跳走无狗


000680A97|.8D5424 40   lea   edx, dword ptr
000680A9B|.52            push    edx
000680A9C|.8D4424 18   lea   eax, dword ptr
000680AA0|.50            push    eax
000680AA1|.8D4C24 20   lea   ecx, dword ptr
000680AA5|.51            push    ecx
000680AA6|.8D5424 14   lea   edx, dword ptr
000680AAA|.52            push    edx
000680AAB|.8D4424 1C   lea   eax, dword ptr
000680AAF|.50            push    eax
000680AB0|.8D4C24 34   lea   ecx, dword ptr
000680AB4|.51            push    ecx
000680AB5|.8D5424 34   lea   edx, dword ptr
000680AB9|.52            push    edx
000680ABA|.8D4424 2C   lea   eax, dword ptr
000680ABE|.50            push    eax

000680ABF|.6A 0A         push    0A       =10号功能   ; // 读用户ID
000680AC1|.895C24 40   mov   dword ptr , ebx
000680AC5|.E8 7607F5FF   call    00601240

000680ACA|.83C4 24       add   esp, 24
000680ACD|.66:85C0       test    ax, ax
000680AD0|.0F85 A2030000 jnz   000680E78            //跳走无狗

00680AD6      817C24 40 424>cmp   dword ptr ,   USERID   //检查ID是不是正确
00680ADC      0F85 3D030000 jnz   00680E78                           //跳走完完


      以下读锁:

00680B1A|.6A 05         push    5                         //5号功能,从锁中读出数据;
00680B1C|.E8 1F07F5FF   call    00601240                        ;读锁
00680B21|.83C4 30       add   esp, 30
00680B24|.66:85C0       test    ax, ax
00680B27|.0F85 4B030000 jnz   00680E78
00680B2D      817xxxxxxxx>cmp   dword ptr , 数据1//找中的要点数据
00680B35      0F85 3D030000 jnz   00680E78
00680B3B      807C24 44 xxcmp   byte ptr ,数据2//找中的要点数据
00680B40      0F85 32030000 jnz   00680E78
00680B46      807C24 45 xxcmp   byte ptr , 数据3//找中的要点数据
00680B4B      0F85 27030000 jnz   00680E78

               。。。。。。。。。。。。。


       这里面我们要提及的是几个数据:(涉及数据版权,暂用汉字说明意思)

            USERID:用户ID,
            
            数据1 :读锁的数据,将来用于数据功能运行         
            数据2 :读锁的数据,将来用于数据功能运行         
            数据3 :读锁的数据,将来用于数据功能运行;

软件继续去读狗;我们看

000680B80|.FFD6          call    esi         ; [rand //取随机数
000680B82|.83C0 03       add   eax, 3
000680B85|.0FB7D0      movzx   edx, ax
000680B88|.895424 24   mov   dword ptr , edx
000680B8C|.FFD6          call    esi
000680B8E|.0FB74C24 18   movzx   ecx, word ptr
000680B93|.0FB75424 14   movzx   edx, word ptr
000680B98|.0FB77C24 24   movzx   edi, word ptr
000680B9D|.83C0 03       add   eax, 3
000680BA0|.0FB7C0      movzx   eax, ax
000680BA3|.894424 20   mov   dword ptr , eax
000680BA7|.894C24 3C   mov   dword ptr , ecx
000680BAB|.0FB7C0      movzx   eax, ax
000680BAE|.895424 38   mov   dword ptr , edx
000680BB2|.8D4C24 4C   lea   ecx, dword ptr
000680BB6|.51            push    ecx
000680BB7|.894424 34   mov   dword ptr , eax
000680BBB|.8D5424 24   lea   edx, dword ptr
000680BBF|.52            push    edx
000680BC0|.8D4424 2C   lea   eax, dword ptr
000680BC4|.50            push    eax
000680BC5|.8D4C24 20   lea   ecx, dword ptr
000680BC9|.51            push    ecx
000680BCA|.8D5424 28   lea   edx, dword ptr
000680BCE|.52            push    edx
000680BCF|.8D4424 40   lea   eax, dword ptr
000680BD3|.50            push    eax
000680BD4|.8D4C24 40   lea   ecx, dword ptr
000680BD8|.51            push    ecx
000680BD9|.8D5424 38   lea   edx, dword ptr
000680BDD|.52            push    edx

000680BDE|.6A 10         push    10                  //读狗
000680BE0|.E8 5B06F5FF   call    00601240            ;计算3 (RY_CALCULATE3)   功能码:10H

   &H10 号功能,是狗中运算功能,这个东西是要有点运气,想去找出他的算法的话,我是运气好,一下给蒙出来了,当然如果找不到,就去查出所有调用他
的地方,统统的用JZ替代JNZ,也是个办法!

    下面看看我的蒙的过程

000680BE5|.8B4C24 58   mov   ecx, dword ptr
000680BE9|.83C4 28       add   esp, 28
000680BEC|.0FB7C0      movzx   eax, ax
000680BEF|.51            push    ecx
000680BF0|.8BCD          mov   ecx, ebp
000680BF2|.894424 44   mov   dword ptr , eax

000680BF6|.E8 A5FCFFFF   call    0006808A0      // 对狗计算的数据进行变换,
000680BFB|.3D 8A0C0000   cmp   eax, 0D23   //比较是否大?

000680C00      0F8D 3E010000 jge   000680D44
000680C06|.66:395C24 40cmp   word ptr , bx
000680C0B|.0F85 33010000 jnz   000680D44
000680C11|.8B5424 10   mov   edx, dword ptr
000680C15|.8B4424 30   mov   eax, dword ptr
000680C19|.83C2 DF       add   edx, -21
000680C1C|.50            push    eax
000680C1D|.8BCD          mov   ecx, ebp
000680C1F|.66:895424 46mov   word ptr , dx

000680C24|.E8 77FCFFFF   call    0006808A0    //对狗计算的数据进行变换,
000680C29|.3D F90C0000   cmp   eax, 0FF5   //比较是否大?
000680C2E      0F8D 10010000 jge   000680D44

这个狗中的计算取的数据简单,通过跟踪后,发现他取的是一个时间数据变量,取到后,与现在的机器时间进行相差,

结果通过一个容不得错区间比较,如果在这个差域内,则说明通过了!


以下为最后一个狗函数!关闭(CLOSE DOG)狗!4号功能
000680E4A|.6A 04         push    4
000680E4C|.E8 EF03F5FF   call    00601240                        ;close

了解上面的过程后,我们开始对软件做手术,就是在每个调用点上,给他正确的返回扬数据,所以这点和微狗的给值是类似的,只有你给他了,狗才会听话哟



我们进入调狗代码,拟合下数据:这个CALL:call00601240 读狗哟!

在 00601240 键入以下代码:

00601240      8B4424 04         mov   eax, dword ptr

//取得狗功能码给EAX,为什么是ESP+4,因为调用读狗前PUSH的就是功能号;


00601244      83F8 05             cmp   eax, 5
00601247      74 12               je      short 0060125B//5号向读狗

00601249      83F8 0A             cmp   eax, 0A
0060124C      74 08               je      short 00601256 //10号取狗ID


0060124E      83F8 10             cmp   eax, 10
00601251      74 29               je      short 0060127C //16号狗中计算

00601253      33C0                xor   eax, eax   //其他号调用狗的都让他返回0;如打开锁、查找锁、关闭锁、检验密码等;
00601255      C3                  retn



10 号取狗的USERID:

00601256      C74424 54 88888888mov   dword ptr , XXXXXXXX
0060125E      33C0                xor   eax, eax
00601260      C3                  retn

5号读狗中的数据:

00601261      C74424 7C 88888888mov   dword ptr , 数据1
00601269      C78424 80000000 888>mov   dword ptr , 数据2

                   。。。。。。。。。。。。。。。。。。。。。。 数据N

00601274      33C0                xor   eax, eax            返回0
00601276      C3                  retn


16号取狗中的动态数据(计算数据)

0060127C      FF15 54925200       call    dword ptr [<&KERNEL32.GetTickCount>]   //取时间
00601282      35 CF000000         xor   eax, 0CF                               //计算
00601287      894424 5C         mov   dword ptr , eax                //存放
0060128B      33C0                xor   eax, eax                               //EAX回0
0060128D      C3                  retn


以上写完后,保存为一个新文件,运行测试,一切OK,狗驯服了!,收工!

写得可能有点乱,我已经很努力去说清楚了,实在文字水平这样,有看不懂的童鞋,一定相信是我的文字组织的不好,狗一定是你可以征服的!



--------------------------------------------------------------------------------
【经验总结】
    现在的狗不象早期的锁了,就那个几个判断,强跳后就解决了,现的狗总是搞得那么花,不光是代码花,数据也花,所以
甚至有作者吹出“不可破解”的神话,但对于软件原理总就是那么回事,所以我总觉得要看锁,先去看作者的SDK,函数接
口,事半功倍是肯定的了,由于本人水平有限,写的不好,请不要向我扔石头!

--------------------------------------------------------------------------------
【版权声明】: 谢谢观看, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2009年11月15日 15:02:31

飘云 发表于 2009-11-15 21:10:54

我们用OD载入程序,下断CreaFileA,

感谢楼主好文章~~ 纠正一处笔误:CreateFileA

daihu37 发表于 2009-11-16 16:50:20

好文,谢谢分享

cjteam 发表于 2009-11-16 22:21:53

/:good 學習了

llh001 发表于 2009-11-19 17:17:09

好文章,写的很详细,感谢分享!

lal978112 发表于 2009-11-20 20:57:38

写得不错啊,向楼主学习!

老万 发表于 2009-11-21 21:02:03

学习了,谢谢楼主分享。

roczyl 发表于 2009-11-27 08:36:13

不错。学习了。

langzi 发表于 2014-7-4 15:16:04

学习了,谢谢楼主分享。

DaShanRen 发表于 2014-7-8 17:57:23

复制代码时,要是学会了关闭机器码,看起来更爽。
页: [1] 2
查看完整版本: 让软件自己来Emulator你的ROCKEY4加密锁