Sidekick, formerly NetworkLocation, is an application that allows you to configure various network parameters based on your location. Sidekick is a simple glue between OSX's built-in location services and the ability to trigger system actions. The application costs USD29 and is a competitor to MarcoPolo.
Since the application extensively uses the _LicenseIsValid
method to determine whether we are in demo mode or not, this single entry-point can be easily subverted by manipulating the outcome. A more elegant way, perhaps, would be to attack the _LicenseIsValid
method itself. However, since we want to only manipulate flow control, we will be modifying the branching after the outcome (the postcondition) of _LicenseIsValid
.
The following functions can be patched in order to turn Sidekick into a registered application:
methImpl_SKWindow_SK_customInit
methImpl_SKWindow_setTitle_
methImpl_SKRegistrationWindowController_trialPeriod
methImpl_SKStatusItemController_populateLocationsInMenu_
methImpl_SKDemo_displayNoticeAndQuit
methImpl_SKDemo_tick_
methImpl_static_SKDemo_demo
methImpl_SKWindow_SK_customInit: 00000001000375d2 55 push rbp 00000001000375d3 4889E5 mov rbp, rsp 00000001000375d6 4157 push r15 ;... 00000001000376dc E86B63FDFF call _LicenseIsValid 00000001000376e1 4885C0 test rax, rax 00000001000376e4 90 nop 00000001000376e5 90 nop 00000001000376e6 488B35A3690500 mov rsi, qword [ds:objc_sel_defaultCenter] ; @selector(defaultCenter) 00000001000376ed 488B3D6C940500 mov rdi, qword [ds:bind__OBJC_CLASS_$_NSNotificationCenter] 00000001000376f4 41FFD4 call r12 00000001000376f7 4889C7 mov rdi, rax 00000001000376fa E893840100 call imp___stubs__objc_retainAutoreleasedReturnValue 00000001000376ff 4989C6 mov r14, rax 0000000100037702 488B3597690500 mov rsi, qword [ds:objc_sel_addObserver_selector_name_object_] ; @selector(addObserver:selector:name:object:) 0000000100037709 488B0D58890500 mov rcx, qword [ds:objc_sel__licensedInstalled_] ; @selector(_licensedInstalled:) 0000000100037710 4C8D0531D10500 lea r8, qword [ds:cfstring_SK_LICENSE_INSTALLED] ; @"SK_LICENSE_INSTALLED"
methImpl_SKWindow_setTitle_: 000000010003739b 55 push rbp 000000010003739c 4889E5 mov rbp, rsp 000000010003739f 4157 push r15 ;... 00000001000373e5 E86266FDFF call _LicenseIsValid 00000001000373ea 4885C0 test rax, rax 00000001000373ed 4989DC mov r12, rbx 00000001000373f0 E999010000 jmp 0x10003758e 00000001000373f5 90 nop 00000001000373f6 48895DB8 mov qword [ss:rbp+0xffffffffffffffb8], rbx 00000001000373fa 4C897DC0 mov qword [ss:rbp+0xffffffffffffffc0], r15 00000001000373fe 488B351B6D0500 mov rsi, qword [ds:objc_sel_demo] ; @selector(demo) 0000000100037405 488B3D84970500 mov rdi, qword [ds:objc_classref_SKDemo] 000000010003740c 4C8B3DDDED0300 mov r15, qword [ds:imp___got__objc_msgSend] ;...
methImpl_SKRegistrationWindowController_trialPeriod: 0000000100036c39 55 push rbp 0000000100036c3a 4889E5 mov rbp, rsp ;... 0000000100036c49 E8FE6DFDFF call _LicenseIsValid 0000000100036c4e 31DB xor ebx, ebx 0000000100036c50 4885C0 test rax, rax 0000000100036c53 E962010000 jmp 0x100036dba 0000000100036c58 90 nop 0000000100036c59 488B35C0740500 mov rsi, qword [ds:objc_sel_demo] ; @selector(demo) 0000000100036c60 488B3D299F0500 mov rdi, qword [ds:objc_classref_SKDemo] 0000000100036c67 4C8B3582F50300 mov r14, qword [ds:imp___got__objc_msgSend]
methImpl_SKStatusItemController_populateLocationsInMenu_: 00000001000095e4 55 push rbp 00000001000095e5 4889E5 mov rbp, rsp 00000001000095e8 4157 push r15 00000001000095ea 4156 push r14 ; ... 0000000100009622 E825440000 call _LicenseIsValid 0000000100009627 4885C0 test rax, rax 000000010000962a E9DF000000 jmp 0x10000970e 000000010000962f 90 nop ;...
methImpl_SKDemo_displayNoticeAndQuit: 000000010000579d 55 push rbp 000000010000579e 4889E5 mov rbp, rsp ;... 00000001000057b3 E894820000 call _LicenseIsValid 00000001000057b8 4885C0 test rax, rax 00000001000057bb 90 nop 00000001000057bc 90 nop 00000001000057bd 488B35648B0800 mov rsi, qword [ds:objc_sel_destroy] ; @selector(destroy) 00000001000057c4 4889DF mov rdi, rbx 00000001000057c7 4883C448 add rsp, 0x48 00000001000057cb 5B pop rbx 00000001000057cc 415C pop r12 00000001000057ce 415D pop r13 00000001000057d0 415E pop r14 00000001000057d2 415F pop r15 00000001000057d4 5D pop rbp 00000001000057d5 FF25150A0700 jmp qword [ds:imp___got__objc_msgSend] 00000001000057db 48895DD0 mov qword [ss:rbp+0xffffffffffffffd0], rbx ; XREF=0x1000057bb 00000001000057df 488B05E2B30800 mov rax, qword [ds:bind__OBJC_CLASS_$_NSAlert] 00000001000057e6 488945B8 mov qword [ss:rbp+0xffffffffffffffb8], rax 00000001000057ea 488B353F8A0800 mov rsi, qword [ds:objc_sel_mainBundle] ; @selector(mainBundle) 00000001000057f1 488B3DD8B30800 mov rdi, qword [ds:bind__OBJC_CLASS_$_NSBundle] 00000001000057f8 488B1DF1090700 mov rbx, qword [ds:imp___got__objc_msgSend] 00000001000057ff FFD3 call rbx 0000000100005801 4889C7 mov rdi, rax 0000000100005804 E889A30400 call imp___stubs__objc_retainAutoreleasedReturnValue 0000000100005809 488945C0 mov qword [ss:rbp+0xffffffffffffffc0], rax 000000010000580d 488B35248A0800 mov rsi, qword [ds:objc_sel_localizedStringForKey_value_table_] ; @selector(localizedStringForKey:value:table:) 0000000100005814 488D15ADF20800 lea rdx, qword [ds:cfstring_Your_evaluation_period_has_expired] ; @"Your evaluation period has expired" ;...
methImpl_SKDemo_tick_: 0000000100004dc3 55 push rbp 0000000100004dc4 4889E5 mov rbp, rsp ;... 0000000100004de2 E8658C0000 call _LicenseIsValid 0000000100004de7 4885C0 test rax, rax 0000000100004dea 90 nop 0000000100004deb 90 nop 0000000100004dec 488B352D950800 mov rsi, qword [ds:objc_sel_invalidate] ; @selector(invalidate) 0000000100004df3 488B1DF6130700 mov rbx, qword [ds:imp___got__objc_msgSend] 0000000100004dfa 4C89F7 mov rdi, r14 0000000100004dfd FFD3 call rbx 0000000100004dff 488B3522950800 mov rsi, qword [ds:objc_sel_destroy] ; @selector(destroy) 0000000100004e06 4C89FF mov rdi, r15 0000000100004e09 FFD3 call rbx 0000000100004e0b EB75 jmp 0x100004e82 0000000100004e0d 4C8B2DE4ED0800 mov r13, qword [ds:_OBJC_IVAR_$_SKDemo.demoPeriod] ; XREF=0x100004dea 0000000100004e14 43FE0C2F dec byte [ds:r15+r13] ;...
methImpl_static_SKDemo_demo: 0000000100004bf9 55 push rbp 0000000100004bfa 4889E5 mov rbp, rsp 0000000100004bfd 53 push rbx 0000000100004bfe 50 push rax 0000000100004bff 4889FB mov rbx, rdi 0000000100004c02 48833D064E090000 cmp qword [ds:_demo], 0x0 0000000100004c0a 7530 jne 0x100004c3c 0000000100004c0c 30C0 xor al, al 0000000100004c0e E8398E0000 call _LicenseIsValid 0000000100004c13 4885C0 test rax, rax 0000000100004c16 E921000000 jmp 0x100004c3c ;...
In order to better understand this, all the patched functions rely on a branching sequence similar to:
call _LicenseIsValid test rax, rax jne 0x100004c3c
where either a jne
or je
is performed depending on the outcome of _LicenseIsValid
. We thus patch the functions by altering the jne
or je
(either by nop-ing or forcibly jumping using jmp
) in order to avoid entering the "demo" related parts of the assembly.