8 November 2015

  • Updated the patch for Jitouch 2.63 - El Capitan.


As with the previous version, Jitouch 2 consists in two distinct binaries that have to be modified:

  • The first binary belongs to the preference-pane component of Jitouch 2, and can be found in Contents/MacOS/Jitouch. Altering this binary, we can eliminate the register button, turn on an endless demo-mode and clear out any nag screens or artefacts.
  • The second binary belongs to the resident program that runs in the background to process controller events at Contents/Resources/ It also carries the same way, so be careful when replacing the altered binaries.

Removing License Check

The first step is to remove the license check, simply by shorting the methImpl_JitouchPref_checkLicense method by jumping directly from 0x1f7e to 0x212d, thereby skipping everything that the license check does.

                                       ; Basic Block Input Regs: rdi -  Killed Regs: rax rdx rbx rbp rsi rdi
0000000000001f6d 55                              push       rbp
0000000000001f6e 4889E5                          mov        rbp, rsp
0000000000001f71 4157                            push       r15
0000000000001f73 4156                            push       r14
0000000000001f75 4155                            push       r13
0000000000001f77 4154                            push       r12
0000000000001f79 53                              push       rbx
0000000000001f7a 4883EC28                        sub        rsp, 0x28
0000000000001f7e E9A6010000                      jmp        0x2129
0000000000002129 4883C428                        add        rsp, 0x28                     ; XREF=0x1fb0, 0x1f7e
000000000000212d 5B                              pop        rbx
000000000000212e 415C                            pop        r12
0000000000002130 415D                            pop        r13
0000000000002132 415E                            pop        r14
0000000000002134 415F                            pop        r15
0000000000002136 5D                              pop        rbp
0000000000002137 C3                              ret        

Removing Register Button

The jitouch preference pane has a Register tab that gets removed once the license check is passed. The Register button is referenced in two places:

000000000002b8f8                                 dq         0x0000000000000000, 0x00000000000007c8, 0x0000000000022df7, 0x0000000000000008 ; XREF=0x2370, 0x288e
  • 0x2370 is the first reference and is triggered when the user actually registers jitouch. Since we will not be doing that, we can ignore this reference.
  • 0x288e is the second reference and is to be found in the methImpl_JitouchPref_mainViewDidLoad, which we do want to attack.

The method that jitouch uses to hide the Register button is to first check whether jitouch is registered (can be observed from 0x285e to 0x2875) and if jitouch is registered, then the function continues down and calls ds:objc_sel_removeTabViewItem_ in order to remove the Register button. Conversely, if jitouch is not registered, then jitouch jumps over that block. Thus, we nop the jump such that jitouch does proceed in the block in order to remove the button.

; Basic Block Input Regs: rdi -  Killed Regs: rax rcx rdx rbx rsi rdi r8 r9 r12 r14 r15 xmm0
000000000000285e 488B35F3760200                  mov        rsi, qword [ds:objc_sel_checkLicense] ; @selector(checkLicense) XREF=0x27fe
0000000000002865 4C89F7                          mov        rdi, r14
0000000000002868 FF15FA270200                    call       qword [ds:imp___got__objc_msgSend]
000000000000286e 488B05AB890200                  mov        rax, qword [ds:_OBJC_IVAR_$_JitouchPref.license]
0000000000002875 41833C0600                      cmp        dword [ds:r14+rax], 0x0
000000000000287a 90                              nop        
000000000000287b 90                              nop        
                                       ; Basic Block Input Regs: r14 r15 -  Killed Regs: rax rdx rbx rsi rdi
000000000000287c 488B05B5890200                  mov        rax, qword [ds:_OBJC_IVAR_$_JitouchPref.mainTabView]
0000000000002883 498B1C06                        mov        rbx, qword [ds:r14+rax]
0000000000002887 488B35FA760200                  mov        rsi, qword [ds:objc_sel_indexOfTabViewItemWithIdentifier_] ; @selector(indexOfTabViewItemWithIdentifier:)
000000000000288e 488D1563900200                  lea        rdx, qword [ds:cfstring_Register] ; @"Register"
0000000000002895 4889DF                          mov        rdi, rbx
0000000000002898 41FFD7                          call       r15
000000000000289b 488B35EE760200                  mov        rsi, qword [ds:objc_sel_tabViewItemAtIndex_] ; @selector(tabViewItemAtIndex:)
00000000000028a2 4889DF                          mov        rdi, rbx
00000000000028a5 4889C2                          mov        rdx, rax
00000000000028a8 41FFD7                          call       r15
00000000000028ab 488B35E6760200                  mov        rsi, qword [ds:objc_sel_removeTabViewItem_] ; @selector(removeTabViewItem:)
00000000000028b2 4889DF                          mov        rdi, rbx
00000000000028b5 4889C2                          mov        rdx, rax
00000000000028b8 41FFD7                          call       r15

Removing The Time Bomb

The sneaky binary that needs to be edited resides at:


which is the background application that is launched from the preference pane.


The binary contains the expiration function methImpl_JitouchAppDelegate_expire. This method is trigged from _increaseLicenseCounter via obj_sel_expire and can be short-circuited:

000000010000dc8c 55                              push       rbp                           ; XREF=0x100009869, 0x100004c49, 0x1000071fa, 0x100007f24
000000010000dc8d 4889E5                          mov        rbp, rsp
000000010000dc90 53                              push       rbx
000000010000dc91 50                              push       rax
000000010000dc92 813DAC270100EF8C7915            cmp        dword [ds:_license], 0x15798cef
000000010000dc9c E974000000                      jmp        0x10000dd15
000000010000dca1 90                              nop        
000000010000dca2 90                              nop        
000000010000dca3 90                              nop        
000000010000dd15 4883C408                        add        rsp, 0x8                      ; XREF=0x10000dc9c
000000010000dd19 5B                              pop        rbx
000000010000dd1a 5D                              pop        rbp
000000010000dd1b C3                              ret

There may be other elaborate ways to disable the expiration, but this does the job.


The new version for El Capitain masks the expire method as a delegate as well as adding stack-guard checks. However, the expire method is called from sub_10000c8b7 such that we can conditionally jump to the end of sub_10000c8b7 without entering the section responsible for calling the expire method:

000000010000c8b7         push       rbp                                         ; XREF=sub_100002bfd+7248, sub_100006aba+779, sub_100006aba+4366, sub_100009169+805
000000010000c8b8         mov        rbp, rsp
000000010000c8bb         push       rbx
000000010000c8bc         push       rax
000000010000c8bd         cmp        dword [ds:0x100022b48], 0x15798cef          ; 0x100022b48
000000010000c8c7         jmp        0x10000c93e
000000010000c8cc         nop        
000000010000c8cd         nop        
000000010000c8ce         nop        
; ...
000000010000c93e         add        rsp, 0x8                                    ; XREF=sub_10000c8b7+16
000000010000c942         pop        rbx
000000010000c943         pop        rbp
000000010000c944         ret        
; ... expire method is being called in the next section ...


cracks/jitouch/v2.x.txt ยท Last modified: 2017/02/22 18:30 (external edit)

Access website using Tor

For the copyright, license, warranty and privacy terms for the usage of this website please see the license and privacy pages.