首页
社区
课程
招聘
[分享]Virtual Serial Port Driver Mobile 4.2 注册算法分析(手机平台)
发表于: 2008-6-14 11:15 12159

[分享]Virtual Serial Port Driver Mobile 4.2 注册算法分析(手机平台)

2008-6-14 11:15
12159

[破文标题]Virtual Serial Port Driver Mobile 4.2  注册算法分析
[破文作者]Baby2008
[破解工具]IDA + WM5 DeviceEmulator+010Editor
[破解平台]Windows XP Sp2
[软件名称]VSPD Mobile 4.2  
[软件大小]很小 132KB
[软件语言]英文   
[软件类别]国外软件 / 共享软件
[原版下载]http://www.serial-port-communication.com/virtual-serial-port-mobile/
[保护方式]注册码
[软件简介]掌上设备虚拟端口,玩GPS导航经常用到,感觉比GPSGate 好使。
[破解声明]我是一只小菜鸟,偶得一点心得,愿与大家分享,初学Crack,只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
          好久没玩XXX,破文格式都忘光了,请见谅....

--------------------------------------------------------------
[破解内容]
--------------------------------------------------------------

1、火力侦查

   启动模拟器,同步,IDA反编译后修改Process Options后直接F9运行,点击Reg按钮输入注册试炼码Key1,Key2,点击“注册”,跳出对话框提示“Incorrect registion key”;
   
2、分析
   有了这个好办了,IDA切换到Function,在 MessageBoxW函数下断,重新运行程序,重新点击注册:程序中断在00014064,向上查找来到:
.text:00013F58 01 1B A0 E3+MOVL    R1, 0x404 ; <suspicious>
.text:00013F60 04 00 A0 E1 MOV     R0, R4
.text:00013F64 6B 09 00 EB BL      GetDlgItem
.text:00013F64
.text:00013F68 7D 2F A0 E3 MOV     R2, #0x1F4 ; <suspicious>
.text:00013F6C 01 1B A0 E3+MOVL    R1, 0x408 ; <suspicious>
.text:00013F74 01 10 8D E0 ADD     R1, SP, R1
.text:00013F78 62 09 00 EB BL      GetWindowTextW
.text:00013F78
.text:00013F7C 01 1B A0 E3+MOVL    R1, 0x405 ; <suspicious>
.text:00013F84 04 00 A0 E1 MOV     R0, R4
.text:00013F88 62 09 00 EB BL      GetDlgItem
.text:00013F88
.text:00013F8C 7D 2F A0 E3 MOV     R2, #0x1F4 ; <suspicious>
.text:00013F90 7F 1E 8D E2 ADD     R1, SP, #0xBE8+var_3F8
.text:00013F94 5B 09 00 EB BL      GetWindowTextW

  ......省略部分代码......
  
