破解Rockey3加密狗复制方法:调用锁的指令

破解Rockey3加密狗复制方法:调用狗的指令

 

 

目的:普及一下Rockey3狗的基本知识及分析的一些方法,有机会分析一下Rockey3的狗壳。

练习内容:系统所带的文件

说明:Rockey3下文中简称R3狗

  

1. 查找狗(RY_FIND)

目的: 查找指定密码的加密狗是否存在

输入参数:

function = RY_FIND  功能码 1

*p1 = 密码1    //必须

*p2 = 密码2    //必须

*p3 = 密码3 (可选)

*p4 = 密码4 (可选)

返回:

retcode = 0 表示成功,其它为错误码。无狗错误码为3

当成功时,*lp1 中为加密狗的硬件ID

//说明:1)密码1及密码2的是必须的,也是查找狗的基础,也称为一级口令。

        密码3和密码4是高级密码,只有有了这一组密码才可以写狗的用

        户ID区,模块区,自定义算法区,这三块的内容中除用户ID区

        外,其它二个正是狗的复制难点之处。

        2)返回的lp1中数据类型为无符号整数,这一个也正是识别不同的R4

        狗的重要之处。同时也是一些软件加密要用的内容。

  

2. 打开狗(RY_OPEN)

目的: 打开指定密码及硬件ID 的加密狗

输入参数:

function = RY_OPEN

*p1 = 密码1   //和1功能中应该相同,且不可改变Lp1中的硬件ID

*p2 = 密码2   //和1功能中应该相同

*p3 = 密码3 (可选)

*p4 = 密码4 (可选)

*lp1 = 硬件ID

返回:

retcode = 0 表示成功,其它为错误码。

当成功时,*handle 为加密狗的句柄

lp2 为加密狗的类型

 //说明: 在lp2中的类型比较重要,一些狗用的比较好的。会判断当

         前的狗的类型,如果类型不对,就是其它的参数相同,也会

         不认当前的狗。

         在这里请注意狗的类型不同,相应的数据量也不同,标版内

         存区为24个字节,自定义算法区 32条指令,增强版及网络版

         内存区为120个字节,自定义算法区为80条指令。

 

3. 关闭狗(RY_CLOSE)

目的: 关闭相应handle 的加密狗

 输入参数:

 function = RY_CLOSE

*handle = 狗的句柄

返回:

retcode = 0 表示成功,其它为错误码。

 

4. 读狗(RY_READ)

目的: 读出加密狗用户读写区的内容

输入参数:

function = RY_READ

*handle = 狗的句柄

*p1 = 位置

*p2 = 长度(以字节为单位)

buf = 缓冲区的指针

返回:retcode = 0 表示成功,其它为错误码。

当成功时,buf 中为读入的内容。

 //buf是直接的内存区,在读数据时要根据功能3中返回的类型判断长度,不

  要超长,标版24 增强及网络版是120。

 

5. 写狗(RY_WRITE)

目的: 向用户读写区内写入内容

输入参数:

function = RY_WRITE

*handle = 狗的句柄

*p1 = 位置

*p2 = 长度(以字节为单位)

buffer = 缓冲区的指针

返回:

retcode = 0 表示成功,其它为错误码。

 //说明同上

 

6. 随机数(RY_RANDOM)

目的: 从加密狗得到一个随机数

输入参数:

function = RY_RANDOM

*handle = 狗的句柄

返回:

retcode = 0 表示成功,其它为错误码。

当成功时,*p1 中为加密狗返回的随机数

 //这个在实际加密的过程中没有多大的意义,在自定义的算法中有意

  义,但不是我们调用得到的。这个功能对用户开放无多大的意义。

 

7. 种子码(RY_SEED)

目的: 得到种子码的返回码

输入参数:

function = RY_SEED

*handle = 狗的句柄

*lp2 = 种子码    //重要之处,在分析时一定要注意这个入口值是多少

返回:

retcode = 0 表示成功,其它为错误码。

当成功时,

*p1 = 返回码1

*p2 = 返回码2

*p3 = 返回码3

*p4 = 返回码4

 //说明:4个返回值用处很大,也是加密者经常使用的功能,这个种子码和狗的密

        码相关,同号狗(指密码相同)生成的种子返回值都是相同的。

        这个功能在狗壳的分析中也是难度最大的,如果没有狗,那是没有办法

        知道返回值的,但可以采用变通的方式来完成,从而取得种子码的返回

        值,也就是常说的无狗脱狗壳的方法。

 

8. 写用户ID(RY_WRITE_USERID)

目的: 写入用户定义的ID

输入参数:

function = RY_WRITE_USERID

*handle = 狗的句柄

*lp1 = 用户ID     //是一个无符号长整型

