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.
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
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:
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.
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
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
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.