Table of Contents

Shortnote

Snippets is a snippet manager that allows you to search previous snippets and then paste them conveniently using a spotlight-like search bar. The application costs USD15 and it is fairly poor in features and easily replaced by ClipMenu.

The difference between Snippets and ClipMenu is that Snippets costs money and offers less and obtrusive features compared to ClipMenu. There is no reason to use Snippets over ClipMenu. After we cracked Snippets, we threw it into the trash, where it belongs, after a few minutes of use.

The copy-protection is also insanely easy to circumvent. When the application starts it triggers a few trial-based checks based on boolean calls such as isTrial.

Endless Trial

Insanely easy, just find updateTrialControls and shortwire the procedure so it does nothing. We just jump from 0x1000072b0 to 0x10000746a where the procedure just returns. The trial stuff is never even activated.

                                            methImpl_MainWindowController_updateTrialControls:
00000001000072a1 55                              push       rbp
00000001000072a2 4889E5                          mov        rbp, rsp
00000001000072a5 4157                            push       r15
00000001000072a7 4156                            push       r14
00000001000072a9 4154                            push       r12
00000001000072ab 53                              push       rbx
00000001000072ac 4883EC10                        sub        rsp, 0x10
00000001000072b0 E9B5010000                      jmp        0x10000746a
...
000000010000746a 4883C410                        add        rsp, 0x10                     ; XREF=0x1000072ec, 0x10000732d, 0x1000072b0
000000010000746e 5B                              pop        rbx
000000010000746f 415C                            pop        r12
0000000100007471 415E                            pop        r14
0000000100007473 415F                            pop        r15
0000000100007475 5D                              pop        rbp
0000000100007476 C3                              ret

That's it (yes, really) for version 1.4.1, it just doesn't even warrant the effort to be cracked . . .

On Launch License Check

This is not necessary, but let's skip some of the checks when the application starts up. We jump at 0x100003540 over the date-check.

                                            methImpl_AppDelegate_applicationDidFinishLaunching_:
000000010000351d 55                              push       rbp
000000010000351e 4889E5                          mov        rbp, rsp
0000000100003521 4156                            push       r14
0000000100003523 53                              push       rbx
0000000100003524 4883EC30                        sub        rsp, 0x30
0000000100003528 4889FB                          mov        rbx, rdi
000000010000352b 30C0                            xor        al, al
000000010000352d E878A80400                      call       _PFMoveToApplicationsFolderIfNecessary_10004ddaa
0000000100003532 E89D000700                      call       imp___stubs__NSUpdateDynamicServices
0000000100003537 30C0                            xor        al, al
0000000100003539 E8D0960500                      call       _SALicenseIsValid_10005cc0e
000000010000353e 84C0                            test       al, al
0000000100003540 E924000000                      jmp        0x100003569
0000000100003545 90                              nop        
0000000100003546 90                              nop        
0000000100003547 90                              nop        
0000000100003548 90                              nop
...
0000000100003569 488B35C8000D00                  mov        rsi, qword [ds:objc_sel_standardUserDefaults] ; @selector(standardUserDefaults) XREF=0x100003540, 0x100003555
0000000100003570 488B3D49490D00                  mov        rdi, qword [ds:bind__OBJC_CLASS_$_NSUserDefaults]
0000000100003577 4C8B35E2DD0A00                  mov        r14, qword [ds:imp___got__objc_msgSend]

Disable Trial Start and Stop Timer

The trial timer is started when the application finished loading and we have disabled that. For reference, one could also disable the trial timer and then the date check above.

Start

                                            methImpl_MainWindowController_startTrialTimer:
0000000100007117 55                              push       rbp
0000000100007118 4889E5                          mov        rbp, rsp
000000010000711b 4156                            push       r14
000000010000711d 53                              push       rbx
000000010000711e 4883EC10                        sub        rsp, 0x10
0000000100007122 E9DE000000                      jmp        0x100007205
..
0000000100007205 4883C410                        add        rsp, 0x10                     ; XREF=0x100007122
0000000100007209 5B                              pop        rbx
000000010000720a 415E                            pop        r14
000000010000720c 5D                              pop        rbp
000000010000720d FFE0                            jmp        rax

Stop

                                            methImpl_MainWindowController_stopTrialTimer:
000000010000720f 55                              push       rbp
0000000100007210 4889E5                          mov        rbp, rsp
0000000100007213 53                              push       rbx
0000000100007214 E93E000000                      jmp        0x100007257
0000000100007219 90                              nop        
000000010000721a 90                              nop        
000000010000721b 90                              nop        
000000010000721c 90                              nop        
000000010000721d 90                              nop        
000000010000721e 90                              nop
...
0000000100007257 4883C408                        add        rsp, 0x8                      ; XREF=0x100007214
000000010000725b 5B                              pop        rbx
000000010000725c 5D                              pop        rbp
000000010000725d C3                              ret

Getting Rid of the Registration Menu

Registration Menu

This is a little more challenging. On first sight, if we run:

strings Snippets.app/Contents/Resources/English.lproj/MainMenu.nib | grep Reg

and there are no "Registration…" results, slightly misleading us into believing that the "Registration…" menu item is not present in the NIB - but it has to be.

So, Using NIBUnlocker, we dump the Snippets.app/Contents/Resources/English.lproj/MainMenu.nib and find the showRegistrationWindow string. Following the ref="22", we find a menu item with ID 22, but with a base64 encoded name.

Decoding, we get:

echo "UmVnaXN0cmF0aW9u4oCm" | base64 -d
Registration…

There it is.

Now we proceed to eliminate all references to id="22". The lines below are snippets that were taken out.

<object class="NSMenuItem" id="22">
    <int key="NSMnemonicLoc">2147483647</int>
    <reference key="NSMenu" ref="9"/>
    <string key="NSKeyEquiv"></string>
    <string type="base64-UTF8" key="NSTitle">UmVnaXN0cmF0aW9u4oCm</string>
    <reference key="NSOnImage" ref="311"/>
    <reference key="NSMixedImage" ref="312"/>
</object>
...
<object class="IBConnectionRecord">
    <object class="IBActionConnection" key="connection">
        <string key="label">showRegistrationWindow:</string>
        <reference key="source" ref="307"/>
        <reference key="destination" ref="22"/>
    </object>
    <int key="connectionID">852</int>
</object>
...
                            <reference ref="22"/>
                            <object class="IBObjectRecord">
                                <int key="objectID">705</int>
                                <reference key="object" ref="22"/>
                                <reference key="parent" ref="9"/>
                            </object>

Now it is time to produce the new NIB, so we run:

ibtool --errors --warnings --notices --output-format human-readable-text --compile MainMenu.nib MainMenu.xib

and replace the original file.

Starting up Snippets, we get a nice clean menu without any ''Registration…" option.