jitouch is a nice tool for controlling your Magic Trackpad. The program is just a preference pane applet that contains a binary image with a license protection. The protection consists in a simple key verification mechanism:
0000000000001f2c 7F20 jnle 0x1F4E ; Basic Block Input Regs: r14 - Killed Regs: rdx rsi rdi 0000000000001f2e 488D15FB830200 lea rdx, qword [ds:cfstring_Invalid_Key] ; @"Invalid Key" 0000000000001f35 488D35C4AD0200 lea rsi, qword [ds:objc_msg_setMessageText_] ; @selector(setMessageText:) 0000000000001f3c 4C89F7 mov rdi, r14 0000000000001f3f FF15BBAD0200 call qword [ds:objc_msg_setMessageText_] ; @selector(setMessageText:) 0000000000001f45 488D1504840200 lea rdx, qword [ds:cfstring_Please_check_your_license_key] ; @"Please check your license key" 0000000000001f4c EB6E jmp 0x1FBC ; Basic Block Input Regs: r14 r15 - Killed Regs: rax rdx rbx rsi rdi r12 r13 0000000000001f4e 488B0513C80200 mov rax, qword [ds:_OBJC_IVAR_$_JitouchPref.mainTabView] ; XREF=0x1f2c
in order to register with any key and name, we change the jnle
into a jmp
, thereby jumping over the check.
The results are as expected, the registration accepts any name and any serial.
There are two binaries that we attack:
Jitouch.prefPane/Contents/MacOS/Jitouch
Jitouch.prefPane/Contents/Resources/Jitouch.app/Contents/MacOS/Jitouch
In the preference pane executable (Jitouch.prefPane/Contents/MacOS/Jitouch
), based on the license check, a preference pane tab is added when mainViewDidLoad
called Register
which we remove by nop
ing the jle
at 0x2965
:
0000000000002965 90 nop 0000000000002966 90 nop 0000000000002967 488B05FABD0200 mov rax, qword [ds:_OBJC_IVAR_$_JitouchPref.mainTabView] 000000000000296e 498B1C06 mov rbx, qword [ds:r14+rax] 0000000000002972 4C8B2DC7A30200 mov r13, qword [ds:objc_msg_removeTabViewItem_] ; @selector(removeTabViewItem:) 0000000000002979 4C8B25B0A30200 mov r12, qword [ds:objc_msg_tabViewItemAtIndex_] ; @selector(tabViewItemAtIndex:) 0000000000002980 488D15E9790200 lea rdx, qword [ds:cfstring_Register] ; @"Register" 0000000000002987 488D3592A30200 lea rsi, qword [ds:objc_msg_indexOfTabViewItemWithIdentifier_] ; @selector(indexOfTabViewItemWithIdentifier:) 000000000000298e 4889DF mov rdi, rbx 0000000000002991 FF1589A30200 call qword [ds:objc_msg_indexOfTabViewItemWithIdentifier_] ; @selector(indexOfTabViewItemWithIdentifier:) 0000000000002997 4889C2 mov rdx, rax 000000000000299a 488D358FA30200 lea rsi, qword [ds:objc_msg_tabViewItemAtIndex_] ; @selector(tabViewItemAtIndex:) 00000000000029a1 4889DF mov rdi, rbx 00000000000029a4 41FFD4 call r12 00000000000029a7 4889C2 mov rdx, rax 00000000000029aa 488D358FA30200 lea rsi, qword [ds:objc_msg_removeTabViewItem_] ; @selector(removeTabViewItem:) 00000000000029b1 4889DF mov rdi, rbx 00000000000029b4 41FFD5 call r13 00000000000029b7 498B3F mov rdi, qword [ds:r15] ; XREF=0x2965
The consequence will be that when the preference pane is loaded, the button will be immediately removed instead of skipping over this block which is what the jle
was responsible for in trial mode.
In the Jitouch application (Jitouch.prefPane/Contents/Resources/Jitouch.app/Contents/MacOS/Jitouch
) we disable the license check increment:
====== B E G I N O F P R O C E D U R E ====== ; Basic Block Input Regs: <nothing> - Killed Regs: <nothing> _increaseLicenseCounter: 000000010000635d 55 push rbp ; XREF=0x10000672c, 0x10000747b, 0x100008b63, 0x10000bc40 000000010000635e 4889E5 mov rbp, rsp 0000000100006361 813D3DE00100EF8C7915 cmp dword [ds:_license], 0x15798CEF 000000010000636b 0F84FA000000 je 0x10000646B
We thus turn the je
into a jmp
so that the license counter does not get increased.
In methImpl_JitouchAppDelegate_expire
we make sure that the application never expires:
methImpl_JitouchAppDelegate_expire: 00000001000030eb 55 push rbp 00000001000030ec 4889E5 mov rbp, rsp 00000001000030ef 4154 push r12 00000001000030f1 53 push rbx 00000001000030f2 E9CB000000 jmp 0x1000031C2
We also nullify showTrialDialog
:
methImpl_JitouchAppDelegate_showTrialDialog: 000000010000275e 55 push rbp 000000010000275f 4889E5 mov rbp, rsp 0000000100002762 4155 push r13 0000000100002764 4154 push r12 0000000100002766 53 push rbx 0000000100002767 4883EC08 sub rsp, 0x8 000000010000276b E924010000 jmp 0x100002894 ... 0000000100002894 4883C408 add rsp, 0x8 ; XREF=0x10000276b 0000000100002898 5B pop rbx 0000000100002899 415C pop r12 000000010000289b 415D pop r13 000000010000289d C9 leave 000000010000289e 41FFE3 jmp r11
the same way, by jumping to the end of the function.
methImpl_JitouchAppDelegate_checkLicense: 0000000100002e68 55 push rbp 0000000100002e69 4889E5 mov rbp, rsp 0000000100002e6c 4157 push r15 0000000100002e6e 4156 push r14 0000000100002e70 4155 push r13 0000000100002e72 4154 push r12 0000000100002e74 53 push rbx 0000000100002e75 4883EC08 sub rsp, 0x8 0000000100002e79 E95E020000 jmp 0x1000030DC ... 00000001000030dc 4883C408 add rsp, 0x8 ; XREF=0x100002eea, 0x100002efa, 0x10000308c, 0x1000030a0, 0x100002e79 00000001000030e0 5B pop rbx 00000001000030e1 415C pop r12 00000001000030e3 415D pop r13 00000001000030e5 415E pop r14 00000001000030e7 415F pop r15 00000001000030e9 C9 leave 00000001000030ea C3 ret
and the same for the preference pane binary (Jitouch.prefPane/Contents/MacOS/Jitouch
):
methImpl_JitouchPref_checkLicense: 00000000000023d3 55 push rbp 00000000000023d4 4889E5 mov rbp, rsp 00000000000023d7 4157 push r15 00000000000023d9 4156 push r14 00000000000023db 4155 push r13 00000000000023dd 4154 push r12 00000000000023df 53 push rbx 00000000000023e0 4883EC08 sub rsp, 0x8 00000000000023e4 E921020000 jmp 0x260A ... 000000000000260a 4883C408 add rsp, 0x8 ; XREF=0x25e2, 0x25f3, 0x2602, 0x23e4 000000000000260e 5B pop rbx 000000000000260f 415C pop r12 0000000000002611 415D pop r13 0000000000002613 415E pop r14 0000000000002615 415F pop r15 0000000000002617 C9 leave 0000000000002618 C3 ret