Glow for FB
is an AppStore program that hooks into the OSX Notification system (Mountain Lion onward) and notifies you of events on your facebook account. The only check is obviously the receipt
file from the AppStore, given that this application does not even have a trial.
Cracking Glow thus involves jumping over all the possible error messages that check the receipt
of the application. The function that performs these checks can be found about 0x10001be18
and starts like this:
; Basic Block Input Regs: rbx rbp rsi rdi r12 r13 r14 r15 - Killed Regs: rax rdx rbx rsp rbp rsi rdi r12 r14 r15 000000010001be18 55 push rbp ; XREF=0x100008633 000000010001be19 4889E5 mov rbp, rsp 000000010001be1c 4157 push r15 000000010001be1e 4156 push r14 000000010001be20 4155 push r13 000000010001be22 4154 push r12 000000010001be24 53 push rbx 000000010001be25 4881ECA8000000 sub rsp, 0xa8 000000010001be2c 4989F7 mov r15, rsi 000000010001be2f 4189FC mov r12d, edi 000000010001be32 488B0557420100 mov rax, qword [ds:imp___got____stack_chk_guard] 000000010001be39 488B00 mov rax, qword [ds:rax] 000000010001be3c 488945D0 mov qword [ss:rbp-0x0+var_m48], rax 000000010001be40 488B3521F90100 mov rsi, qword [ds:objc_sel_mainBundle] ; @selector(mainBundle) 000000010001be47 488B3D0A090200 mov rdi, qword [ds:bind__OBJC_CLASS_$_NSBundle] 000000010001be4e FF158C420100 call qword [ds:imp___got__objc_msgSend] 000000010001be54 4889C7 mov rdi, rax 000000010001be57 E854210000 call imp___stubs__objc_retainAutoreleasedReturnValue 000000010001be5c 4889C3 mov rbx, rax 000000010001be5f 488D35FA060200 lea rsi, qword [ds:objc_msg_respondsToSelector_] ; @selector(respondsToSelector:) 000000010001be66 488B1503060200 mov rdx, qword [ds:objc_sel_appStoreReceiptURL] ; @selector(appStoreReceiptURL) 000000010001be6d 4889DF mov rdi, rbx 000000010001be70 FF15EA060200 call qword [ds:objc_msg_respondsToSelector_] ; @selector(respondsToSelector:) 000000010001be76 4188C6 mov r14L, al 000000010001be79 4889DF mov rdi, rbx 000000010001be7c E817210000 call imp___stubs__objc_release 000000010001be81 4584F6 test r14L, r14L ...
Browsing the function you will observe that you will have instances where versious checks are performed to determine whether the receipt
is legitimate. All these checks have to be skipped; jumped over by turing je
s, jne
s, and so on into jumps. For example, the first instance where a jump is necessary is right after the function starts:
... 000000010001bf18 E924000000 jmp 0x10001bf41 000000010001bf1d 90 nop 000000010001bf1e 90 nop 000000010001bf1f 90 nop 000000010001bf20 90 nop 000000010001bf21 488B3D70090200 mov rdi, qword [ds:bind__OBJC_CLASS_$_NSException] 000000010001bf28 488D15D1530200 lea rdx, qword [ds:cfstring_MacAppStore_Receipt_Validation_Error] ; @"MacAppStore Receipt Validation Error" 000000010001bf2f 488D0D0A570200 lea rcx, qword [ds:cfstring_Failed_to_check_bundle_ID_] ; @"Failed to check bundle ID." 000000010001bf36 4531C0 xor r8d, r8d 000000010001bf39 30C0 xor al, al 000000010001bf3b FF159F410100 call qword [ds:imp___got__objc_msgSend] ..
The jump at 0x10001bf18
skips the validation error and lets the program carry on. The next instance is then:
... 000000010001bff5 E924000000 jmp 0x10001c01e 000000010001bffa 90 nop 000000010001bffb 90 nop 000000010001bffc 90 nop 000000010001bffd 90 nop 000000010001bffe 488B3D93080200 mov rdi, qword [ds:bind__OBJC_CLASS_$_NSException] 000000010001c005 488D15F4520200 lea rdx, qword [ds:cfstring_MacAppStore_Receipt_Validation_Error] ; @"MacAppStore Receipt Validation Error" 000000010001c00c 488D0D8D550200 lea rcx, qword [ds:cfstring_Failed_to_validate_bundle_signature__Create_a_static_code] ; @"Failed to validate bundle signature: Create a static code" 000000010001c013 4531C0 xor r8d, r8d 000000010001c016 30C0 xor al, al 000000010001c018 FF15C2400100 call qword [ds:imp___got__objc_msgSend] ...
Then the next:
... 000000010001c040 E935000000 jmp 0x10001c07a 000000010001c045 90 nop 000000010001c046 90 nop 000000010001c047 90 nop 000000010001c048 90 nop 000000010001c049 4885FF test rdi, rdi 000000010001c04c 7405 je 0x10001c053 000000010001c04e E8E71F0000 call imp___stubs__CFRelease 000000010001c053 488B3526040200 mov rsi, qword [ds:objc_sel_raise_format_] ; @selector(raise:format:) XREF=0x10001c04c 000000010001c05a 488B3D37080200 mov rdi, qword [ds:bind__OBJC_CLASS_$_NSException] 000000010001c061 488D1598520200 lea rdx, qword [ds:cfstring_MacAppStore_Receipt_Validation_Error] ; @"MacAppStore Receipt Validation Error" 000000010001c068 488D0D71550200 lea rcx, qword [ds:cfstring_Failed_to_validate_bundle_signature__Create_a_requirement] ; @"Failed to validate bundle signature: Create a requirement" 000000010001c06f 4531C0 xor r8d, r8d 000000010001c072 30C0 xor al, al 000000010001c074 FF1566400100 call qword [ds:imp___got__objc_msgSend] ...
and this carries on for quite a while, up to the last required sequence:
... 000000010001c8a5 E924000000 jmp 0x10001c8ce 000000010001c8aa 90 nop 000000010001c8ab 90 nop 000000010001c8ac 90 nop 000000010001c8ad 90 nop 000000010001c8ae 488B3DE3FF0100 mov rdi, qword [ds:bind__OBJC_CLASS_$_NSException] 000000010001c8b5 488D15444A0200 lea rdx, qword [ds:cfstring_MacAppStore_Receipt_Validation_Error] ; @"MacAppStore Receipt Validation Error" 000000010001c8bc 488D0D7D4A0200 lea rcx, qword [ds:cfstring_Failed_to_check_receipt_hash_] ; @"Failed to check receipt hash." 000000010001c8c3 4531C0 xor r8d, r8d 000000010001c8c6 30C0 xor al, al 000000010001c8c8 FF1512380100 call qword [ds:imp___got__objc_msgSend] ...
The last jne
before the function returns can be left alone:
... 000000010001c948 7573 jne 0x10001c9bd ; Basic Block Input Regs: rbx - Killed Regs: rax rbx rsp rbp r12 r13 r14 r15 000000010001c94a 89D8 mov eax, ebx 000000010001c94c 4881C4A8000000 add rsp, 0xa8 000000010001c953 5B pop rbx 000000010001c954 415C pop r12 000000010001c956 415D pop r13 000000010001c958 415E pop r14 000000010001c95a 415F pop r15 000000010001c95c 5D pop rbp 000000010001c95d C3 ret ...
There are quite a few of these steps, just remember than given the top-down execution, the function must avoid those error sequences and carry on till it reaches the ret
.
That is it for Glow for FB
at version 1.0.7
.