返回:

retcode = 0 表示成功,其它为错误码。

 //这个功能要求在1功能和3功能中打开狗时指定高级密码,否则是不允许写入的,

  如果无高级密码状态下写入次数过多,将可能会损坏狗或将狗狗死,请慎重操作。

 

9. 读用户ID (RY_READ_USERID)

目的: 读出用户定义的ID

输入参数:

function = RY_READ_USERID

*handle = 狗的句柄

返回:

retcode = 0 表示成功,其它为错误码。

当成功时,*lp1 为用户ID

 //读可以不用高级密码。

 

10. 设置模块(RY_SET_MOUDLE)

目的: 设置模块字及递减属性

输入参数:

function = RY_SET_MOUDLE

*handle = 狗的句柄

*p1 = 模块号

*p2 = 用户模块字

*p3 = 是否允许递减(1 = 允许,0 = 不允许)

返回:

retcode = 0 表示成功,其它为错误码。

 //模块的数据比较特殊,只有有高级密码的情况下才可以写,但就是具有了全部的

密码,也不能读出模块的内容,但可以用变通的方法来读出它的数值。

 

11. 检查模块属性(RY_CHECK_MOUDLE)

目的: 检查模块属性字

输入参数:

function = RY_CHECK_MOUDLE

*handle = 狗的句柄

*p1 = 模块号

返回:

retcode = 0 表示成功,其它为错误码。

当成功时,

*p2 = 1 表示此模块有效

*p3 = 1 表示此模块可以递减

 //这一项功能常用在一些试用版的软件上,使用了递减功能,使模块内的数据逐步

  减1,当为0时,当前模块将无效,测试功能也就结束了。

 

12. 写算法(RY_WRITE_ARITHMETIC)

目的: 向加密狗中写入自定义算法

输入参数:

function = RY_WRITE_ARITHMETIC

*handle = 狗的句柄

*p1 = 算法区位置

buffer = 算法指令串

返回:

retcode = 0 表示成功,其它为错误码。

 // 自定义是难度最高的部分,也是这个R3的狗特点之一,可以将一些关键计算写到

狗中,指令格式见后面。但因为狗的自身原因,不可能写入太多的指令,否则软件

的速度会很受影响,算法常是1-10条之间,当然并不一定,如果指令少,还可以用

猜的办法来获得算法,但如果过长,那时间将是天文数字。

 

13. 计算1 (RY_CALCULATE1)   功能码:E

目的: 让加密狗进行指定方式的运算,计算结果由用户算法决定。

输入参数:

function = RY_CALCULATE1

*handle = 狗的句柄

*lp1 = 计算起始点     //从第几行代码开始执行

*lp2 = 模块号         //模块参与运算

*p1 = 输入值1

*p2 = 输入值2

*p3 = 输入值3

*p4 = 输入值4

返回:

retcode = 0 表示成功,其它为错误码。

当成功时,

*p1 = 返回值1

*p2 = 返回值2

*p3 = 返回值3

*p4 = 返回值4

 //如果指定的起始点不是狗内的自定义算法起始点,那么返回的值都是随机数,

没有多少意义,但正是利用这一点,我们可以判断出狗内有几组算法区。

 

14. 计算2 (RY_CALCULATE2)  功能码:F

目的: 让加密狗进行指定方式的运算,计算结果由用户算法决定。

输入参数:

function = RY_CALCULATE2

*handle = 狗的句柄

*lp1 = 计算起始点

*lp2 = 种子码    //种子码参与运算

*p1 = 输入值1

*p2 = 输入值2

*p3 = 输入值3

*p4 = 输入值4

返回:

retcode = 0 表示成功,其它为错误码。

当成功时,

*p1 = 返回值1

*p2 = 返回值2

*p3 = 返回值3

*p4 = 返回值4

 

15. 计算3 (RY_CALCULATE3)   功能码:10H

目的: 让加密狗进行指定方式的运算,计算结果由用户算法决定。

输入参数:

function = RY_CALCULATE3

*handle = 狗的句柄

*lp1 = 计算起始点

*lp2 =模块字起始地址    //完全由模块来参与运算,

*p1 = 输入值1

*p2 = 输入值2

*p3 = 输入值3

*p4 = 输入值4

返回:

retcode = 0 表示成功,其它为错误码。

当成功时,

*p1 = 返回值1

*p2 = 返回值2

*p3 = 返回值3

*p4 = 返回值4

 //对于算法来说,直接参数应该是9个,1是位置的起始点 2是 p1,p2,p3,p4 对

  应ABCD 4个入口参数 3就是狗内的E F G H,对应由LP2指定功能区数据,

  E功能中 E硬件ID高位  F硬件ID低位  G模块字    H随机

  F功能中 E是种子码生成的数值1  F数值2   G 数值3   H 数值4

  10功能中就是模块的值了,由LP2指定的开始模块的连续4个。

 

