破解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空间
-
新浪微博
-
人人网
-
豆瓣