本文练习CrackeMe下载链接如下:https://reverse.put.as/wp-content/uploads/2010/08/Pie.zip。来自MacSerialJunkies 2010 Contest。
所以分析破解起来还是有点难度。
运行截图如下。
0x1代码静态分析
Hopper中打开Pie,可以看到如下代码。
; ================ B E G I N N I N G O F P R O C E D U R E ================
; Variables:
; var_8: -8
; var_10: -16
; var_18: -24
; var_20: -32
; var_28: -40
-[PieAppDelegate serialFieldDidChange]:
0000000100001061 push rbp ; Objective C Implementation defined at 0x1000025d8 (instance method), DATA XREF=0x1000025d8
0000000100001062 mov rbp, rsp
0000000100001065 mov qword [rbp+var_28], rbx
0000000100001069 mov qword [rbp+var_20], r12
000000010000106d mov qword [rbp+var_18], r13
0000000100001071 mov qword [rbp+var_10], r14
0000000100001075 mov qword [rbp+var_8], r15
0000000100001079 sub rsp, 0x30
000000010000107d mov r13, rdi
0000000100001080 mov rdi, qword [objc_cls_ref_NSUserDefaults] ; argument "instance" for method _objc_msgSend_fixup
0000000100001087 lea rsi, qword [0x100002208] ; @selector(standardUserDefaults), argument "selector" for method _objc_msgSend_fixup
000000010000108e call qword [0x100002208] ; @selector(standardUserDefaults),_objc_msgSend_fixup
0000000100001094 mov r15, rax
0000000100001097 lea r14, qword [0x1000022a8] ; @selector(setObject:forKey:)
000000010000109e mov r12, qword [0x1000022a8] ; @selector(setObject:forKey:)
00000001000010a5 mov rax, qword [objc_ivar_offset_PieAppDelegate_nameField]
00000001000010ac mov rdi, qword [r13+rax] ; argument "instance" for method _objc_msgSend_fixup
00000001000010b1 lea rbx, qword [0x100002258] ; @selector(stringValue)
00000001000010b8 mov rsi, rbx ; argument "selector" for method _objc_msgSend_fixup
00000001000010bb call qword [0x100002258] ; @selector(stringValue),_objc_msgSend_fixup
00000001000010c1 lea rcx, qword [cfstring_name] ; @"name"
00000001000010c8 mov rdx, rax
00000001000010cb mov rsi, r14 ; argument "selector" for method _objc_msgSend_fixup
00000001000010ce mov rdi, r15 ; argument "instance" for method _objc_msgSend_fixup
00000001000010d1 call r12 ; _objc_msgSend_fixup
00000001000010d4 mov r12, qword [0x1000022a8] ; @selector(setObject:forKey:)
00000001000010db mov rax, qword [objc_ivar_offset_PieAppDelegate_serialField]
00000001000010e2 mov rdi, qword [r13+rax] ; argument "instance" for method _objc_msgSend_fixup
00000001000010e7 mov rsi, rbx ; argument "selector" for method _objc_msgSend_fixup
00000001000010ea call qword [0x100002258] ; @selector(stringValue),_objc_msgSend_fixup
00000001000010f0 lea rcx, qword [cfstring_serial] ; @"serial"
00000001000010f7 mov rdx, rax
00000001000010fa mov rsi, r14 ; argument "selector" for method _objc_msgSend_fixup
00000001000010fd mov rdi, r15 ; argument "instance" for method _objc_msgSend_fixup
0000000100001100 call r12 ; _objc_msgSend_fixup
0000000100001103 mov r14, qword [0x100002268] ; @selector(verifySerial:andName:)
000000010000110a mov rax, qword [objc_ivar_offset_PieAppDelegate_nameField]
0000000100001111 mov rdi, qword [r13+rax] ; argument "instance" for method _objc_msgSend_fixup
0000000100001116 mov rsi, rbx ; argument "selector" for method _objc_msgSend_fixup
0000000100001119 call qword [0x100002258] ; @selector(stringValue),_objc_msgSend_fixup
000000010000111f mov r12, rax
0000000100001122 mov rax, qword [objc_ivar_offset_PieAppDelegate_serialField]
0000000100001129 mov rdi, qword [r13+rax] ; argument "instance" for method _objc_msgSend_fixup
000000010000112e mov rsi, rbx ; argument "selector" for method _objc_msgSend_fixup
0000000100001131 call qword [0x100002258] ; @selector(stringValue),_objc_msgSend_fixup
0000000100001137 mov rcx, r12
000000010000113a mov rdx, rax
000000010000113d lea rsi, qword [0x100002268] ; @selector(verifySerial:andName:), argument "selector" for method _objc_msgSend_fixup
0000000100001144 mov rdi, r13 ; argument "instance" for method _objc_msgSend_fixup
0000000100001147 mov r11, r14
000000010000114a mov rbx, qword [rbp+var_28]
000000010000114e mov r12, qword [rbp+var_20]
0000000100001152 mov r13, qword [rbp+var_18]
0000000100001156 mov r14, qword [rbp+var_10]
000000010000115a mov r15, qword [rbp+var_8]
000000010000115e leave
000000010000115f jmp r11 ; _objc_msgSend_fixup
; endp
[PieAppDelegate serialFieldDidChange]方法监听输入serial的变化,然后 调用[PieAppDelegate verifySerial:andName:]进行检验。所以真正校验的方法在 -[PieAppDelegate verifySerial:andName:]。代码如下。
; ================ B E G I N N I N G O F P R O C E D U R E ================
; Variables:
; var_8: -8
; var_10: -16
; var_18: -24
; var_20: -32
; var_28: -40
; var_38: -56
; var_40: -64
; var_48: -72
; var_50: -80
; var_58: -88
; var_60: -96
; var_70: -112
; var_78: -120
; var_80: -128
; var_88: -136
; var_90: -144
; var_98: -152
; var_A0: -160
; var_A8: -168
; var_B0: -176
; var_B8: -184
; var_C0: -192
; var_C8: -200
; var_D0: -208
-[PieAppDelegate verifySerial:andName:]:
0000000100001342 push rbp ; Objective C Implementation defined at 0x1000025c0 (instance method), DATA XREF=0x1000025c0
0000000100001343 mov rbp, rsp
0000000100001346 mov qword [rbp+var_28], rbx
000000010000134a mov qword [rbp+var_20], r12
000000010000134e mov qword [rbp+var_18], r13
0000000100001352 mov qword [rbp+var_10], r14
0000000100001356 mov qword [rbp+var_8], r15
000000010000135a sub rsp, 0xd0
0000000100001361 mov qword [rbp+var_60], rdi
0000000100001365 mov r13, rdx
0000000100001368 mov r14, rcx
000000010000136b mov rdi, qword [0x100002768] ; argument "instance" for method _objc_msgSend_fixup
0000000100001372 mov edx, 0x4
0000000100001377 lea rsi, qword [0x1000022b8] ; @selector(dataUsingEncoding:), argument "selector" for method _objc_msgSend_fixup
000000010000137e call qword [0x1000022b8] ; @selector(dataUsingEncoding:),_objc_msgSend_fixup
0000000100001384 mov r15, rax
0000000100001387 lea rsi, qword [0x1000022c8] ; @selector(length), argument "selector" for method _objc_msgSend_fixup
000000010000138e mov rdi, r13 ; argument "instance" for method _objc_msgSend_fixup
0000000100001391 call qword [0x1000022c8] ; @selector(length),_objc_msgSend_fixup
0000000100001397 cmp rax, 0x10
000000010000139b jne loc_100001666
00000001000013a1 mov edx, 0x6
00000001000013a6 lea rsi, qword [0x1000022d8] ; @selector(substringToIndex:), argument "selector" for method _objc_msgSend_fixup
00000001000013ad mov rdi, r13 ; argument "instance" for method _objc_msgSend_fixup
00000001000013b0 call qword [0x1000022d8] ; @selector(substringToIndex:),_objc_msgSend_fixup
00000001000013b6 mov rdi, rax ; argument "instance" for method _objc_msgSend_fixup
00000001000013b9 mov edx, 0x4
00000001000013be lea rsi, qword [0x1000022b8] ; @selector(dataUsingEncoding:), argument "selector" for method _objc_msgSend_fixup
00000001000013c5 call qword [0x1000022b8] ; @selector(dataUsingEncoding:),_objc_msgSend_fixup
00000001000013cb mov rbx, rax
00000001000013ce lea rsi, qword [0x1000022c8] ; @selector(length), argument "selector" for method _objc_msgSend_fixup
00000001000013d5 mov rdi, rax ; argument "instance" for method _objc_msgSend_fixup
00000001000013d8 call qword [0x1000022c8] ; @selector(length),_objc_msgSend_fixup
00000001000013de mov r12, rax
00000001000013e1 lea rsi, qword [0x1000022e8] ; @selector(bytes), argument "selector" for method _objc_msgSend_fixup
00000001000013e8 mov rdi, rbx ; argument "instance" for method _objc_msgSend_fixup
00000001000013eb call qword [0x1000022e8] ; @selector(bytes),_objc_msgSend_fixup
00000001000013f1 mov rdi, rax ; argument "d" for method imp___symbol_stub1__MD5
00000001000013f4 xor edx, edx ; argument "md" for method imp___symbol_stub1__MD5
00000001000013f6 mov rsi, r12 ; argument "n" for method imp___symbol_stub1__MD5
00000001000013f9 call imp___symbol_stub1__MD5
00000001000013fe mov rdx, qword [objc_cls_ref_NSString]
0000000100001405 mov qword [rbp+var_58], rdx
0000000100001409 movzx r9d, byte [rax+2]
000000010000140e movzx r8d, byte [rax+1]
0000000100001413 movzx ecx, byte [rax]
0000000100001416 movzx edx, byte [rax+0xf]
000000010000141a mov dword [rsp+0xd0+var_70], edx
000000010000141e movzx edx, byte [rax+0xe]
0000000100001422 mov dword [rsp+0xd0+var_78], edx
0000000100001426 movzx edx, byte [rax+0xd]
000000010000142a mov dword [rsp+0xd0+var_80], edx
000000010000142e movzx edx, byte [rax+0xc]
0000000100001432 mov dword [rsp+0xd0+var_88], edx
0000000100001436 movzx edx, byte [rax+0xb]
000000010000143a mov dword [rsp+0xd0+var_90], edx
000000010000143e movzx edx, byte [rax+0xa]
0000000100001442 mov dword [rsp+0xd0+var_98], edx
0000000100001446 movzx edx, byte [rax+9]
000000010000144a mov dword [rsp+0xd0+var_A0], edx
000000010000144e movzx edx, byte [rax+8]
0000000100001452 mov dword [rsp+0xd0+var_A8], edx
0000000100001456 movzx edx, byte [rax+7]
000000010000145a mov dword [rsp+0xd0+var_B0], edx
000000010000145e movzx edx, byte [rax+6]
0000000100001462 mov dword [rsp+0xd0+var_B8], edx
0000000100001466 movzx edx, byte [rax+5]
000000010000146a mov dword [rsp+0xd0+var_C0], edx
000000010000146e movzx edx, byte [rax+4]
0000000100001472 mov dword [rsp+0xd0+var_C8], edx
0000000100001476 movzx eax, byte [rax+3]
000000010000147a mov dword [rsp+0xd0+var_D0], eax
000000010000147d lea rdx, qword [cfstring__02X_02X_02X_02X_02X_02X_02X_02X_02X_02X_02X_02X_02X_02X_02X_02X] ; @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
0000000100001484 lea rsi, qword [0x1000022f8] ; @selector(stringWithFormat:), argument "selector" for method _objc_msgSend_fixup
000000010000148b mov rdi, qword [rbp+var_58] ; argument "instance" for method _objc_msgSend_fixup
000000010000148f xor eax, eax
0000000100001491 call qword [0x1000022f8] ; @selector(stringWithFormat:),_objc_msgSend_fixup
0000000100001497 mov rdi, rax ; argument "instance" for method _objc_msgSend_fixup
000000010000149a mov rdx, qword [0x100002770]
00000001000014a1 lea rsi, qword [0x100002308] ; @selector(isEqualToString:), argument "selector" for method _objc_msgSend_fixup
00000001000014a8 call qword [0x100002308] ; @selector(isEqualToString:),_objc_msgSend_fixup
00000001000014ae test al, al
00000001000014b0 je loc_100001666
00000001000014b6 mov edx, 0xd
00000001000014bb lea rsi, qword [0x100002318] ; @selector(characterAtIndex:), argument "selector" for method _objc_msgSend_fixup
00000001000014c2 mov rdi, r13 ; argument "instance" for method _objc_msgSend_fixup
00000001000014c5 call qword [0x100002318] ; @selector(characterAtIndex:),_objc_msgSend_fixup
00000001000014cb cmp ax, 0x46
00000001000014cf jne loc_100001666
00000001000014d5 mov edx, 0x4
00000001000014da lea rsi, qword [0x1000022b8] ; @selector(dataUsingEncoding:), argument "selector" for method _objc_msgSend_fixup
00000001000014e1 mov rdi, r14 ; argument "instance" for method _objc_msgSend_fixup
00000001000014e4 call qword [0x1000022b8] ; @selector(dataUsingEncoding:),_objc_msgSend_fixup
00000001000014ea mov rbx, rax
00000001000014ed lea rsi, qword [0x1000022c8] ; @selector(length), argument "selector" for method _objc_msgSend_fixup
00000001000014f4 mov rdi, rax ; argument "instance" for method _objc_msgSend_fixup
00000001000014f7 call qword [0x1000022c8] ; @selector(length),_objc_msgSend_fixup
00000001000014fd mov r12, rax
0000000100001500 lea rsi, qword [0x1000022e8] ; @selector(bytes), argument "selector" for method _objc_msgSend_fixup
0000000100001507 mov rdi, rbx ; argument "instance" for method _objc_msgSend_fixup
000000010000150a call qword [0x1000022e8] ; @selector(bytes),_objc_msgSend_fixup
0000000100001510 mov rdi, rax ; argument "d" for method imp___symbol_stub1__MD5
0000000100001513 xor edx, edx ; argument "md" for method imp___symbol_stub1__MD5
0000000100001515 mov rsi, r12 ; argument "n" for method imp___symbol_stub1__MD5
0000000100001518 call imp___symbol_stub1__MD5
000000010000151d movzx r9d, byte [rax+2]
0000000100001522 movzx r8d, byte [rax+1]
0000000100001527 movzx ecx, byte [rax]
000000010000152a movzx edx, byte [rax+7]
000000010000152e mov dword [rsp+0xd0+var_B0], edx
0000000100001532 movzx edx, byte [rax+6]
0000000100001536 mov dword [rsp+0xd0+var_B8], edx
000000010000153a movzx edx, byte [rax+5]
000000010000153e mov dword [rsp+0xd0+var_C0], edx
0000000100001542 movzx edx, byte [rax+4]
0000000100001546 mov dword [rsp+0xd0+var_C8], edx
000000010000154a movzx eax, byte [rax+3]
000000010000154e mov dword [rsp+0xd0+var_D0], eax
0000000100001551 lea rdx, qword [cfstring__02X_02X_02X_02X_02X_02X_02X] ; @"%02X%02X%02X%02X%02X%02X%02X"
0000000100001558 lea rsi, qword [0x1000022f8] ; @selector(stringWithFormat:), argument "selector" for method _objc_msgSend_fixup
000000010000155f mov rdi, qword [rbp+var_58] ; argument "instance" for method _objc_msgSend_fixup
0000000100001563 xor eax, eax
0000000100001565 call qword [0x1000022f8] ; @selector(stringWithFormat:),_objc_msgSend_fixup
000000010000156b mov rdi, rax ; argument "instance" for method _objc_msgSend_fixup
000000010000156e mov edx, 0x7
0000000100001573 lea rsi, qword [0x1000022d8] ; @selector(substringToIndex:), argument "selector" for method _objc_msgSend_fixup
000000010000157a call qword [0x1000022d8] ; @selector(substringToIndex:),_objc_msgSend_fixup
0000000100001580 mov rbx, rax
0000000100001583 mov qword [rbp+var_38], 0x7
000000010000158b mov qword [rbp+var_40], 0x6
0000000100001593 mov edx, 0x6
0000000100001598 mov ecx, 0x7
000000010000159d lea rsi, qword [0x100002328] ; @selector(substringWithRange:), argument "selector" for method _objc_msgSend_fixup
00000001000015a4 mov rdi, r13 ; argument "instance" for method _objc_msgSend_fixup
00000001000015a7 call qword [0x100002328] ; @selector(substringWithRange:),_objc_msgSend_fixup
00000001000015ad mov rdi, rax ; argument "instance" for method _objc_msgSend_fixup
00000001000015b0 mov rdx, rbx
00000001000015b3 lea rsi, qword [0x100002308] ; @selector(isEqualToString:), argument "selector" for method _objc_msgSend_fixup
00000001000015ba call qword [0x100002308] ; @selector(isEqualToString:),_objc_msgSend_fixup
00000001000015c0 test al, al
00000001000015c2 je loc_100001666
00000001000015c8 mov qword [rbp+var_48], 0x2
00000001000015d0 mov qword [rbp+var_50], 0xe
00000001000015d8 mov edx, 0xe
00000001000015dd mov ecx, 0x2
00000001000015e2 lea rsi, qword [0x100002328] ; @selector(substringWithRange:), argument "selector" for method _objc_msgSend_fixup
00000001000015e9 mov rdi, r13 ; argument "instance" for method _objc_msgSend_fixup
00000001000015ec call qword [0x100002328] ; @selector(substringWithRange:),_objc_msgSend_fixup
00000001000015f2 mov rdi, rax ; argument "instance" for method _objc_msgSend_fixup
00000001000015f5 mov edx, 0x4
00000001000015fa lea rsi, qword [0x1000022b8] ; @selector(dataUsingEncoding:), argument "selector" for method _objc_msgSend_fixup
0000000100001601 call qword [0x1000022b8] ; @selector(dataUsingEncoding:),_objc_msgSend_fixup
0000000100001607 mov rdi, rax ; argument "instance" for method _objc_msgSend_fixup
000000010000160a mov rdx, r15
000000010000160d lea rsi, qword [0x100002338] ; @selector(isEqualToData:), argument "selector" for method _objc_msgSend_fixup
0000000100001614 call qword [0x100002338] ; @selector(isEqualToData:),_objc_msgSend_fixup
000000010000161a test al, al
000000010000161c je loc_100001666
000000010000161e mov rdi, qword [objc_cls_ref_NSNotificationCenter] ; argument "instance" for method _objc_msgSend_fixup
0000000100001625 lea rsi, qword [0x100002238] ; @selector(defaultCenter), argument "selector" for method _objc_msgSend_fixup
000000010000162c call qword [0x100002238] ; @selector(defaultCenter),_objc_msgSend_fixup
0000000100001632 mov rdi, rax ; argument "instance" for method _objc_msgSend_fixup
0000000100001635 mov rcx, qword [rbp+var_60]
0000000100001639 lea rdx, qword [cfstring_Registered] ; @"Registered"
0000000100001640 lea rsi, qword [0x100002348] ; @selector(postNotificationName:object:), argument "selector" for method _objc_msgSend_fixup
0000000100001647 mov r11, qword [0x100002348] ; @selector(postNotificationName:object:)
000000010000164e mov rbx, qword [rbp+var_28]
0000000100001652 mov r12, qword [rbp+var_20]
0000000100001656 mov r13, qword [rbp+var_18]
000000010000165a mov r14, qword [rbp+var_10]
000000010000165e mov r15, qword [rbp+var_8]
0000000100001662 leave
0000000100001663 jmp r11 ; _objc_msgSend_fixup
; endp
loc_100001666:
0000000100001666 mov rbx, qword [rbp+var_28] ; CODE XREF=-[PieAppDelegate verifySerial:andName:]+89, -[PieAppDelegate verifySerial:andName:]+366, -[PieAppDelegate verifySerial:andName:]+397, -[PieAppDelegate verifySerial:andName:]+640, -[PieAppDelegate verifySerial:andName:]+730
000000010000166a mov r12, qword [rbp+var_20]
000000010000166e mov r13, qword [rbp+var_18]
0000000100001672 mov r14, qword [rbp+var_10]
0000000100001676 mov r15, qword [rbp+var_8]
000000010000167a leave
000000010000167b ret
; endp
在此方法中还引用了两个常量字符@"BC",@"66EAD6FE7CBE7987B7C4B1A1EED0E5A5"。如下。
0000000100002767 db 0x00 ; '.'
0000000100002768 dq 0x0000000100002168 ; @"BC", DATA XREF=-[PieAppDelegate verifySerial:andName:]+41
0000000100002770 dq 0x0000000100002188 ; @"66EAD6FE7CBE7987B7C4B1A1EED0E5A5", DATA XREF=-[PieAppDelegate verifySerial:andName:]+344
0000000100002778 db 0x00 ; '.'
其中,此方法开头有如下引用。得知@“BC”存入了r15。
000000010000136b mov rdi, qword [0x100002768] ; argument "instance" for method _objc_msgSend_fixup
0000000100001372 mov edx, 0x4
0000000100001377 lea rsi, qword [0x1000022b8]
0000000100001384 mov r15, rax
首先,判断Serial的length长度是否是16(0x10)位,如果不是,则失败。如果长度符合,则取Serial前6位进行MD5加密,加密后的字符串截取前7位,和@"66EAD6FE7CBE7987B7C4B1A1EED0E5A5"比较,如果不相等,失败。如果相等,则继续。关键跳转如下。
000000010000149a mov rdx, qword [0x100002770]
00000001000014a1 lea rsi, qword [0x100002308] ; @selector(isEqualToString:), argument "selector" for method _objc_msgSend_fixup
00000001000014a8 call qword [0x100002308] ; @selector(isEqualToString:),_objc_msgSend_fixup
00000001000014ae test al, al
00000001000014b0 je loc_100001666
所以,@"66EAD6FE7CBE7987B7C4B1A1EED0E5A5"反向MD5就得出Serial的前六位。即:KRACK- 。
接下来如下代码,比较Serial的第14位是否与F相等,不相等,则失败。
00000001000014b6 mov edx, 0xd
00000001000014bb lea rsi, qword [0x100002318] ; @selector(characterAtIndex:), argument "selector" for method _objc_msgSend_fixup
00000001000014c2 mov rdi, r13 ; argument "instance" for method _objc_msgSend_fixup
00000001000014c5 call qword [0x100002318] ; @selector(characterAtIndex:),_objc_msgSend_fixup
00000001000014cb cmp ax, 0x46
00000001000014cf jne loc_100001666
后面一大段,将Name进行MD5加密,截取前7位(大写),和Serial的7-13位比较,不相等,则失败。如果相等,最后校验Serial最后的15-16位。
代码如下。
000000010000160a mov rdx, r15
000000010000160d lea rsi, qword [0x100002338] ; @selector(isEqualToData:), argument "selector" for method _objc_msgSend_fixup
0000000100001614 call qword [0x100002338] ; @selector(isEqualToData:),_objc_msgSend_fixup
000000010000161a test al, al
000000010000161c je loc_100001666
此段代码将Serial的后两位与r15相比较。如果相等,则通过。根据上面的分析,r15为BC。所以得出Serial的最后两位为BC。
0x2 Keygen算法
根据上述分析(动态分析过程略),得出Keygen算法如下。
Serial ="KRACK-"+ MD5(Name).upCase().subStringWithRange(0,7)+"FBC"
设Name 为MyTest。则MD5(Name).upCase().subStringWithRange(0,7)为:1A1220A,所以得出Serial为:KRACK-1A1220AFBC。
程序验证,Success。:)!