16. 递减(RY_DECREASE)

目的: 对指定模块字进行递减操作

输入参数:

function = RY_DECREASE

*handle = 狗的句柄

*p1 = 模块号

返回:

retcode = 0 表示成功,其它为错误码。

 //用于测试值中递减模块中的数据

 常用错误码

ERR_SUCCESS                0 //没有错误         **最好的一个

ERR_NO_DRIVER              2 //没安装驱动程序

ERR_NO_ROCKEY              3 //没有ROCKEY       **易用的一个

ERR_INVALID_PASSWORD       4 //有ROCKEY狗,但基本密码错  

ERR_OPEN_OVERFLOW         16 //打开的狗太多(>16)

参数格式:

WORD Rockey

(

WORD  function,

WORD*  handle,

DWORD* lp1,

DWORD* lp2,

WORD*  p1,

WORD*  p2,

WORD*  p3,

WORD*  p4,

BYTE*  buffer

);

C 语言调用样例,下面的说明都会依照这个样例来说明:

retcode = Rockey(function,handle,lp1,lp2,p1,p2,p3,p4,buffer);

ROCKEY函数的参数定义如下:

参数名称  参数类型      参数含义

Function  16位数        API 函数功能

Handle    16位数的地址  狗操作句柄的指针

lp1       32位数的地址  长参数1

lp2       32位数的地址  长参数2

p1        16位数的地址  参数 1

p2        16位数的地址  参数 2

p3        16位数的地址  参数 3

p4        16位数的地址  参数 4

Buffer     8位数的地址  字符缓冲区指针

<注意>:

所有的接口参数必须在程序中定义,不能传递一个 NULL 类型的空指针过去,否则程序会出现错误。

1.1 function 是 16 位数字,它代表具体的功能,其定义如下:

RY_FIND                 1 //找狗

RY_FIND_NEXT            2 //找下一把狗

RY_OPEN                 3 //打开狗

RY_CLOSE                4 //关闭狗

RY_READ                 5 //读狗

RY_WRITE                6 //写狗

RY_RANDOM               7 //产生随机数

RY_SEED                 8 //产生种子码

RY_WRITE_USERID         9 //写用户 ID

RY_READ_USERID         10 //读用户 ID

RY_SET_MOUDLE          11 //设置模块字

RY_CHECK_MOUDLE        12 //检查模块状态

RY_WRITE_ARITHMETIC    13 //写算法

RY_CALCULATE1          14 //计算 1

RY_CALCULATE2          15 //计算 2

RY_CALCULATE3          16 //计算 3

RY_DECREASE            17 //递减模块单元

 

算法指令格式

 我们所有的算法指令必须是下列形式:

reg1 = reg2 op reg3/value

其中 reg1,reg2,reg3 都是某个寄存器,value 是个立即数,op 是运算符。

例如: A = A + B

我们所支持的所有运算符有:

  +  加法   -  减法   <  循环左移  *  乘法

  ^  异或   &  与     |  或        ~  取反(标准版)

  ?  比较(增强版和网络版)

value 是数值,只能是 0 - 63 之间的十进制数值。

 

<注意>:

 ~ 是我们标准版加密狗才有的指令,在增强版和网络版中,原来的这个指令代码被用于

比较,使用新的符号 "?"。

1) ~ 指令是单参数操作符,所以 A = A ~ B 就是 A = ~A 后面的 B 参数被忽略。

2) ? 指令用于比较两个操作数,例如 C = A ? B,比较结果如下:

 C    A?B    B?A

A

A=B  FFFF  FFFF

A>B  FFFF  0

C 里面会根据比较结果放入 0 或者 FFFF

 算法指令的一些限制

 

  在开发者编写加密狗算法指令的时候,会有一些特定的限制,结合一些例子,我们会介

绍这些限制是什么:

A = A + B  合法指令

D = D ^ D  合法指令

A = B    非法指令,必须按算法格式,可写成 A = B | B

A = 0    非法指令,必须按算法格式,可写成 A = A ^ A

C = 3 * B  非法指令,常数必须放在后面,可写成 C = B * 3

D = 3 + 4  非法指令,一条指令内只能使用一个常数

A = A / B  非法指令,我们不支持除法运算符

H = E*200  非法指令,常数必须小于 64

A = A*63   看情况,我们不允许在算法中的第一条指令和最后一条指令中使用常数。

 

如果这条指令出现在中间就是合法指令,如果是算法的第一条或最后一条指令就是非法指令


推荐

  • QQ空间

  • 新浪微博

  • 人人网

  • 豆瓣

取消