Skip to content

Instantly share code, notes, and snippets.

@opastorello
Created November 4, 2021 06:43
  • Star 18 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save opastorello/05f02f902339ebc27ea7f20c1838b066 to your computer and use it in GitHub Desktop.
Cracking Sublime Text Build (4121)
# Cracking Sublime Text ( Build 4121 ) Tutorial Analysis
---
Two main changes to be made for best experience. This can be done with script.
### License Key
While it is possible to deduce the format of the license key, there is available ones online to show. Analyse and see that it is still that same format. The main part is the verification of the hash values from the license key that we want to always be "correct". This is also the key that this tutorial will use.
```
----- BEGIN LICENSE -----
username_here
Unlimited User License
EA7E-00000000
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
----- END LICENSE -----
```
#### 1. Return the RSA verification to always be True
Responsible for RSA verification starts from this function.
```c
__int64 __fastcall sub_7FF79C10868E(__int64 a1)
{
unsigned int i; // esi
__int64 v4; // [rsp+0h] [rbp-80h] BYREF
char v5[32]; // [rsp+38h] [rbp-48h] BYREF
char v6[32]; // [rsp+58h] [rbp-28h] BYREF
_OWORD v7[2]; // [rsp+78h] [rbp-8h] BYREF
char v8[32]; // [rsp+98h] [rbp+18h] BYREF
_OWORD v9[2]; // [rsp+B8h] [rbp+38h] BYREF
char v10[32]; // [rsp+D8h] [rbp+58h] BYREF
_OWORD v11[2]; // [rsp+F8h] [rbp+78h] BYREF
_OWORD v12[2]; // [rsp+118h] [rbp+98h] BYREF
char v13[32]; // [rsp+138h] [rbp+B8h] BYREF
__int64 v14; // [rsp+158h] [rbp+D8h]
v14 = -2i64;
sub_7FF79C102DBE(&v4 + 7, "7E-1000\n");
sub_7FF79C102DBE(v7, "EA");
sub_7FF79C102DBE(v9, "User License\n");
sub_7FF79C102DBE(v11, "Unlimited ");
sub_7FF79C102DBE(v12, "Name\n");
sub_7FF79C10B5D7(v10, v12, v11);
sub_7FF79C10B5D7(v8, v10, v9);
sub_7FF79C10B5D7(v6, v8, v7);
sub_7FF79C10B5D7(v13, v6, v5);
sub_7FF79C10277C(v6);
sub_7FF79C10277C(v8);
sub_7FF79C10277C(v10);
sub_7FF79C10277C(v12);
sub_7FF79C10277C(v11);
sub_7FF79C10277C(v9);
sub_7FF79C10277C(v7);
sub_7FF79C10277C(v5);
for ( i = 0; i < 9; ++i )
sub_7FF79C10395C(v13, "00000000000000000000000000000000\n");
// If result is 0,
if ( !root_license_check_sub_7FF6A2C1751C(v13, 0i64, 0i64, 0i64, 0i64, 0i64) )
sub_7FF79C309B74(sub_7FF79C10B632, a1, 480000i64);
return sub_7FF79C10277C(v13);
}
```
Which checks license.
```c
__int64 __fastcall root_license_check_sub_7FF6A2C1751C(__int64 a1, __int64 a2, _DWORD *a3, unsigned int *a4, int *a5, _BYTE *a6)
{
...
...
LOBYTE(v31[0]) = 0;
v10 = v33;
v34 = xmmword_7FF79C737950;
LOBYTE(v33[0]) = 0;
v11 = &qword_7FF79C9D3ED8;
hash_verified = verify_hash_please(v8, (__int64)&qword_7FF79C9D3ED8, (int)v24, &v38, (int)v35, v31, v33);
if ( *((_QWORD *)&v34 + 1) > 0xFui64 )
v10 = (__int64 *)v33[0];
v13 = sub_7FF79C6D8BB0((__int64)v10);
if ( hash_verified )
v14 = (unsigned __int8)Current_set_0(v35, "E52D");
else
v14 = 2;
if ( (unsigned __int64)qword_7FF79C9D3EF0 > 0xF )
v11 = (__int64 *)qword_7FF79C9D3ED8;
sub_7FF79C234E63((__int128 *)v27, (__int64)v11, qword_7FF79C9D3EE8);
if ( v28 ^ 0xEA | v27[14] ^ 0xA5 | v29 ^ 0x56 )
v14 = 2;
...
...
```
This calls the verify_hash_please function (renamned)
```c
__int64 __fastcall verify_hash_please(int a1, __int64 a2, _QWORD *a3, _DWORD *a4, _QWORD *a5, void *a6, void *a7)
{
unsigned int v10; // eax
unsigned int v11; // esi
_BYTE v13[32]; // [rsp+0h] [rbp-80h] BYREF
__int64 v14[4]; // [rsp+38h] [rbp-48h] BYREF
__int64 v15[11]; // [rsp+58h] [rbp-28h] BYREF
v15[4] = -2i64;
*(_OWORD *)&v13[72] = xmmword_7FF79C737950;
v13[56] = 0;
if ( (unsigned __int8)sub_7FF79C6A1C9F(a1, (int)a3, (int)a4, (int)a5, a6, a7, (__int64)&v13[56]) )
{
sub_7FF79C6A20B2((__int64)v15, a3, *a4, a5, a6, (__int64)a7);
LOBYTE(v10) = check_license_hash_sub_7FF79C6A2881(v15, v14, (__int64 *)a2);
v11 = v10;
sub_7FF79C10277C(v15);
}
else
{
v11 = 0;
}
sub_7FF79C10277C(v14);
return v11;
}
```
Invokes to check the RSA hash
```c
/* We just have to return 1 as value !*/
bool __fastcall check_license_hash_sub_7FF79C6A2881(__int64 *a1, __int64 *a2, __int64 *a3)
{
_QWORD rbx1; // rbx
_QWORD r14_1; // r14
_QWORD rsi1; // rsi
_DWORD edi1; // edi
_DWORD er8_1; // er8
_DWORD ebp4; // ebp
_DWORD ebx7; // ebx
bool result; // al
int var2108; // [rsp+50h] [rbp-2108h]
int result_1; // [rsp+54h] [rbp-2104h]
_QWORD var2100[9]; // [rsp+58h] [rbp-2100h]
char var20B8[128]; // [rsp+A0h] [rbp-20B8h]
char var2038[4096]; // [rsp+120h] [rbp-2038h]
char var1038[4152]; // [rsp+1120h] [rbp-1038h]
memmove(&qword_7FF79C9DF810, &off_7FF79C7D8820, 0x1A0ui64);
sub_7FF79C5E80CC(&off_7FF79C7D8670);
edi1 = sub_7FF79C5E8068("sha1");
var2108 = 128;
er8_1 = *((_DWORD *)a2 + 4);
if ( (unsigned __int64)a2[3] > 0xF )
a2 = (__int64 *)*a2;
if ( (unsigned int)sub_7FF79C5E49E8(edi1, (_DWORD)a2, er8_1, (unsigned int)var20B8, (__int64)&var2108) )
return 0;
ebp4 = *((_DWORD *)a3 + 4) / 2;
if ( (unsigned __int64)a3[3] > 0xF )
a3 = (__int64 *)*a3;
sub_7FF79C6A283C(a3, var1038, ebp4);
if ( (unsigned int)sub_7FF79C5ECF3C(var1038, ebp4, var2100) )
return 0;
ebx7 = *((_DWORD *)a1 + 4) >> 1;
if ( (unsigned __int64)a1[3] > 0xF )
a1 = (__int64 *)*a1;
sub_7FF79C6A283C(a1, var2038, ebx7);
result_1 = 0;
if ( (unsigned int)verify_RSA_hash_sub_7FF79C5ED870(var2038, ebx7, var20B8, var2108, 1, edi1, 0, &result_1, var2100) )
return 0;
sub_7FF79C5ECECC(var2100);
return result_1 == 1;
}
```
As we need to get the result to 1, patch to always return 1.
When cracking this, check that this 1 helps. I use 010editor (cracked also) to patch out the bytes.
This are the current bytes see in ida.
```
; want to change to mov rax, 1
; ret
.text:00007FF79C6A2881 41 57 push r15
.text:00007FF79C6A2883 41 56 push r14
.text:00007FF79C6A2885 56 push rsi
.text:00007FF79C6A2886 57 push rdi
.text:00007FF79C6A2887 55 push rbp
.text:00007FF79C6A2888 53 push rbx
.text:00007FF79C6A2889 B8 28 21 00 00 mov eax, 2128h
.text:00007FF79C6A288E E8 5D 62 05 00 call _alloca_probe
.text:00007FF79C6A2893 48 29 C4 sub rsp, rax
.text:00007FF79C6A2896 4C 89 C3 mov rbx, r8
.text:00007FF79C6A2899 49 89 D6 mov r14, rdx
.text:00007FF79C6A289C 48 89 CE mov rsi, rcx
.text:00007FF79C6A289F 48 8D 0D 6A CF 33 00 lea rcx, qword_7FF79C9DF810 ; void *
.text:00007FF79C6A28A6 48 8D 15 73 5F 13 00 lea rdx, off_7FF79C7D8820 ; Src
.text:00007FF79C6A28AD 41 B8 A0 01 00 00 mov r8d, 1A0h ; Size
.text:00007FF79C6A28B3 E8 F8 9E 04 00 call memmove
.text:00007FF79C6A28B8 48 8D 0D B1 5D 13 00 lea rcx, off_7FF79C7D8670 ; Buf2
.text:00007FF79C6A28BF E8 08 58 F4 FF call sub_7FF79C5E80CC
.text:00007FF79C6A28C4 48 8D 0D 23 2E 1B 00 lea rcx, aSha1 ; "sha1"
.text:00007FF79C6A28CB E8 98 57 F4 FF call sub_7FF79C5E8068
```
Change `41 57 41 56 56 57 55 53 b8 28 21 00 00 e8 5d` to `b8 01 00 00 00 c3 55 53 b8 28 21 00 00 e8 5d`.
In the debugger, after changing, should see this.
```asm
00007FF747152881 | B8 01000000 | mov eax,1 |
00007FF747152886 | C3 | ret |
00007FF747152887 | 55 | push rbp |
00007FF747152888 | 53 | push rbx | rbx:"81044230"
00007FF747152889 | B8 28210000 | mov eax,2128 |
00007FF74715288E | E8 5D620500 | call sublime_text.7FF7471A8AF0 |
00007FF747152893 | 48:29C4 | sub rsp,rax |
00007FF747152896 | 4C:89C3 | mov rbx,r8 | rbx:"81044230", r8:&"30819D300D06092A864886F70D010101050003818B0030818702818100D87BA24562F7C5D14A0CFB12B9740C195C6BDC7E6D6EC92BAC0EB29D59E1D9AE67890C2B88C3ABDCAFFE7D4A33DCC1BFBE531A251CEF0C923F06BE79B2328559ACFEE986D5E15E4D1766EA56C4E10657FA74DB0977C3FB7582B78CD47BB2C7F9B252B4A9463D15F6AE6EE9237D54C5481BF3E0B09920190BCFB31E5BE509C33B020111"
00007FF747152899 | 49:89D6 | mov r14,rdx | r14:&"30819D300D06092A864886F70D010101050003818B0030818702818100D87BA24562F7C5D14A0CFB12B9740C195C6BDC7E6D6EC92BAC0EB29D59E1D9AE67890C2B88C3ABDCAFFE7D4A33DCC1BFBE531A251CEF0C923F06BE79B2328559ACFEE986D5E15E4D1766EA56C4E10657FA74DB0977C3FB7582B78CD47BB2C7F9B252B4A9463D15F6AE6EE9237D54C5481BF3E0B09920190BCFB31E5BE509C33B020111", rdx:&"0C0CD4A8CAA317D9CCABD1AC434C984C7E4A0B1377893C3EDD0A5BA1B2EB721C4BAAB4C49B96437D14EB743E7DB55D9C7CA26EE267C3B4EC29B2C65A88D90C59CB6CCBA57DE6177BC02C28268C9A21B06AB1A5B620B09EA
00007FF74715289C | 48:89CE | mov rsi,rcx | rcx:&"TESTING\nUnlimited User License\nEA7E-81044230"
00007FF74715289F | 48:8D0D 6ACF3300 | lea rcx,qword ptr ds:[7FF74748F810] | rcx:&"TESTING\nUnlimited User License\nEA7E-81044230", 00007FF74748F810:&"LibTomMath"
00007FF7471528A6 | 48:8D15 735F1300 | lea rdx,qword ptr ds:[7FF747288820] | rdx:&"0C0CD4A8CAA317D9CCABD1AC434C984C7E4A0B1377893C3EDD0A5BA1B2EB721C4BAAB4C49B96437D14EB743E7DB55D9C7CA26EE267C3B4EC29B2C65A88D90C59CB6CCBA57DE6177BC02C28268C9A21B06AB1A5B620B09EA201C979BD29670B1992DC6D906E3658494AB847395B4C3EA1048CC1D09748ED54CAC9D58590CAD815", 00007FF747288820:&"LibTomMath"
00007FF7471528AD | 41:B8 A0010000 | mov r8d,1A0 |
00007FF7471528B3 | E8 F89E0400 | call sublime_text.7FF74719C7B0 |
00007FF7471528B8 | 48:8D0D B15D1300 | lea rcx,qword ptr ds:[7FF747288670] | rcx:&"TESTING\nUnlimited User License\nEA7E-81044230", 00007FF747288670:&"sha1"
00007FF7471528BF | E8 0858F4FF | call sublime_text.7FF7470980CC |
00007FF7471528C4 | 48:8D0D 232E1B00 | lea rcx,qword ptr ds:[7FF7473056EE] | rcx:&"TESTING\nUnlimited User License\nEA7E-81044230", 00007FF7473056EE:"sha1"
00007FF7471528CB | E8 9857F4FF | call sublime_text.7FF747098068 |
```
---
### 2. Patch so not connect to sublimetext site for license check
Sometime while running with debugger, there is exception. RPC_S_Server_Unavailable is message of exception. See [this](`https://docs.microsoft.com/en-us/troubleshoot/windows-server/user-profiles-and-logon/not-log-on-error-rpc-server-unavailable`). It appears to be DNS failure for connection. This step is not very important but it seems to be better to just do it anyways.
```
#### After submitting the license
INT3 breakpoint at sublime_text.00007FF747152881 (00007FF747152881)!
Thread 66A8 created, Entry: sublime_text.00007FF746C57117
SetThreadName(66A8, "license_notification")
EXCEPTION_DEBUG_INFO:
dwFirstChance: 1
ExceptionCode: 406D1388 (MS_VC_EXCEPTION)
ExceptionFlags: 00000000
ExceptionAddress: 00007FFA5D874F99 kernelbase.00007FFA5D874F99
NumberParameters: 6
ExceptionInformation[00]: 0000000000001000
ExceptionInformation[01]: 00007FF7472F465F sublime_text.00007FF7472F465F
ExceptionInformation[02]: 00000000000066A8
ExceptionInformation[03]: 0000000004D4A306
ExceptionInformation[04]: 0000000000000000
ExceptionInformation[05]: 000000819FEFFBB0
First chance exception on 00007FFA5D874F99 (406D1388, MS_VC_EXCEPTION)!
###### After attempting to close
Thread 275C created, Entry: sublime_text.00007FF746C58A22
SetThreadName(275C, "license_check")
EXCEPTION_DEBUG_INFO:
dwFirstChance: 1
ExceptionCode: 406D1388 (MS_VC_EXCEPTION)
ExceptionFlags: 00000000
ExceptionAddress: 00007FFA5D874F99 kernelbase.00007FFA5D874F99
NumberParameters: 6
ExceptionInformation[00]: 0000000000001000
ExceptionInformation[01]: 00007FF7472F63AD sublime_text.00007FF7472F63AD
ExceptionInformation[02]: 000000000000275C
ExceptionInformation[03]: 0000000000000000
ExceptionInformation[04]: 0000000000000000
ExceptionInformation[05]: 000000819FEFF5C0
First chance exception on 00007FFA5D874F99 (406D1388, MS_VC_EXCEPTION)!
###### After attempting to save the new file
DLL Loaded: 00007FFA56870000 C:\Windows\System32\cscapi.dll
EXCEPTION_DEBUG_INFO:
dwFirstChance: 1
ExceptionCode: 000006BA (RPC_S_SERVER_UNAVAILABLE)
ExceptionFlags: 00000001
ExceptionAddress: 00007FFA5D874F99 kernelbase.00007FFA5D874F99
NumberParameters: 0
First chance exception on 00007FFA5D874F99 (000006BA, RPC_S_SERVER_UNAVAILABLE)!
```
For this case, we do not need the connection to their server. We can find this server address hardcoded in the binary. Patch `license.sublimehq.com` to `127.0.0.1`
```
CHANGE FROM
00007FF7472F4D4E 6C 69 63 65 6E 73 65 2E 73 75 62 6C 69 6D 65 68 license.sublimeh
00007FF7472F4D5E 71 2E 63 6F 6D 00 71 77 65 72 74 79 75 69 6F 70 q.com.qwertyuiop
TO
00007FF7472F4D4E 31 32 37 2e 30 2e 30 2e 31 00 00 00 00 00 00 00 127.0.0.1.......
00007FF7472F4D5E 00 00 00 00 00 00 71 77 65 72 74 79 75 69 6F 70 ......qwertyuiop
```
This is because sublime text will create a thread with the function for license notification.
```c
v2 = root_license_check_sub_7FF6A2C1751C(
v20,
*(v1 + 616) + 16i64,
*(v1 + 616),
&v23,
(*(v1 + 616) + 12i64),
(*(v1 + 616) + 4i64));
...
...
sub_7FF746BB277C(&v15);
if ( !v10 )
warning_message_box_sub_7FF79C23B528(&unk_7FF747485958, sub_7FF746C58716, 0i64);
v11 = CreateThread_sub_7FF746CE7C5C(license_notification_sub_7FF746C57117, v23);
CloseHandle(v11);
...
...
```
In the license notification thread, a request is made and requested to domain `www.sublimetext.com` to check for sublime version checking. For instance, `/license_notification?n=0&b=4121&m=FRnBZEeWU-l-fp1689XdMA`.
license_check thread is also created which query to license.sublimehq.com also for `sublime-license-check` with parameters looking like `/check/29f27acf86591ee7be8691fd97ebcb6d3faf05d1f06431b73603d400fddc724c?n=0&b=4121&m=FRnBZEeWU-l-fp1689XdMA`
```c
__int64 __fastcall license_check_thread_sub_7FF746C58A22(void *Block)
{
...
...
sub_7FF746CE7CB8("license_check");
v2 = v35;
check_license_sub_1405A2221(v35, Block);
v3 = *(Block + 8);
if ( Block )
sub_7FF746BB277C(Block);
j_free_0(Block);
if ( v35[3] > 0xFui64 )
v2 = v35[0];
sub_7FF746CE5017(v2, v35[2], Str);
sub_7FF746BEC654(v32, 32i64, "%d", v3);
v4 = v36;
sub_7FF746DCDFFF(v36);
if ( v36[3] > 0xFui64 )
v4 = v36[0];
sub_7FF746CDD6B1(v4, v36[2], v33);
v8 = xmmword_7FF7471E7940;
v9 = v10;
*&v22 = "/check/";
*(&v22 + 1) = "";
sub_7FF746BB5E62(&v8, &v22);
*&v23 = Str;
*(&v23 + 1) = &v10[strlen(Str) + 520];
sub_7FF746BB5E62(&v8, &v23);
*&v24 = "?n=";
*(&v24 + 1) = "";
sub_7FF746BB5E62(&v8, &v24);
*&v25 = v32;
*(&v25 + 1) = &v32[strlen(v32)];
sub_7FF746BB5E62(&v8, &v25);
*&v26 = "&b=";
*(&v26 + 1) = "";
sub_7FF746BB5E62(&v8, &v26);
*&v27 = "4121";
*(&v27 + 1) = "";
sub_7FF746BB5E62(&v8, &v27);
*&v28 = "&m=";
*(&v28 + 1) = "";
sub_7FF746BB5E62(&v8, &v28);
*&v29 = v33;
*(&v29 + 1) = &v33[strlen(v33)];
sub_7FF746BB5E62(&v8, &v29);
v14 = xmmword_7FF7471E7950;
v13[0] = 0;
v16 = xmmword_7FF7471E7950;
v15[0] = 0;
v18 = xmmword_7FF7471E7950;
v17[0] = 0;
v19 = 0;
v20 = 0i64;
v21 = 0i64;
v12 = 1i64;
strcpy_(v13, "license.sublimehq.com");
sub_7FF746CE5A02(&v8, Src);
sub_7FF746BBB46E(v15, Src);
sub_7FF746BB277C(Src);
strcpy_(v17, "sublime-license-check/3.0");
v5 = v37;
v38 = xmmword_7FF7471E7950;
LOBYTE(v37[0]) = 0;
v30 = &string_http_connection_handler::`vftable';
...
...
}
```
---
#### Python Script
Change `41 57 41 56 56 57 55 53 b8 28 21 00 00 e8 5d` to `b8 01 00 00 00 c3 55 53 b8 28 21 00 00 e8 5d`.
```
CHANGE FROM
00007FF7472F4D4E 6C 69 63 65 6E 73 65 2E 73 75 62 6C 69 6D 65 68 license.sublimeh
00007FF7472F4D5E 71 2E 63 6F 6D 00 71 77 65 72 74 79 75 69 6F 70 q.com.qwertyuiop
TO
00007FF7472F4D4E 31 32 37 2e 30 2e 30 2e 31 00 00 00 00 00 00 00 127.0.0.1.......
00007FF7472F4D5E 00 00 00 00 00 00 71 77 65 72 74 79 75 69 6F 70 ......qwertyuiop
```
Instructions:
- Go to sublimetext folder and extract the sublimetext.exe to Desktop
- Run the python script
```python
# Use Python 3
f = open("./sublime_text.exe","rb")
data = f.read()
f.close
f = open("./sublime_text.exe.back","wb")
f.write(data)
f.close()
f = open("./sublime_text.exe","wb")
data = data.replace(b"\x41\x57\x41\x56\x56\x57\x55\x53\xb8\x28\x21\x00\x00\xe8\x5d",b"\xb8\x01\x00\x00\x00\xc3\x55\x53\xb8\x28\x21\x00\x00\xe8\x5d")
data = data.replace(b"\x6C\x69\x63\x65\x6E\x73\x65\x2E\x73\x75\x62\x6C\x69\x6D\x65\x68\x71\x2E\x63\x6F\x6D\x00\x71\x77\x65\x72\x74\x79\x75\x69\x6F\x70",b"\x31\x32\x37\x2e\x30\x2e\x30\x2e\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x71\x77\x65\x72\x74\x79\x75\x69\x6F\x70")
f.write(data)
f.close()
```
- Put sublimetext.exe back into the original folder.
- Go to Help -> Enter License
```
----- BEGIN LICENSE -----
username_here
Unlimited User License
EA7E-00000000
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
----- END LICENSE -----
```
---
@only1basket
Copy link

Hola Amigo, saludos desde Chile, este script lo debo correr o que ? o se ejecuta en consola?

@opastorello
Copy link
Author

opastorello commented Nov 4, 2021

Hola amigo, saludos desde Brasil, reemplace el archivo crack que generé para usted con el original e ingrese el número de serie a continuación.

----- BEGIN LICENSE -----
only1basket
Licença de usuário ilimitada
EA7E-00000000
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
feedbeef feedbeef feedbeef feedbeef
----- END LICENSE -----

CRACK

@only1basket
Copy link

Gracias Bro!

@25620192
Copy link

谢谢! thank u!

@RezSat
Copy link

RezSat commented Nov 29, 2021

hey, do you have discord ?, you really are an awesome guy

@AJMartel
Copy link

Very nice writeup!
You mentioned 010editor, could you also do a writeup for that as well?

@stelectronic
Copy link

Hi Bro, thanks for detailed guidance! I tried similar way for newset Sublime Text 4 Build x4126 for windows, and it works!

When I tried to do the same modification on Sublime Text 4 Build x4126 for linux (https://download.sublimetext.com/sublime_text_build_4126_x64.tar.xz), I do locate the server IP logic part in hexadecimal mode, but failed to locate where checking result logic is. Could you please share the way how to locate where checking result logic is? Thanks!

@stelectronic
Copy link

@opastorello I learn and apply the IDA you mentioned and I think maybe I have located the hash checking logic in Sublime Text 4 Build x4126 for linux :

Pseudo code:
if ( var0 )
var1 = need_to_do();

Assembly code:
.text:000000000058674A test bl, bl ; Logical Compare
.text:000000000058674C jz short loc_586763 ; Jump if Zero (ZF=1)

In order to get checking okay result always, need to ensure var0=1. Could you please teach me how to do that? I tried to use "test $1, $1" but it's a syntax error...

Thanks a lot!

@stelectronic
Copy link

I find a tricky way, replace jz with jnz instruction and it works. LOL

@ppnoufal
Copy link

Can anyone help me on how to use this trick, I 'm pretty confused..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment