Shortnote

ProxyCap is a tool, similar to Little Snitch that allows you to set per-application proxy settings. The registration is a simple license-check that can be circumvented by forcing the application to register and then blocking any re-validations. The result is that we managed to register the application using a picture instead of the license fileā€¦

 
====== B E G I N   O F   P R O C E D U R E ======
 
 
                                       ; Basic Block Input Regs: <nothing> -  Killed Regs: eax ebx esp
                                    meth_Controller_aboutRegister_:
00003edc 55                              push       ebp
00003edd 89E5                            mov        ebp, esp
00003edf 57                              push       edi
00003ee0 56                              push       esi
00003ee1 53                              push       ebx
00003ee2 83EC5C                          sub        esp, 0x5C
...
00004028 E929000000                      jmp        0x4056
0000402d 90                              nop        
0000402e 90                              nop        
0000402f 90                              nop        
00004030 90                              nop        
00004031 E80A830600                      call       imp___jump_table____cxa_allocate_exception
00004036 8B1510C00600                    mov        edx, dword [ds:imp___pointers___ZTIi]
0000403c C70001000000                    mov        dword [ds:eax], 0x1
00004042 C744240800000000                mov        dword [ss:esp+0x8], 0x0
0000404a 89542404                        mov        dword [ss:esp+0x4], edx
0000404e 890424                          mov        dword [ss:esp], eax
00004051 E812830600                      call       imp___jump_table____cxa_throw
                                       ; Basic Block Input Regs: eax ebp -  Killed Regs: eax edx esp ebp esi
00004056 C7042400020000                  mov        dword [ss:esp], 0x200                 ; XREF=0x4028
...
                                       ; Basic Block Input Regs: eax ebp -  Killed Regs: eax edx esp ebp esi
00004056 C7042400020000                  mov        dword [ss:esp], 0x200                 ; XREF=0x4028
0000405d E8D4820600                      call       imp___jump_table___Znam               ; operator new[](unsigned long)
00004062 8B55BC                          mov        edx, dword [ss:ebp-0x68+var_36]
00004065 89C6                            mov        esi, eax
00004067 8945C4                          mov        dword [ss:ebp-0x68+var_44], eax
0000406a C744240800020000                mov        dword [ss:esp+0x8], 0x200
00004072 89442404                        mov        dword [ss:esp+0x4], eax
00004076 891424                          mov        dword [ss:esp], edx
00004079 E8300C0100                      call       sub_14cae
0000407e 8D45D8                          lea        eax, dword [ss:ebp-0x68+var_64]
00004081 890424                          mov        dword [ss:esp], eax
00004084 E8C1120200                      call       sub_2534a
00004089 E95C010000                      jmp        0x41EA
...
00004293 E9A3000000                      jmp        0x433B
00004298 90                              nop        
00004299 8B55B8                          mov        edx, dword [ss:ebp+0xFFFFFFFFFFFFFFB8]
0000429c C7442404E4E50200                mov        dword [ss:esp+0x4], 0x2E5E4           ; "$canceled"
000042a4 891424                          mov        dword [ss:esp], edx
000042a7 E8F47F0600                      call       imp___jump_table___ZNKSs7compareEPKc  ; std::string::compare(char const*) const
...
                                       ; Basic Block Input Regs: ebp -  Killed Regs: eax edx esp
0000433b A178A00600                      mov        eax, dword [ds:objc_msg_syncDisabled] ; XREF=0x4293
00004340 89442404                        mov        dword [ss:esp+0x4], eax
00004344 8B4508                          mov        eax, dword [ss:ebp-0x68+arg_0]
00004347 890424                          mov        dword [ss:esp], eax
0000434a E822810600                      call       imp___jump_table__objc_msgSend
0000434f 8B4508                          mov        eax, dword [ss:ebp-0x68+arg_0]
00004352 8B5024                          mov        edx, dword [ds:eax+0x24]
00004355 A14CA00600                      mov        eax, dword [ds:objc_msg_setStringValue_]
0000435a C7442408EC4C0600                mov        dword [ss:esp+0x8], 0x64CEC           ; @"This copy is registered"

