[破文标题]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
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!