Cornerstone is one of the top-paid SVN
management applications, priced at USD69 and competes with Versions for OSX which is a dozen cheaper (and also more difficult to crack). The Cornerstone crack involves never running Cornerstone, or, at least, a fresh install on a machine where Cornerstone had never run before.
Two jumps are necessary that will bypass all the annoyances used by Cornerstone to convince you to register the software. Cornerstone's set-up procedure includes the following operations in methImpl_V4ApplicationDelegate_finishLaunch
:
All of these can be bypassed with two jumps in methImpl_V4ApplicationDelegate_finishLaunch
:
; Basic Block Input Regs: rdi - Killed Regs: rax r15 xmm0 methImpl_V4ApplicationDelegate_finishLaunch: 000000010001aff1 55 push rbp 000000010001aff2 4889E5 mov rbp, rsp 000000010001aff5 4157 push r15 000000010001aff7 4156 push r14 000000010001aff9 53 push rbx 000000010001affa 50 push rax 000000010001affb 4989FF mov r15, rdi 000000010001affe 488B052B702800 mov rax, qword [ds:imp___got__NSAppKitVersionNumber] 000000010001b005 F20F1000 movsd xmm0, qword [ds:rax] 000000010001b009 E816951B00 call imp___stubs__floor 000000010001b00e 660F2E0532A01B00 ucomisd xmm0, dword [ds:0x1001d5048] 000000010001b016 E97A000000 jmp 0x10001b095 000000010001b01b 90 nop 000000010001b01c 90 nop 000000010001b01d 90 nop 000000010001b01e 90 nop ; ... 000000010001b095 488B35F4272F00 mov rsi, qword [ds:objc_sel_setupPanels] ; @selector(setupPanels) XREF=0x10001b07c, 0x10001b016 000000010001b09c 4C89FF mov rdi, r15 000000010001b09f FF1513752800 call qword [ds:imp___got__objc_msgSend] 000000010001b0a5 488B35EC272F00 mov rsi, qword [ds:objc_sel_setupMainMenu] ; @selector(setupMainMenu) 000000010001b0ac 4C89FF mov rdi, r15 000000010001b0af FF1503752800 call qword [ds:imp___got__objc_msgSend] 000000010001b0b5 488B35E4272F00 mov rsi, qword [ds:objc_sel_setupDockMenu] ; @selector(setupDockMenu) 000000010001b0bc 4C89FF mov rdi, r15 ; ... 000000010001b16c E902000000 jmp 0x10001b173 000000010001b171 90 nop 000000010001b172 90 nop ; Basic Block Input Regs: <nothing> - Killed Regs: rbx rsp rbp r14 r15 000000010001b173 4883C408 add rsp, 0x8 ; XREF=0x10001b16c 000000010001b177 5B pop rbx 000000010001b178 415E pop r14 000000010001b17a 415F pop r15 000000010001b17c 5D pop rbp 000000010001b17d C3 ret
The first jump takes care to skip over all the licensing stuff and the second jump is required in order to not fall into the exception trap:
000000010001b16c E902000000 jmp 0x10001b173 000000010001b171 90 nop 000000010001b172 90 nop ; Basic Block Input Regs: <nothing> - Killed Regs: rbx rsp rbp r14 r15 000000010001b173 4883C408 add rsp, 0x8 ; XREF=0x10001b16c 000000010001b177 5B pop rbx 000000010001b178 415E pop r14 000000010001b17a 415F pop r15 000000010001b17c 5D pop rbp 000000010001b17d C3 ret
which would take the program out of the method and into some loop.
Contrary to our previous cracks, this application embeds the License Registration…
menu item directly into the code instead of using a NIB/XIB for the menu items. The identified string can be found in the setupMainMenu
method (duh) which contains a conditional that skips over the License Registration…
menu item in case the application is registered. So, we disregard the postcondition of that conditional and jump over the menu item display:
methImpl_V4ApplicationDelegate_setupMainMenu: 000000010001a995 55 push rbp 000000010001a996 4889E5 mov rbp, rsp 000000010001a999 4157 push r15 000000010001a99b 4156 push r14 000000010001a99d 4155 push r13 ; ... yadda yadda, blah blah blah... ; here comes the interesting part: 000000010001a9f5 488B35CC2D2F00 mov rsi, qword [ds:objc_sel_isLicensingUIEnabled] ; @selector(isLicensingUIEnabled) 000000010001a9fc 4889C7 mov rdi, rax 000000010001a9ff 41FFD7 call r15 000000010001aa02 3C01 cmp al, 0x1 ; we substitute the jne through a jmp and really not care about the result of cmp 000000010001aa04 E992000000 jmp 0x10001aa9b 000000010001aa09 90 nop ; here is what we would have gotten into: 000000010001aa0a 488B3DE7E82F00 mov rdi, qword [ds:0x1003192f8] 000000010001aa11 488D3518E62F00 lea rsi, qword [ds:objc_msg_alloc] ; @selector(alloc) 000000010001aa18 FF1512E62F00 call qword [ds:objc_msg_alloc] ; @selector(alloc) ; ... yadda yadda, blah blah blah... 000000010001aa2f 4C8B3D827B2800 mov r15, qword [ds:imp___got__objc_msgSend] 000000010001aa36 41FFD7 call r15 000000010001aa39 488D1500D33000 lea rdx, qword [ds:cfstring_License_Registration___] ; @"License Registration..." ; ... yadda yadda, blah blah blah... ; we jumped to the rest of the menu setup which is now clean: 000000010001aa9b 488B357E162F00 mov rsi, qword [ds:objc_sel_sharedInstance] ; @selector(sharedInstance) XREF=0x10001aa04 000000010001aaa2 488B3D9FE72F00 mov rdi, qword [ds:objc_classref_V4Defaults] 000000010001aaa9 4C8B3D087B2800 mov r15, qword [ds:imp___got__objc_msgSend] ; ... yadda yadda, blah blah blah...
For instructions on how to apply this patch to your Conrnerstone 2.7.14
please see the applying binary patches part of the tutorial.
begin 644 Cornerstone.bsdiff M0E-$249&-#!.`````````!8!````````P&AX``````!"6F@Y,4%9)E-9?]@R M.@``%4U+<`A&`'"``,!`#`(`0(``("``,4PFF@-,0A`,C09J(J39B2YF9B2D M]07&>`JVB3P/B[DBG"A(/^P9'0!"6F@Y,4%9)E-9/(N-?```0G__S8-01E$` M`Q!@,&```(2&T$`(0!0$@V`'B1A0%$A.Q"^P`/A(:34T0``&@`!HT#33(])M M"`<PF`3`"83":8``!,FF@81*2C30````T:````;"EQ@M,51+$QY(.&(A(B!5 M?HH%<1D4!0,$!50!'@@H`B7L@#4(!RDTB99N:^;C*(``KBGN6?94CPW\,JN( M0FGXT`UHYT40`!6D.N-(HR?T[X\D&\1`1```$1;'-.U)#PZTTF1!06:K#,,7 M3FX`J[2\Q3:!GCX4([`D1-]?N*9@E?#J5H6A625@M58P`9F`M'OT#+]\.$69 ME2UA`1``5LAOR0KAZEMM+C_%W)%.%"0/(N-?`$)::#DQ05DF4UEA(0'C``!H =T`#````@``@@`""E-!F-"6PB7B[DBG"A(,)"`\8` ` end
That is it, for the crack of Cornerstone v2.7.14
.