The successive jmps make sure to skip most of the license validation procedures and end in the valid registration zone.

The next target is the showAbout method at 0x3768:

                                    meth_Controller_showAbout_:
00003768 55                              push       ebp
00003769 89E5                            mov        ebp, esp
...
00003789 E922000000                      jmp        0x37B0
0000378e 90                              nop        
0000378f 90                              nop        
00003790 891C24                          mov        dword [ss:esp], ebx
00003793 89442404                        mov        dword [ss:esp+0x4], eax
00003797 E8D58C0600                      call       imp___jump_table__objc_msgSend
0000379c 8B5310                          mov        edx, dword [ds:ebx+0x10]
0000379f A164A00600                      mov        eax, dword [ds:objc_msg_center]
000037a4 891424                          mov        dword [ss:esp], edx
000037a7 89442404                        mov        dword [ss:esp+0x4], eax
000037ab E8C18C0600                      call       imp___jump_table__objc_msgSend
000037b0 A114C00600                      mov        eax, dword [ds:imp___pointers__NSApp] ; XREF=0x3789

The jmp at 0x3789 prevents the application from re-validating the license.

The result is that you can use absolutely any irrelevant file to activate the application.

Making it Permanent

We can avoid all the above and just modify the aboutReinitLicenseStatus so that it will permanently indicate that the application is registered:

                                    meth_Controller_aboutReinitLicenseStatus:
00003b74 55                              push       ebp
00003b75 89E5                            mov        ebp, esp
00003b77 56                              push       esi
00003b78 53                              push       ebx
00003b79 83EC20                          sub        esp, 0x20
...
00003b96 7420                            je         0x3BB8
                                       ; Basic Block Input Regs: ebp -  Killed Regs: <nothing>
00003b98 807DF500                        cmp        byte [ss:ebp-0x28+var_29], 0x0
00003b9c 740A                            je         0x3BA8
                                       ; Basic Block Input Regs: <nothing> -  Killed Regs: esp
00003b9e C7442404C3A00200                mov        dword [ss:esp+0x4], 0x2A0C3           ; "This copy is registered"
00003ba6 EB08                            jmp        0x3BB0
                                       ; Basic Block Input Regs: <nothing> -  Killed Regs: esp
00003ba8 C7442404DBA00200                mov        dword [ss:esp+0x4], 0x2A0DB           ; "30 days trial copy" XREF=0x3b9c
                                       ; Basic Block Input Regs: esi -  Killed Regs: esp
00003bb0 893424                          mov        dword [ss:esp], esi                   ; XREF=0x3ba6
00003bb3 E829870600                      call       imp___jump_table___ZNSs6assignEPKc    ; std::string::assign(char const*)
                                       ; Basic Block Input Regs: ebp -  Killed Regs: eax ebx esp
00003bb8 8B4508                          mov        eax, dword [ss:ebp-0x28+arg_0]        ; XREF=0x3b96

We use nops to slide to the registered zone by cancelling out both jes at 0x3b96 respectively 0x3b9c:

00003b92 807DF400                        cmp        byte [ss:ebp+0xFFFFFFFFFFFFFFF4], 0x0
00003b96 90                              nop        
00003b97 90                              nop        
00003b98 807DF500                        cmp        byte [ss:ebp+0xFFFFFFFFFFFFFFF5], 0x0
00003b9c 90                              nop        
00003b9d 90                              nop        
00003b9e C7442404C3A00200                mov        dword [ss:esp+0x4], 0x2A0C3           ; "This copy is registered"
00003ba6 EB08                            jmp        0x3BB0

The result is that the about window will always show ProxyCap registered as in the image above.