在上一篇《How to Crack App by Self-Keygen》中,通过打印内存获取到了Serial,但是如何得到Keygen算法,还没有继续分析。下面具体分析Keygen算法。
0x1代码分析
已知道licenseForEmailAddress:withSecret:为产生Serial的函数。代码如下
000000000006175b push rbp ; Objective C Implementation defined at 0x2a2da8 (instance method), DATA XREF=0x2a2da8
000000000006175c mov rbp, rsp
000000000006175f push r15
0000000000061761 push r14
0000000000061763 push r13
0000000000061765 push r12
0000000000061767 push rbx
0000000000061768 sub rsp, 0x38
000000000006176c mov rbx, rcx
000000000006176f mov r13, rdx
0000000000061772 mov r15, rsi
0000000000061775 mov r12, rdi
0000000000061778 mov r14, qword [_objc_retain_25b300]
000000000006177f mov rdi, r13 ; argument "instance" for method _objc_retain
0000000000061782 call r14 ; _objc_retain
0000000000061785 mov qword [rbp+var_30], rax
0000000000061789 mov rdi, rbx ; argument "instance" for method _objc_retain
000000000006178c call r14 ; _objc_retain
000000000006178f mov qword [rbp+var_40], rax
0000000000061793 mov rax, qword [_OBJC_IVAR_$_HSLicense.initialized]
000000000006179a cmp byte [r12+rax], 0x0
000000000006179f jne loc_6184b
00000000000617a5 mov rdi, qword [objc_cls_ref_NSString] ; argument "instance" for method _objc_msgSend
00000000000617ac mov rsi, qword [0x2c0af0] ; @selector(stringWithUTF8String:), argument "selector" for method _objc_msgSend
00000000000617b3 lea rdx, qword [0x1e648d] ; "XXX.m"
00000000000617ba call qword [_objc_msgSend_25b2e8] ; _objc_msgSend
00000000000617c0 mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
00000000000617c3 call imp___stubs__objc_retainAutoreleasedReturnValue
00000000000617c8 mov rbx, rax
00000000000617cb test rbx, rbx
00000000000617ce lea rdi, qword [cfstring__Unknown_File_] ; @"<Unknown File>"
00000000000617d5 cmovne rdi, rbx ; argument "instance" for method _objc_retain
00000000000617d9 call qword [_objc_retain_25b300] ; _objc_retain
00000000000617df mov r14, rax
00000000000617e2 mov qword [rbp+var_38], r15
00000000000617e6 mov r15, qword [_objc_release_25b2f8]
00000000000617ed mov rdi, rbx ; argument "instance" for method _objc_release
00000000000617f0 call r15 ; _objc_release
00000000000617f3 mov rdi, qword [objc_cls_ref_NSAssertionHandler] ; argument "instance" for method _objc_msgSend
00000000000617fa mov rsi, qword [0x2c0af8] ; @selector(currentHandler), argument "selector" for method _objc_msgSend
0000000000061801 call qword [_objc_msgSend_25b2e8] ; _objc_msgSend
0000000000061807 mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
000000000006180a call imp___stubs__objc_retainAutoreleasedReturnValue
000000000006180f mov rbx, rax
0000000000061812 mov rsi, qword [0x2c0b00] ; @selector(handleFailureInMethod:object:file:lineNumber:description:), argument "selector" for method _objc_msgSend
0000000000061819 lea rax, qword [cfstring_License_has_not_been_initialized_] ; @"License has not been initialized."
0000000000061820 mov qword [rsp+0x60+var_60], rax
0000000000061824 mov r9d, 0xa7
000000000006182a xor eax, eax
000000000006182c mov rdi, rbx ; argument "instance" for method _objc_msgSend
000000000006182f mov rdx, qword [rbp+var_38]
0000000000061833 mov rcx, r12
0000000000061836 mov r8, r14
0000000000061839 call qword [_objc_msgSend_25b2e8] ; _objc_msgSend
000000000006183f mov rdi, r14 ; argument "instance" for method _objc_release
0000000000061842 call r15 ; _objc_release
0000000000061845 mov rdi, rbx ; argument "instance" for method _objc_release
0000000000061848 call r15 ; _objc_release
loc_6184b:
000000000006184b mov rdi, qword [objc_cls_ref_NSCharacterSet] ; argument "instance" for method _objc_msgSend, CODE XREF=-[HSLicense licenseForEmailAddress:withSecret:]+68
0000000000061852 mov rsi, qword [0x2c10f0] ; @selector(whitespaceAndNewlineCharacterSet), argument "selector" for method _objc_msgSend
0000000000061859 mov rbx, qword [_objc_msgSend_25b2e8]
0000000000061860 call rbx ; _objc_msgSend
0000000000061862 mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
0000000000061865 call imp___stubs__objc_retainAutoreleasedReturnValue
000000000006186a mov r15, rax
000000000006186d mov rsi, qword [0x2c10f8] ; @selector(stringByTrimmingCharactersInSet:), argument "selector" for method _objc_msgSend
0000000000061874 mov rdi, r13 ; argument "instance" for method _objc_msgSend
0000000000061877 mov rdx, r15
000000000006187a call rbx ; _objc_msgSend
000000000006187c mov r14, rax
000000000006187f mov r12, qword [_objc_release_25b2f8]
0000000000061886 mov rdi, qword [rbp+var_30] ; argument "instance" for method _objc_release
000000000006188a call r12 ; _objc_release
000000000006188d mov rdi, r14 ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
0000000000061890 call imp___stubs__objc_retainAutoreleasedReturnValue
0000000000061895 mov r13, rax
0000000000061898 mov qword [rbp+var_48], r13
000000000006189c mov rdi, r15 ; argument "instance" for method _objc_release
000000000006189f call r12 ; _objc_release
00000000000618a2 mov r14, qword [objc_cls_ref_NSString]
00000000000618a9 mov rsi, qword [0x2c1100] ; @selector(lowercaseString), argument "selector" for method _objc_msgSend
00000000000618b0 mov rdi, r13 ; argument "instance" for method _objc_msgSend
00000000000618b3 call rbx ; _objc_msgSend
00000000000618b5 mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
00000000000618b8 call imp___stubs__objc_retainAutoreleasedReturnValue
00000000000618bd mov r15, rax
00000000000618c0 mov rsi, qword [0x2c11d8] ; @selector(stringWithFormat:), argument "selector" for method _objc_msgSend
00000000000618c7 lea rdx, qword [cfstring______27de28] ; @"%@%@"
00000000000618ce xor eax, eax
00000000000618d0 mov rdi, r14 ; argument "instance" for method _objc_msgSend
00000000000618d3 mov rcx, r15
00000000000618d6 mov r8, qword [rbp+var_40]
00000000000618da call rbx ; _objc_msgSend
00000000000618dc mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
00000000000618df call imp___stubs__objc_retainAutoreleasedReturnValue
00000000000618e4 mov r14, rax
00000000000618e7 mov qword [rbp+var_50], r14
00000000000618eb mov rdi, r15 ; argument "instance" for method _objc_release
00000000000618ee call r12 ; _objc_release
00000000000618f1 mov rdi, qword [objc_cls_ref_HSLicense] ; argument "instance" for method _objc_msgSend
00000000000618f8 mov rsi, qword [0x2c3c28] ; @selector(MD5String:), argument "selector" for method _objc_msgSend
00000000000618ff mov rdx, r14
0000000000061902 call rbx ; _objc_msgSend
0000000000061904 mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
0000000000061907 call imp___stubs__objc_retainAutoreleasedReturnValue
000000000006190c mov r13, rax
000000000006190f mov rdi, qword [objc_cls_ref_NSMutableString] ; argument "instance" for method _objc_msgSend
0000000000061916 mov rsi, qword [0x2c07f0] ; @selector(string), argument "selector" for method _objc_msgSend
000000000006191d call rbx ; _objc_msgSend
000000000006191f mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
0000000000061922 call imp___stubs__objc_retainAutoreleasedReturnValue
0000000000061927 mov r15, rax
000000000006192a mov rsi, qword [0x2c0898] ; @selector(length), argument "selector" for method _objc_msgSend
0000000000061931 mov rdi, r13 ; argument "instance" for method _objc_msgSend
0000000000061934 call rbx ; _objc_msgSend
0000000000061936 mov r14, rax
0000000000061939 test r14, r14
000000000006193c jle loc_6199a
000000000006193e mov rax, qword [0x2c08c8] ; @selector(substringWithRange:)
0000000000061945 mov qword [rbp+var_38], rax
0000000000061949 mov r12, qword [0x2c1500] ; @selector(appendString:)
0000000000061950 inc r14
0000000000061953 mov qword [rbp+var_30], r15
loc_61957:
0000000000061957 lea rdx, qword [r14-2] ; CODE XREF=-[HSLicense licenseForEmailAddress:withSecret:]+571
000000000006195b mov ecx, 0x1
0000000000061960 mov rdi, r13 ; argument "instance" for method _objc_msgSend
0000000000061963 mov rsi, qword [rbp+var_38] ; argument "selector" for method _objc_msgSend
0000000000061967 call rbx ; _objc_msgSend
0000000000061969 mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
000000000006196c call imp___stubs__objc_retainAutoreleasedReturnValue
0000000000061971 mov r15, r13
0000000000061974 mov r13, rax
0000000000061977 mov rdi, qword [rbp+var_30] ; argument "instance" for method _objc_msgSend
000000000006197b mov rsi, r12 ; argument "selector" for method _objc_msgSend
000000000006197e mov rdx, r13
0000000000061981 call rbx ; _objc_msgSend
0000000000061983 mov rdi, r13 ; argument "instance" for method _objc_release
0000000000061986 mov r13, r15
0000000000061989 call qword [_objc_release_25b2f8] ; _objc_release
000000000006198f dec r14
0000000000061992 cmp r14, 0x1
0000000000061996 jg loc_61957
0000000000061998 jmp loc_6199e
loc_6199a:
000000000006199a mov qword [rbp+var_30], r15 ; CODE XREF=-[XXLicense licenseForEmailAddress:withSecret:]+481
loc_6199e:
000000000006199e mov rdi, qword [objc_cls_ref_HSLicense] ; argument "instance" for method _objc_msgSend, CODE XREF=-[HSLicense licenseForEmailAddress:withSecret:]+573
00000000000619a5 mov rsi, qword [0x2c3c30] ; @selector(hyphonate:everyX:), argument "selector" for method _objc_msgSend
00000000000619ac mov ecx, 0x6
00000000000619b1 mov rdx, qword [rbp+var_30]
00000000000619b5 call rbx ; _objc_msgSend
00000000000619b7 mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
00000000000619ba call imp___stubs__objc_retainAutoreleasedReturnValue
00000000000619bf mov r14, rax
00000000000619c2 mov rsi, qword [0x2c3c38] ; @selector(rangeOfString:options:), argument "selector" for method _objc_msgSend
00000000000619c9 lea rdx, qword [cfstring___279de8] ; @"-"
00000000000619d0 mov ecx, 0x4
00000000000619d5 mov rdi, r14 ; argument "instance" for method _objc_msgSend
00000000000619d8 call rbx ; _objc_msgSend
00000000000619da mov rsi, qword [0x2c1518] ; @selector(substringToIndex:), argument "selector" for method _objc_msgSend
00000000000619e1 mov rdi, r14 ; argument "instance" for method _objc_msgSend
00000000000619e4 mov rdx, rax
00000000000619e7 call rbx ; _objc_msgSend
00000000000619e9 mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
00000000000619ec call imp___stubs__objc_retainAutoreleasedReturnValue
00000000000619f1 mov r15, rax
00000000000619f4 mov rdi, r14 ; argument "instance" for method _objc_release
00000000000619f7 mov r12, qword [_objc_release_25b2f8]
00000000000619fe call r12 ; _objc_release
0000000000061a01 mov rsi, qword [0x2c1488] ; @selector(uppercaseString), argument "selector" for method _objc_msgSend
0000000000061a08 mov rdi, r15 ; argument "instance" for method _objc_msgSend
0000000000061a0b call rbx ; _objc_msgSend
0000000000061a0d mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
0000000000061a10 call imp___stubs__objc_retainAutoreleasedReturnValue
0000000000061a15 mov r14, rax
0000000000061a18 mov rdi, r15 ; argument "instance" for method _objc_release
0000000000061a1b call r12 ; _objc_release
0000000000061a1e mov rdi, qword [rbp+var_30] ; argument "instance" for method _objc_release
0000000000061a22 call r12 ; _objc_release
0000000000061a25 mov rdi, r13 ; argument "instance" for method _objc_release
0000000000061a28 call r12 ; _objc_release
0000000000061a2b mov rdi, qword [rbp+var_50] ; argument "instance" for method _objc_release
0000000000061a2f call r12 ; _objc_release
0000000000061a32 mov rdi, qword [rbp+var_40] ; argument "instance" for method _objc_release
0000000000061a36 call r12 ; _objc_release
0000000000061a39 mov rdi, qword [rbp+var_48] ; argument "instance" for method _objc_release
0000000000061a3d call r12 ; _objc_release
0000000000061a40 mov rdi, r14 ; argument "instance" for method imp___stubs__objc_autoreleaseReturnValue
0000000000061a43 add rsp, 0x38
0000000000061a47 pop rbx
0000000000061a48 pop r12
0000000000061a4a pop r13
0000000000061a4c pop r14
0000000000061a4e pop r15
0000000000061a50 pop rbp
0000000000061a51 jmp imp___stubs__objc_autoreleaseReturnValue
; endp
先看下面这一步。
00000000000618c0 mov rsi, qword [0x2c11d8] ; @selector(stringWithFormat:), argument "selector" for method _objc_msgSend
00000000000618c7 lea rdx, qword [cfstring______27de28] ; @"%@%@"
00000000000618ce xor eax, eax
00000000000618d0 mov rdi, r14 ; argument "instance" for method _objc_msgSend
00000000000618d3 mov rcx, r15
00000000000618d6 mov r8, qword [rbp+var_40]
00000000000618da call rbx ; _objc_msgSend
00000000000618dc mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
00000000000618df call imp___stubs__objc_retainAutoreleasedReturnValue
00000000000618e4 mov r14, rax
00000000000618e7 mov qword [rbp+var_50], r14
00000000000618eb mov rdi, r15 ; argument "instance" for method _objc_release
00000000000618ee call r12 ; _objc_release
00000000000618f1 mov rdi, qword [objc_cls_ref_HSLicense] ; argument "instance" for method _objc_msgSend
00000000000618f8 mov rsi, qword [0x2c3c28] ; @selector(MD5String:), argument "selector" for method _objc_msgSend
00000000000618ff mov rdx, r14
0000000000061902 call rbx ; _objc_msgSend
此段代码将输入的邮箱和SecretKey拼接,然后进行MD5加密。也就是MD5加盐(MD5+Salt,增强MD5安全)。接着,有如下代码。
loc_6199e:
000000000006199e mov rdi, qword [objc_cls_ref_HSLicense] ; argument "instance" for method _objc_msgSend, CODE XREF=-[HSLicense licenseForEmailAddress:withSecret:]+573
00000000000619a5 mov rsi, qword [0x2c3c30] ; @selector(hyphonate:everyX:), argument "selector" for method _objc_msgSend
00000000000619ac mov ecx, 0x6
00000000000619b1 mov rdx, qword [rbp+var_30]
00000000000619b5 call rbx ; _objc_msgSend
00000000000619b7 mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
00000000000619ba call imp___stubs__objc_retainAutoreleasedReturnValue
00000000000619bf mov r14, rax
00000000000619c2 mov rsi, qword [0x2c3c38] ; @selector(rangeOfString:options:), argument "selector" for method _objc_msgSend
00000000000619c9 lea rdx, qword [cfstring___279de8] ; @"-"
00000000000619d0 mov ecx, 0x4
00000000000619d5 mov rdi, r14 ; argument "instance" for method _objc_msgSend
00000000000619d8 call rbx ; _objc_msgSend
00000000000619da mov rsi, qword [0x2c1518] ; @selector(substringToIndex:), argument "selector" for method _objc_msgSend
00000000000619e1 mov rdi, r14 ; argument "instance" for method _objc_msgSend
00000000000619e4 mov rdx, rax
00000000000619e7 call rbx ; _objc_msgSend
00000000000619e9 mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
00000000000619ec call imp___stubs__objc_retainAutoreleasedReturnValue
00000000000619f1 mov r15, rax
00000000000619f4 mov rdi, r14 ; argument "instance" for method _objc_release
00000000000619f7 mov r12, qword [_objc_release_25b2f8]
00000000000619fe call r12 ; _objc_release
0000000000061a01 mov rsi, qword [0x2c1488] ; @selector(uppercaseString), argument "selector" for method _objc_msgSend
0000000000061a08 mov rdi, r15 ; argument "instance" for method _objc_msgSend
0000000000061a0b call rbx ; _objc_msgSend
0000000000061a0d mov rdi, rax ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
0000000000061a10 call imp___stubs__objc_retainAutoreleasedReturnValue
0000000000061a15 mov r14, rax
0000000000061a18 mov rdi, r15 ; argument "instance" for method _objc_release
0000000000061a1b call r12 ; _objc_release
0000000000061a1e mov rdi, qword [rbp+var_30] ; argument "instance" for method _objc_release
0000000000061a22 call r12 ; _objc_release
0000000000061a25 mov rdi, r13 ; argument "instance" for method _objc_release
0000000000061a28 call r12 ; _objc_release
0000000000061a2b mov rdi, qword [rbp+var_50] ; argument "instance" for method _objc_release
0000000000061a2f call r12 ; _objc_release
0000000000061a32 mov rdi, qword [rbp+var_40] ; argument "instance" for method _objc_release
0000000000061a36 call r12 ; _objc_release
0000000000061a39 mov rdi, qword [rbp+var_48] ; argument "instance" for method _objc_release
0000000000061a3d call r12 ; _objc_release
0000000000061a40 mov rdi, r14 ; argument "instance" for method imp___stubs__objc_autoreleaseReturnValue
0000000000061a43 add rsp, 0x38
0000000000061a47 pop rbx
0000000000061a48 pop r12
0000000000061a4a pop r13
0000000000061a4c pop r14
0000000000061a4e pop r15
0000000000061a50 pop rbp
0000000000061a51 jmp imp___stubs__objc_autoreleaseReturnValue
; endp
此段代码调用hyphonate:everyX:函数,将加密后的32位MD5字符串,截取前面30位,然后分割成5段,用“-”连接起来,并转大写uppercaseString,作为最终的Serial。
0x2 Keygen
由以上分析,得到Keygen算法描述。
1.A = MD5(email+secretkey)
2.B = A.subStringWithRange(0,30);
3.Serial = B.splitWithLength(6).jointBy("-")
设输入的email 为:xx@qq.com(这里隐去了SecretKey),则MD5字符串为:
B9D3C9816381FC5AA075B626C7564D01,
前30位子串为:
B9D3C9816381FC5AA075B626C7564D
分割成5段得到序列号为:
B9D3C9-816381-FC5AA0-75B626-C7564D