This page presents the crack method for Lyn 1.6 meant to turn the program into a fully registered program as well as removing the obtrusive menu items such as "Buy Lyn" or "Enter Serial Number…".
Lyn's protection seems to revolve around the isRegistered
method that is called in various places and, depending on the outcome, the program uses either a jne
or a je
. De-mining this puppy will require some work but it is fairly straight-forward, almost algorithmically.
Find all the occurrences of the code-pattern:
000000010008c29d mov rsi, qword [ds:0x100727778] ; @selector(isRegistered), argument "selector" for method _objc_msgSend 000000010008c2a4 mov rdi, rax ; argument "instance" for method _objc_msgSend 000000010008c2a7 call r13 ; _objc_msgSend 000000010008c2aa test al, al 000000010008c2ac jne 0x10008c5f9
and turn the last jne
into a jmp
.
Find all the occurrences of the code-pattern:
000000010000beb0 mov rsi, qword [ds:0x100727778] ; @selector(isRegistered), argument "selector" for method _objc_msgSend 000000010000beb7 mov rdi, rax ; argument "instance" for method _objc_msgSend 000000010000beba call rbx ; _objc_msgSend 000000010000bebc mov rcx, rbx 000000010000bebf test al, al 000000010000bec1 je 0x10000beef
and eliminate the last je
(with nop
).
In some instances, the above pattern will not work and you will not find a jne
or je
. In such cases, if you browse the code, you will find a reference to isTrialPeriod
which should be attacked instead. Thus, in these cases, locate the code-pattern:
000000010007d98a mov rsi, qword [ds:0x100727780] ; @selector(isTrialPeriod), argument "selector" for method _objc_msgSend 000000010007d991 mov rdi, rax ; argument "instance" for method _objc_msgSend 000000010007d994 call r14 ; _objc_msgSend 000000010007d997 test al, al 000000010007d999 jne 0x10007d9c0
and replace the jne
by a jmp
.
One more annoyance is the trial timer that gets installed in the applicationDidFinishLaunching
. Locate the applicationDidFinishLaunching
method where the fireTimer
is referenced. You will find the isRegistered
call ending in a je
that you nop
-ed :
001344c 0000000100013426 mov rdi, qword [ds:objc_cls_ref_AppDelegate] ; objc_cls_ref_AppDelegate, argument "instance" for method _objc_msgSend 000000010001342d mov rsi, qword [ds:0x1007271c8] ; @selector(appDelegate), argument "selector" for method _objc_msgSend 0000000100013434 call r13 ; _objc_msgSend 0000000100013437 mov rsi, qword [ds:0x100727778] ; @selector(isRegistered), argument "selector" for method _objc_msgSend 000000010001343e mov rdi, rax ; argument "instance" for method _objc_msgSend 0000000100013441 call r13 ; _objc_msgSend 0000000100013444 test al, al 0000000100013446 nop 0000000100013447 nop 0000000100013448 nop 0000000100013449 nop 000000010001344a nop 000000010001344b nop ; isRegistered former "je" was removed with "nop" 000000010001344c mov rdi, qword [ds:objc_cls_ref_AppDelegate] ; objc_cls_ref_AppDelegate, argument "instance" for method _objc_msgSend, XREF=-[AppDelegate applicationDidFinishLaunching:]+299 0000000100013453 mov rsi, qword [ds:0x1007271c8] ; @selector(appDelegate), argument "selector" for method _objc_msgSend 000000010001345a call r13 ; _objc_msgSend 000000010001345d mov rsi, qword [ds:0x100727778] ; @selector(isRegistered), argument "selector" for method _objc_msgSend 0000000100013464 mov rdi, rax ; argument "instance" for method _objc_msgSend 0000000100013467 call r13 ; _objc_msgSend 000000010001346a test al, al 000000010001346c jmp 0x10001374f 0000000100013471 nop
And replace the jne
or je
around 0x10001346c
(before last line) by a jmp
as illustrated which will make the code skip over the fireTimer
code and not install it at all.
You will have to use NibUnlocker and locate the MainMenu.nib
file in Lyn.app/Contents/Resources/English.lproj
and covert it to a MainMenu.xib
. Then, opening up MainMenu.xib
, you will find in that file the following pattern:
<object class="NSMenuItem" id="17"> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSMenu" ref="7"/> <string key="NSKeyEquiv"></string> <int key="NSTag">55</int> <string key="NSTitle">Buy Lyn</string> <reference key="NSOnImage" ref="680"/> <reference key="NSMixedImage" ref="681"/> </object> <object class="NSMenuItem" id="20"> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSMenu" ref="7"/> <string key="NSKeyEquiv"></string> <int key="NSTag">56</int> <string key="NSTitle">Enter Serial Number...</string> <reference key="NSOnImage" ref="680"/> <reference key="NSMixedImage" ref="681"/> </object>
which are both the menu items Buy Lyn
, respectively Enter Serial Number…
that we want to remove.
The procedure is simple:
ref="17"
(the reference to the Buy Lyn
button) and delete the immediate parent block that contains ref="17"
.ref="20"
(the reference to the Enter Serial Number…
button) and delete the parent block that contains ref="20"
.