About

The following instructions are a guide to attacking the licensing protections employed by VirtualHere USB server. The methodology is different in that it does not coerce control flow as much but instead replaces a single instruction by its counterpart in order to dismantle all licensing checks.

Limitation of the unregistered software include:

  • the number of USB devices are restricted to only a single device,
  • cannot use client authentication and deauthentication scripts,
  • SSL is not available,
  • cannot ignore USB devices,

etc…

The procedure is a two-part attack:

  1. coerce the software to allow an unlimited number of USB devices to manage,
  2. coerce the software to believe that it is fully licensed in order to disable the rest of the limitations,
  3. [optional] mark the software as being altered for vanity's sake

Removing the Protection

VirtualHere USB seems to rely on some inline Base64 encoded data to mark the software as unlicensed when running the program in trial mode. In case the Base64 data is modified, then VirtualHere USB will announce that the license is invalid. This behaviour can be observed in sub_422c90 in the decompiled source:

0000000000422ce8         mov        edx, 0x1                                    ; argument #3 for method sub_405340, XREF=sub_422c90+38
0000000000422ced         mov        esi, 0x5dd1f8                               ; "unlicensed,1,MCACDkn0jww6R5WOIjFqU/apAg4Um+mDkU2TBcC7fA1FrA==", argument #2 for method sub_405340
0000000000422cf2         mov        edi, 0x5d7fc9                               ; "License", argument #1 for method sub_405340
0000000000422cf7         call       sub_405340
0000000000422cfc         mov        rbx, rax
0000000000422cff         mov        rdi, rax                                    ; argument #1 for method sub_422af0
0000000000422d02         call       sub_422af0
0000000000422d07         mov        rdi, rbx
0000000000422d0a         call       sub_420150
0000000000422d0f         test       rax, rax
0000000000422d12         mov        qword [ds:0x892bf8], rax
0000000000422d19         je         0x422d98

The code calls the soubroutine sub_405340 with function parameters: License, unlicensed,1,MCACDkn0jww6R5WOIjFqU/apAg4Um+mDkU2TBcC7fA1FrA== and 1. In case the second parameter (unlicensed,1,MCACDkn0jww6R5WOIjFqU/apAg4Um+mDkU2TBcC7fA1FrA==) passed to sub_405340 is tampered with, then VirtualHere USB will display on startup:

LOG_ERR     Invalid License
LOG_INFO    Server licensed to=unlicensed max_devices=1

The latter behaviour can be traced to subroutine sub_420150 of the decompiled code that performs various licensing checks resulting (most likely, if unfavourable) to a jump into the segment:

; ...
0000000000420338         mov        rcx, qword [ds:0x643d68]                    ; argument #4 for method sub_5cb6dd, XREF=sub_420150+113, sub_420150+145, sub_420150+177, sub_420150+206, sub_420150+660, sub_420150+702, sub_420150+785, sub_420150+801, sub_420150+1091
000000000042033f         mov        edx, 0x10                                   ; argument #3 for method sub_5cb6dd
0000000000420344         mov        esi, 0x1                                    ; argument #2 for method sub_5cb6dd
0000000000420349         mov        edi, 0x5dd287                               ; "Invalid License\\n", argument #1 for method sub_5cb6dd
000000000042034e         call       sub_5cb6dd
0000000000420353         mov        esi, 0x5d7fc1
0000000000420358         mov        edi, 0x3
000000000042035d         xor        eax, eax
000000000042035f         call       sub_414d90
0000000000420364         mov        esi, 0x34                                   ; argument #2 for method sub_5c5380
0000000000420369         mov        edi, 0x1                                    ; argument #1 for method sub_5c5380
000000000042036e         call       sub_5c5380
0000000000420373         mov        rbx, rax
0000000000420376         movabs     rax, 0x736e6563696c6e75
0000000000420380         mov        qword [ds:rbx], rax
0000000000420383         mov        eax, 0x6465
0000000000420388         mov        byte [ds:rbx+0xa], 0x0
000000000042038c         mov        word [ds:rbx+0x8], ax
0000000000420390         mov        dword [ds:rbx+0x28], 0x1
0000000000420397         mov        byte [ds:rbx+0x30], 0x1
; ...

that is responsible for marking the license as invalid and hence enforcing all trial limitations. However, if the code segment starting at 0x420338, then VirtualHere USB has no way to determine whether the license is invalid or not. Following the latter reasoning, a jump is injected at the very start of the code segment 0x420338 and up to 0x42039b, after the code segment.

