This crack procedure applies to VirtualHostX
at version 5.0.6
.
VirtualHostX
complains about the trial every time a virtual host is manipulated, this includes mines in the addNewHost
method, the duplicateVirtualHost
method and the applyChanges
method.
In succession, for the addNewHost
method, we have:
; Basic Block Input Regs: rdx rdi - Killed Regs: rax rdx rbx rbp rsi rdi r12 r13 r14 r15 methImpl_MainWindowController_addNewHost_: 000000010000da49 55 push rbp 000000010000da4a 4889E5 mov rbp, rsp 000000010000da4d 4157 push r15 000000010000da4f 4156 push r14 000000010000da51 4155 push r13 000000010000da53 4154 push r12 000000010000da55 53 push rbx 000000010000da56 4883EC38 sub rsp, 0x38 ... 000000010000db00 E910000000 jmp 0x10000db15 000000010000db05 4C89EE mov rsi, r13 000000010000db08 E851D30200 call sub_10003ae5e 000000010000db0d 84C0 test al, al 000000010000db0f 0F84DF020000 je 0x10000ddf4 ; leads to activation garbage 000000010000db15 4C8B25D4B40F00 mov r12, qword [ds:bind__OBJC_CLASS_$_NSEntityDescription] ; XREF=0x10000db00 ... 000000010000ddde 90 nop ; leads to activation garbage 000000010000dddf 90 nop 000000010000dde0 4883C438 add rsp, 0x38 000000010000dde4 5B pop rbx 000000010000dde5 415C pop r12 000000010000dde7 415D pop r13 000000010000dde9 415E pop r14 000000010000ddeb 415F pop r15 000000010000dded 5D pop rbp 000000010000ddee C3 ret 000000010000ddef E810A80800 call imp___stubs____stack_chk_fail ; XREF=0x10000ddde 000000010000ddf4 488B3D5DB10F00 mov rdi, qword [ds:bind__OBJC_CLASS_$_NSAlert] ; XREF=0x10000db0f 000000010000ddfb 488B3596780F00 mov rsi, qword [ds:objc_sel_alertWithMessageText_defaultButton_alternateButton_otherButton_informativeTextWithFormat_] ; @selector(alertWithMessageText:defaultButton:alternateButton:otherButton:informativeTextWithFormat:) 000000010000de02 488D05470B1000 lea rax, qword [ds:cfstring_Thanks_for_trying_VirtualHostX__Your_free_trial_has_expired__If_you_would_like_to_continue_] ; @"Thanks for trying VirtualHostX. Your free trial has expired. If you would like to continue using VirtualHostX, please purchase a copy from our secure website."
The main point of interest is the je
that leads to the activation sequence:
000000010000db0f 0F84DF020000 je 0x10000ddf4 ; leads to activation garbage
It can be avoided, as we did in the example, by using a jmp
at 0x10000db00
. Additionally at 0x10000ddde
another jump should be nop
ed which would have lead to the activation again.
The same sort-of sequence, can be seen in the next method duplicateVirtualHost
:
; Basic Block Input Regs: rax rdx rdi - Killed Regs: rdx rbx rbp rsi rdi r12 r13 r14 r15 methImpl_MainWindowController_duplicateVirtualHost_: 000000010000e15b 55 push rbp 000000010000e15c 4889E5 mov rbp, rsp 000000010000e15f 4157 push r15 ... 000000010000e23e E910000000 jmp 0x10000e253 ; would have lead to activation garbage 000000010000e243 4889DE mov rsi, rbx 000000010000e246 E813CC0200 call sub_10003ae5e 000000010000e24b 84C0 test al, al 000000010000e24d 0F84C6030000 je 0x10000e619 000000010000e253 4C8B3596AD0F00 mov r14, qword [ds:bind__OBJC_CLASS_$_NSEntityDescription] ; XREF=0x10000e23e 000000010000e25a 488B3D4FAC0F00 mov rdi, qword [ds:bind__OBJC_CLASS_$_NSManagedObjectContext]
where by using a jmp
at 0x10000e23e
we avoid the je
to 0x10000e619
where the activation stuff will bomb us out.
For the third one, the same applies to applyChanges
:
; Basic Block Input Regs: rax rdi - Killed Regs: rdx rbx rbp rsi rdi r12 r13 r14 r15 methImpl_MainWindowController_applyChanges_: 000000010000eec3 55 push rbp 000000010000eec4 4889E5 mov rbp, rsp 000000010000eec7 4157 push r15 000000010000eec9 4156 push r14 000000010000eecb 4155 push r13 000000010000eecd 4154 push r12 000000010000eecf 53 push rbx ... 000000010000ef5f E911000000 jmp 0x10000ef75 ; would have lead to activation garbage 000000010000ef64 90 nop 000000010000ef65 4C89E6 mov rsi, r12 000000010000ef68 E8F1BE0200 call sub_10003ae5e 000000010000ef6d 84C0 test al, al 000000010000ef6f 0F84ED000000 je 0x10000f062 000000010000ef75 488B354C650F00 mov rsi, qword [ds:objc_sel_window] ; @selector(window) XREF=0x10000ef5f
In order to explain this better, all these methods first call a subroutine and then depending on the outcome, it jumps or does not jump into the trial-expired activation block. Here is an example sequence from addNewHost
:
000000010000ef58 E812BD0200 call sub_10003ac6f 000000010000ef5d 84C0 test al, al 000000010000ef5f E911000000 jmp 0x10000ef75 ; original code does not jump... 000000010000ef64 90 nop 000000010000ef65 4C89E6 mov rsi, r12 000000010000ef68 E8F1BE0200 call sub_10003ae5e 000000010000ef6d 84C0 test al, al 000000010000ef6f 0F84ED000000 je 0x10000f062 ; and then ends up jumping at this point...
Lastly, we have another bomb in the showReg
method, which can be avoided:
methImpl_PreferencesController_showReg_: 0000000100006b7b 55 push rbp 0000000100006b7c 4889E5 mov rbp, rsp 0000000100006b7f 4157 push r15 0000000100006b81 4156 push r14 0000000100006b83 4155 push r13 0000000100006b85 4154 push r12 ... 0000000100006cf7 4C89FB mov rbx, r15 ; XREF=0x100006c7e 0000000100006cfa E8703F0300 call sub_10003ac6f 0000000100006cff 84C0 test al, al 0000000100006d01 E91C000000 jmp 0x100006d22 0000000100006d06 90 nop 0000000100006d07 90 nop 0000000100006d08 90 nop 0000000100006d09 90 nop 0000000100006d0a 498B3C04 mov rdi, qword [ds:r12+rax] 0000000100006d0e 488B35BBE80F00 mov rsi, qword [ds:objc_sel_setStringValue_] ; @selector(setStringValue:) 0000000100006d15 488D15346F1000 lea rdx, qword [ds:cfstring_Your_14_day_trial_of_VirtualHostX_has_ended__If_you_d_like_to_continue_using_the_app__pleas] ; @"Your 14 day trial of VirtualHostX has ended. If you'd like to continue using the app, please consider buying a license below. Thanks!" 0000000100006d1c FF150EA60D00 call qword [ds:imp___got__objc_msgSend] ...
the newly inserted jmp
at 0x100006d01
will skip the activation stuff and carry on.
The nag bar is shown conditionally in the addDemoBanner
method. Simply by turning the original jne
into a jmp
at 0x10000bff8
we can avoid the banner being shown:
; Basic Block Input Regs: rax rdi - Killed Regs: rdx rbx rbp rsi rdi r12 r13 r14 r15 methImpl_MainWindowController_addDemoBanner: 000000010000bf50 55 push rbp 000000010000bf51 4889E5 mov rbp, rsp 000000010000bf54 4157 push r15 000000010000bf56 4156 push r14 000000010000bf58 4155 push r13 000000010000bf5a 4154 push r12 000000010000bf5c 53 push rbx 000000010000bf5d 4881EC08010000 sub rsp, 0x108 ... 000000010000bff8 E9E2040000 jmp 0x10000c4df 000000010000bffd 90 nop ; ... ; ... original code: show banner ; ... 000000010000c4df 4881C408010000 add rsp, 0x108 ; XREF=0x10000bff8 000000010000c4e6 5B pop rbx 000000010000c4e7 415C pop r12 000000010000c4e9 415D pop r13 000000010000c4eb 415E pop r14 000000010000c4ed 415F pop r15 000000010000c4ef 5D pop rbp 000000010000c4f0 C3 ret