.text:00014018 10 00 95 E5 LDR     R0, [R5,#0x10]
.text:0001401C 7D 3F A0 E3 MOV     R3, #0x1F4 ; <suspicious>
.text:00014020 7F 2E 8D E2 ADD     R2, SP, #0xBE8+var_3F8
.text:00014024 69 10 A0 E3 MOV     R1, #0x69 ; 'i' ; <suspicious>
.text:00014028 2E 09 00 EB BL      LoadStringW
.text:00014028
.text:0001402C 21 1E 8D E2 ADD     R1, SP, #0xBE8+var_9D8          ; key1
.text:00014030 18 00 8D E2 ADD     R0, SP, #0xBE8+var_BD0          ; key2
.text:00014034 5D FF FF EB BL      sub_13DB0                       ; 验证,关键函数
.text:00014034
.text:00014038 00 00 50 E3 CMP     R0, #0                          ; 注册结果判断
.text:0001403C 11 00 00 0A BEQ     loc_14088
.text:0001403C
.text:00014040 21 1E 8D E2 ADD     R1, SP, #0xBE8+var_9D8
.text:00014044 18 00 8D E2 ADD     R0, SP, #0xBE8+var_BD0
.text:00014048 DB FE FF EB BL      sub_13BBC
.text:00014048
.text:0001404C 14 21 9F E5 LDR     R2, =s->VspdMobile4_2
.text:00014050 00 30 A0 E3 MOV     R3, #0
.text:00014054 01 1B A0 E3+MOVL    R1, 0x408 ; <suspicious>
.text:0001405C 01 10 8D E0 ADD     R1, SP, R1
.text:00014060 04 00 A0 E1 MOV     R0, R4
.text:00014064 1B 09 00 EB BL      MessageBoxW                     ; 中断在这里^_^
.text:00014064
.text:00014068 00 00 95 E5 LDR     R0, [R5]
.text:0001406C 3F 1E A0 E3 MOV     R1, #0x3F0 ; <suspicious>
.text:00014070 28 09 00 EB BL      GetDlgItem

   
这个验证判断方式太普通了,没啥好说的,跟进 sub_13DB0 看看:
.text:00013DB0             sub_13DB0                               ; CODE XREF: sub_13EE4+150p
.text:00013DB0                                                     ; sub_14680+158p
.text:00013DB0
.text:00013DB0             var_14= -0x14
.text:00013DB0             var_10= -0x10
.text:00013DB0
.text:00013DB0 30 40 2D E9 STMFD   SP!, {R4,R5,LR}
.text:00013DB4 08 D0 4D E2 SUB     SP, SP, #8
.text:00013DB8 01 40 A0 E1 MOV     R4, R1
.text:00013DBC D7 FF FF EB BL      sub_13D20                       ; 计算Key1
.text:00013DBC
.text:00013DC0 00 50 A0 E1 MOV     R5, R0                          ; 结果保存在R5
.text:00013DC4 04 00 A0 E1 MOV     R0, R4                          ; 指向Key2
.text:00013DC8 D4 FF FF EB BL      sub_13D20                       ; 计算Key2
.text:00013DC8
.text:00013DCC 00 40 A0 E1 MOV     R4, R0                          ; 结果保存在R4
.text:00013DD0 00 00 8D E2 ADD     R0, SP, #0x14+var_14
.text:00013DD4 04 10 8D E2 ADD     R1, SP, #0x14+var_10
.text:00013DD8 43 FF FF EB BL      sub_13AEC                       ; 产生机器码
.text:00013DD8
.text:00013DD8             ; End of function sub_13DB0
.text:00013DD8
.text:00013DDC 00 30 9D E5 LDR     R3, [SP]                        ; 机器码 MachineNo1
.text:00013DE0 38 20 9F E5 LDR     R2, =0x456C7469
.text:00013DE4 05 30 23 E0 EOR     R3, R3, R5                      ; EOR 将在两个操作数上进行逻辑异或
.text:00013DE8 02 00 53 E1 CMP     R3, R2
.text:00013DEC 04 00 00 1A BNE     loc_13E04                       ; MachineNo1 EOR Result(Key1)=0x456C7469
.text:00013DEC
.text:00013DF0 04 30 9D E5 LDR     R3, [SP,#4]
.text:00013DF4 20 20 9F E5 LDR     R2, =0x6D613330
.text:00013DF8 04 30 23 E0 EOR     R3, R3, R4
.text:00013DFC 02 00 53 E1 CMP     R3, R2
.text:00013E00 01 00 00 0A BEQ     loc_13E0C                       ; 同理,MachineNo2 EOR Result(Key2)=0x6D613330
.text:00013E00
.text:00013E04
.text:00013E04             loc_13E04                               ; CODE XREF: .text:00013DECj
.text:00013E04 00 00 A0 E3 MOV     R0, #0                          ; 注册验证失败标记
.text:00013E08 00 00 00 EA B       loc_13E10                       ; 弹出失败窗口
.text:00013E08                                                     ; 注册验证爆破点,00 00 A0 E1(Nop)
.text:00013E08
.text:00013E0C             ; ---------------------------------------------------------------------------
.text:00013E0C
.text:00013E0C             loc_13E0C                               ; CODE XREF: .text:00013E00j
.text:00013E0C 01 00 A0 E3 MOV     R0, #1                          ; 注册成功标志
.text:00013E0C
.text:00013E10
.text:00013E10             loc_13E10                               ; CODE XREF: .text:00013E08j
.text:00013E10 08 D0 8D E2 ADD     SP, SP, #8
.text:00013E14 30 40 BD E8 LDMFD   SP!, {R4,R5,LR}
.text:00013E18 1E FF 2F E1 BX      LR

这段代码说明了注册验证的大致过程是:
--------------------------------------------
注册码1运算结果 EOR 机器码1=0x456C7469
注册码2运算结果 EOR 机器码2=0x6D613330  
--------------------------------------------

现在关键是看机器码是怎么运算的了,跟进sub_13D20:
.text:00013D20
.text:00013D20             ; =============== S U B R O U T I N E =======================================
.text:00013D20
.text:00013D20
.text:00013D20             sub_13D20                               ; CODE XREF: sub_13DB0+Cp
.text:00013D20                                                     ; sub_13DB0+18p
.text:00013D20
.text:00013D20             arg_5=  5
.text:00013D20
.text:00013D20 F0 43 2D E9 STMFD   SP!, {R4-R9,LR}
.text:00013D24 00 90 A0 E1 MOV     R9, R0
.text:00013D28 BE 09 00 EB BL      strlen
.text:00013D28
.text:00013D2C 06 00 50 E3 CMP     R0, #6                          ; key长度必须为6位
.text:00013D30 00 00 A0 13 MOVNE   R0, #0
.text:00013D34 F0 43 BD 18 LDMNEFD SP!, {R4-R9,LR}
.text:00013D38 1E FF 2F 11 BXNE    LR
.text:00013D38
.text:00013D3C D5 00 D9 E1 LDRSB   R0, [R9,#arg_5]                 ; 取Key的第6位,记为key[6]
.text:00013D40 E1 FF FF EB BL      sub_13CCC                       ; 字符转16进制函数?
.text:00013D40
.text:00013D44 00 80 A0 E1 MOV     R8, R0
.text:00013D48 D4 00 D9 E1 LDRSB   R0, [R9,#4]                     ; 5
.text:00013D4C DE FF FF EB BL      sub_13CCC
.text:00013D4C
.text:00013D50 00 70 A0 E1 MOV     R7, R0
.text:00013D54 D3 00 D9 E1 LDRSB   R0, [R9,#3]                     ; 4
.text:00013D58 DB FF FF EB BL      sub_13CCC
.text:00013D58
.text:00013D5C 00 60 A0 E1 MOV     R6, R0
.text:00013D60 D2 00 D9 E1 LDRSB   R0, [R9,#2]                     ; 3
.text:00013D64 D8 FF FF EB BL      sub_13CCC
.text:00013D64
.text:00013D68 00 50 A0 E1 MOV     R5, R0
.text:00013D6C D1 00 D9 E1 LDRSB   R0, [R9,#1]                     ; 2
.text:00013D70 D5 FF FF EB BL      sub_13CCC
.text:00013D70
.text:00013D74 00 40 A0 E1 MOV     R4, R0
.text:00013D78 D0 00 D9 E1 LDRSB   R0, [R9]                        ; 1
.text:00013D7C D2 FF FF EB BL      sub_13CCC
.text:00013D7C
.text:00013D80 08 32 68 E0 RSB     R3, R8, R8,LSL#4                ; a1=(key[6] LSL 4)-Key[6]=0xF*Key[6]
.text:00013D84 03 31 87 E0 ADD     R3, R7, R3,LSL#2                ; a2=(a1 LSL 2)+Key[5]
.text:00013D88 03 32 63 E0 RSB     R3, R3, R3,LSL#4                ; a3=a2*0xF
.text:00013D8C 03 31 86 E0 ADD     R3, R6, R3,LSL#2                ; a4=(a3 LSL 2)+Key[4]
.text:00013D90 03 32 63 E0 RSB     R3, R3, R3,LSL#4                ; a5=a4*0xF
.text:00013D94 03 31 85 E0 ADD     R3, R5, R3,LSL#2                ; a6=(a5 LSL 2)+Key[3]
.text:00013D98 03 32 63 E0 RSB     R3, R3, R3,LSL#4                ; a7=a6*0xF
.text:00013D9C 03 31 84 E0 ADD     R3, R4, R3,LSL#2                ; a8=(a7 LSL 2)+Key[2]
.text:00013DA0 03 32 63 E0 RSB     R3, R3, R3,LSL#4                ; a9=a8*0xF
.text:00013DA4 03 01 80 E0 ADD     R0, R0, R3,LSL#2                ; a10=(a9 LSL 2)+Key[0]并返回结果
.text:00013DA8 F0 43 BD E8 LDMFD   SP!, {R4-R9,LR}
.text:00013DAC 1E FF 2F E1 BX      LR

3、注册算法总结

上段代码中a10 就是注册码的计算结果并返回,到此,注册码整个验证过程就清楚了;

sub_13D20(Key1)=a10, a10 EOR MachineNo1=常数0x456C7469,  
sub_13D20(Key2)=a10, a10 EOR MachineNo2=常数0x6D613330;
根据已知的机器码,常数求得a10

再根据
a1=(key[6] LSL 4)-Key[6]=0xF*Key[6]
a2=(a1 LSL 2)+Key[5]
a3=a2*0xF
a4=(a3 LSL 2)+Key[4]
a5=a4*0xF
a6=(a5 LSL 2)+Key[3]
a7=a6*0xF
a8=(a7 LSL 2)+Key[2]
a9=a8*0xF
a10=(a9 LSL 2)+Key[0]
的要求分别求的Key[0,1,2,3,4,5,6],这个好像有点晕,留给数学高人来玩注册机;

(完)        2008.06.14


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (10)
雪    币: 232
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
好贴,谢谢楼主分享!
2008-6-14 16:51
0
雪    币: 2575
活跃值: (502)
能力值: ( LV2,RANK:85 )
在线值:
发帖
回帖
粉丝
3
这些指令看不懂
2008-6-14 17:12
0
雪    币: 260
活跃值: (81)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
支持baby
2008-6-14 20:04
0
雪    币: 817
活跃值: (1927)
能力值: ( LV12,RANK:2670 )
在线值:
发帖
回帖
粉丝
5
baby在2008又回来了
2008-6-15 05:16
0
雪    币: 136
活跃值: (105)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
6
hehe 且贴留名
2008-6-15 10:02
0
雪    币: 276
活跃值: (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
破解功力有限,目前还仅限于暴破!
2008-6-20 11:31
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
好  好东西
2008-6-20 17:23
0
雪    币: 186
活跃值: (201)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
好东西!!!
2008-9-18 22:59
0
雪    币: 208
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
确实利害呀!!
2008-11-21 23:32
0
雪    币: 134
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
F5不行么?
2008-11-22 08:23
0
游客
登录 | 注册 方可回帖
返回
//