0000000000420338         jmp        0x42039b                                    ; XREF=sub_420150+113, sub_420150+145, sub_420150+177, sub_420150+206, sub_420150+660, sub_420150+702, sub_420150+785, sub_420150+801, sub_420150+1091
000000000042033d         nop        
000000000042033e         nop        
000000000042033f         mov        edx, 0x10                                   ; argument #3 for method sub_5cb6dd
0000000000420344         mov        esi, 0x1                                    ; argument #2 for method sub_5cb6dd
0000000000420349         mov        edi, 0x5dd287                               ; "Invalid License\\n", argument #1 for method sub_5cb6dd
000000000042034e         call       sub_5cb6dd
; ...
000000000042039b         mov        rdi, rbp                                    ; argument #1 for method sub_5c5a10, XREF=sub_420150+488, sub_420150+875
000000000042039e         call       sub_5c5a10
00000000004203a3         add        rsp, 0x598
00000000004203aa         mov        rax, rbx
00000000004203ad         pop        rbx
00000000004203ae         pop        rbp
00000000004203af         pop        r12
00000000004203b1         pop        r13
00000000004203b3         pop        r14
00000000004203b5         pop        r15
00000000004203b7         ret

Now VirtualHere USB cannot set itself as using an invalid license however, the code is not reached unless the license is indeed invalid such that the unlicensed hash unlicensed,1,MCACDkn0jww6R5WOIjFqU/apAg4Um+mDkU2TBcC7fA1FrA== has to be destroyed to trigger the now modified invalid license code. To do so, the string is contained within the program starting with address 0x5dd1f8:

00000000005dd1f8         db         "unlicensed,1,MCACDkn0jww6R5WOIjFqU/apAg4Um+mDkU2TBcC7fA1FrA==", 0 ; XREF=sub_422c90+93

and it is sufficient to just modify a single byte to trigger the invalid license code.

When running VirtualHere USB, the program will now display:

Server licensed to= max_devices=1919247151

which is not vary pretty and just begs for a vanity fix. :-)

Vanity

The string Server licensed to=%s %s can be found referenced in the subroutine sub_422930:

                     sub_422930:
0000000000422930         push       rbx                                         ; XREF=sub_422c90+197
0000000000422931         sub        rsp, 0x20
0000000000422935         mov        rdx, qword [ds:0x892bf8]
000000000042293c         mov        eax, dword [ds:rdx+0x28]
000000000042293f         test       eax, eax
0000000000422941         jne        0x422980
 
0000000000422943         movdqa     xmm0, xmmword [ds:0x5dd570]                 ; "max_devices=unliDeregistered interface %s\\n"
000000000042294b         mov        eax, 0x64
0000000000422950         mov        rbx, rsp
0000000000422953         mov        dword [ss:rsp+var_18], 0x6574696d
000000000042295b         mov        word [ss:rsp+var_14], ax
0000000000422960         movaps     xmmword [ss:rsp+var_28], xmm0
 
0000000000422964         mov        rcx, rbx                                    ; XREF=sub_422930+107
0000000000422967         mov        esi, 0x5dd4e3                               ; "Server licensed to=%s %s"
000000000042296c         mov        edi, 0x6
0000000000422971         xor        eax, eax
0000000000422973         call       sub_414d90
0000000000422978         add        rsp, 0x20
000000000042297c         pop        rbx
000000000042297d         ret        
000000000042297e         nop        
 
0000000000422980         mov        rbx, rsp                                    ; XREF=sub_422930+17
0000000000422983         mov        edx, eax
0000000000422985         mov        esi, 0x5dd4d4                               ; "max_devices=%d"
000000000042298a         mov        rdi, rbx
000000000042298d         xor        eax, eax
000000000042298f         call       sub_5cbda2
0000000000422994         mov        rdx, qword [ds:0x892bf8]
000000000042299b         jmp        0x422964

the jne at 0x422941 has already been taken care of in the previous section such that no modification is necessary. On the other hand, the referenced string Server licensed to=%s %s can be found inline at address 0x5dd4e3:

00000000005dd4e3         db         "Server licensed to=%s %s", 0               ; XREF=sub_422930+55

and can be replaced with any other 24 characters - note that this will overwrite the parameters %s that interpolates some variables at runtime using a printf formatting function but that does not matter because by replacing the string the parameters will just be ignored.

The string Server licensed to=%s %s at 0x5dd4e3 reads, in hex:

53 65 72 76 65 72 20 6c 69 63 65 6e 73 65 64 20 74 6f 3d 25 73 20 25 73

and that can be replaced by, say:

57 69 7a 61 72 64 72 79 20 61 6e 64 20 53 74 65 61 6d 77 6f 72 6b 73 00

thereby making the program display:

LOG_INFO    Wizardry and Steamworks 

instead of:

LOG_INFO    Server licensed to= max_devices=1919247151

Patches


cracks/virtualhere_usb/3.5.4.txt · Last modified: 2022/04/19 08:28 by 127.0.0.1

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.