Feeling that our literary expertise needs a boost, one of our members wanted an application to write novels in. The sort of assistive document writer... So browsing around for the most expensive one out there (since we like to live in style), we found Scrivener. Scrivener's trial mode can be defeated by turning the application into a never-expiring trial. There is no loss of options in doing so and we can also get rid of the nag screen.

Registration Prompt

Getting rid of this one is fairly easy. When you launch the application you get a big banner “Scrivener is unregistered!” and with buttons to Buy, Enter License and Try. Clearly, this is just a popup that you cannot get rid off. So instead of pressing any button, let us kill the application using Activity Monitor and disassemble the program:

Starting with 0x2924f7 we have an unnamed procedure called sub_2924f7 which contains lines such as:

00292677 897C240C                        mov        dword [ss:esp+0xC], edi
0029267b 8D93BBE50A00                    lea        edx, dword [ds:ebx-0x292505+cfstring_Invalid_serial_number_or_name_] ; @"Invalid serial number or name."
00292681 89542408                        mov        dword [ss:esp+0x8], edx


002926b4 8B8BAB740B00                    mov        ecx, dword [ds:ebx-0x292505+objc_msg_localizedStringForKey_value_table_] ; @selector(localizedStringForKey:value:table:)
002926ba 897C240C                        mov        dword [ss:esp+0xC], edi
002926be 8D93CBE50A00                    lea        edx, dword [ds:ebx-0x292505+cfstring_Please_check_that_the_serial_number_and_name_you_have_entered_match_the_ones_sent_to_you_] ; @"Please check that the serial number and name you have entered match the ones sent to you."
002926c4 89542408                        mov        dword [ss:esp+0x8], edx

but most importantly:

0029283b 8974240C                        mov        dword [ss:esp+0xC], esi
0029283f 8D938BE50A00                    lea        edx, dword [ds:ebx-0x292505+cfstring_Try] ; @"Try"
00292845 89542408                        mov        dword [ss:esp+0x8], edx

which is sufficient to assume that the routine is some callback of the nag screen we get when we launch the application. The whole registration procedure, buy button and trial button handling extends up to 002933af where the subroutine ends.

We jump back to 0x2924f7 and follow the procedure down to 0x292558 which is the first jump into the maze of registration procedures:

00292556 85C0                            test       eax, eax
00292558 0F84DE0D0000                    je         0x29333C

If registers are not equal then the jump proceeds to the usual nagging. We hard-wire that jump to the end of the application in order to get rid of the nag screen:

00292556 85C0                            test       eax, eax
00292558 E9520E0000                      jmp        0x2933AF

and that is enough to get rid of the nag screen.

Expiration Days

Additionally, let's make sure that the trial never expires. So let's pull up a list of symbols and see what we have available. The most obvious of all is:

0028fd4a 8D976F0B0B00                    lea        edx, dword [ds:edi-0x28fcc1+cfstring_Scrivener_Trial_Expired] ; @"Scrivener Trial Expired"

Looking at the procedure the string is in, called here sub_28fcb3, we find stuff like:

                                       ; Basic Block Input Regs: ebx edi -  Killed Regs: eax esp
0028fea0 8B878BF50B00                    mov        eax, dword [ds:edi-0x28fcc1+objc_msg_endTrialImmediatelyAndQuit_] ; @selector(endTrialImmediatelyAndQuit:)

which is a clear indication that the procedure we are in quits the application when the trial is over.

Going to the beginning of the procedure at 0x28fcb3, we follow the code up to the first jump:

0028fcc5 80BB3001000000                  cmp        byte [ds:ebx+0x130], 0x0
0028fccc 0F8597020000                    jne        0x28FF69

and following the jne to 0x28ff69 we find the end of the procedure:

                                       ; Basic Block Input Regs: <nothing> -  Killed Regs: ebx esp ebp esi edi
0028ff69 83C42C                          add        esp, 0x2C                             ; XREF=0x28fccc, 0x28fe5b, 0x28fe39
0028ff6c 5E                              pop        esi
0028ff6d 5F                              pop        edi
0028ff6e 5B                              pop        ebx
0028ff6f 5D                              pop        ebp
0028ff70 C3                              ret        
                        ; endp

which is a clear indication that this subroutine is responsible for checking whether the trial has expired. Thus, we go back to 0x28fccc and change the jne into a plain boring jmp.

This will make this callback skip all the code related to terminating the application once the trial is over and will just return as if the trial is not over.

0028fcc5 80BB3001000000                  cmp        byte [ds:ebx+0x130], 0x0
0028fccc E985970200                      jmp        0x2B9456

Job done. When the application is launched, it does not even prompt for registration and if we set the date forward more than 30 days, we get no nag screen.


cracks/scrivener/2.6.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.