As requested by Óscar, here is the crack procedure for Sublime Text 2. Sublime Text 2 is text editor that has a loose protection consisting of a nag screen that randomly pops-up on saving a document.
Disassembling the code, we find the routine that randomly pops-up the nag screen depending on some preconditions in the environment as well as a simple random number generator shunted with the time of execution of the program. The procedure is meant to prevent pop-ing up the nag screen too soon.
The nag window can be made to never show up by just skipping the code of the maybe_show_nag_screen
function. In the original code, the function performs a check to see whether Sublime Text 2 has a valid license (cmp byte [ds:_g_valid_license], 0x
), and it it does then it jumps over to the end of the function. So, the task reduces to making sure that the outcome (postcondition) of the comparison is that we do have a valid license. In order to do that, we turn the jne
:
00000001000f0c00 7570 jne 0x1000f0c72
into a unconditional jump (jmp
):
00000001000f0c00 E96D000000 jmp 0x1000f0c72
Here is how the abbreviated function looks like after the patch:
__Z21maybe_show_nag_screenv: // maybe_show_nag_screen() 00000001000f0bf0 55 push rbp ; XREF=0x1001564a4, 0x100156654 00000001000f0bf1 4889E5 mov rbp, rsp 00000001000f0bf4 53 push rbx 00000001000f0bf5 4883EC08 sub rsp, 0x8 00000001000f0bf9 803D087E510000 cmp byte [ds:_g_valid_license], 0x0 00000001000f0c00 E96D000000 jmp 0x1000f0c72 00000001000f0c05 90 nop 00000001000f0c06 90 nop ... 00000001000f0c72 4883C408 add rsp, 0x8 ; XREF=0x1000f0c00, 0x1000f0c1a, 0x1000f0c3f 00000001000f0c76 5B pop rbx 00000001000f0c77 5D pop rbp 00000001000f0c78 C3 ret
which is sufficient to never show the pop-up
This is optional but if you want Sublime Text 2 to show that it is licensed, and to change the About
window to reflect that:
it is sufficient to alter the About
window drawing function such that the Unregistered
section is never reached. This involves nop
ing a je
around 0x1000855e1
that would lead the program to displaying the Unregistered
text such that it never occurs. This is done by replacing the je
:
00000001000855e1 0F84ED010000 je 0x1000857d4
with a nop
sledge.
The abbreviated about_window
draw function after the change would look like this:
__ZN12about_window4drawEP17px_render_context4rect: // about_window::draw(px_render_context*, rect) 000000010008546c 55 push rbp 000000010008546d 4889E5 mov rbp, rsp 0000000100085470 4157 push r15 0000000100085472 4156 push r14 0000000100085474 4155 push r13 0000000100085476 4154 push r12 0000000100085478 53 push rbx 0000000100085479 4881ECE8040000 sub rsp, 0x4e8 ... 00000001000855ac FF5018 call qword [ds:rax+0x18] 00000001000855af 488D0552345800 lea rax, qword [ds:_g_valid_license] 00000001000855b6 803800 cmp byte [ds:rax], 0x0 00000001000855b9 F30F108560FBFFFF movss xmm0, dword [ss:rbp+0xfffffffffffffb60] 00000001000855c1 F30F5AC0 cvtss2sd xmm0, xmm0 00000001000855c5 F20F118550FBFFFF movsd qword [ss:rbp+0xfffffffffffffb50], xmm0 00000001000855cd F30F108548FBFFFF movss xmm0, dword [ss:rbp+0xfffffffffffffb48] 00000001000855d5 F30F5AC0 cvtss2sd xmm0, xmm0 00000001000855d9 F20F118560FBFFFF movsd qword [ss:rbp+0xfffffffffffffb60], xmm0 00000001000855e1 90 nop 00000001000855e2 90 nop 00000001000855e3 90 nop 00000001000855e4 90 nop 00000001000855e5 90 nop 00000001000855e6 90 nop ... 00000001000855e7 4C8DBD70FBFFFF lea r15, qword [ss:rbp+0xfffffffffffffb70] 00000001000855ee 4C89FF mov rdi, r15 00000001000855f1 E8F60AF8FF call __ZN13string_bufferC1Ev ; string_buffer::string_buffer() 00000001000855f6 8BB570FBFFFF mov esi, dword [ss:rbp+0xfffffffffffffb70] 00000001000855fc 4883C60F add rsi, 0xf 0000000100085600 4C89FF mov rdi, r15 0000000100085603 E8A80BF8FF call __ZN13string_buffer7reserveEm ; string_buffer::reserve(unsigned long) ... 00000001000857ad BAFFFFFFFF mov edx, 0xffffffff 00000001000857b2 4889DF mov rdi, rbx 00000001000857b5 4C89E6 mov rsi, r12 00000001000857b8 4C89F9 mov rcx, r15 00000001000857bb FFD0 call rax 00000001000857bd 488D7DD0 lea rdi, qword [ss:rbp+0xffffffffffffffd0] 00000001000857c1 E85A943300 call imp___stubs___ZNSsD1Ev ; std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() 00000001000857c6 488DBD70FBFFFF lea rdi, qword [ss:rbp+0xfffffffffffffb70] 00000001000857cd E8A609F8FF call __ZN13string_bufferD1Ev ; string_buffer::~string_buffer() 00000001000857d2 EB73 jmp 0x100085847 ... ; Unregistered Section Here (Doesn't Happen)