Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1)

в 7:59, , рубрики: crackme, kaspersky, reverse engineering, zeronights, информационная безопасность, отладка, реверс-инжиниринг

Недавно закончился конкурс обратной разработки ZeroNight2015, проводимый «Лабораторией Касперского». Сама организация конкурса, с моей точки зрения, хромала, но статья не об этом. На конкурсе была представлена интересная задача под названием «Смартфон», разбору которой и будет посвящена данная серия статей. Эта статья будет посвящена описанию условия задачи и поиску защитного механизма. Вторая статья затронет оптимизацию скорости работы взламываемой программы посредством внедрения X-кода. В третьей статье будет описан процесс поиска ошибок во внедренном коде с использованием юнит-тестирования.

Начнем с описания задачи. На сайте конкурса дано следующее описание задания и возможность скачать .exe файл программы.

Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 1

После запуска программы видим окно с предложением ввести email и серийный номер.

Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 2

Задача заключается в том, чтобы узнать серийный номер для собственного email адреса. После решения задачи серийный номер отправляется на проверку с помощью формы на сайте, в которой предварительно указывается собственный email и ник, который будет отображаться в рейтинге.

Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 3

После ввода случайного серийного номера в crackme программа предупреждает о том, что мой компьютер слишком медленный и я успею состариться прежде чем дождусь результата проверки. После закрытия предупреждающего сообщения программа безнадежно зависает, загружая по полной одно ядро процессора.

Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 4

Попытка дождаться результата проверки серийного номера обречена на провал и остается только принудительно завершить программу. В этом отчасти уникальность данной задачи. В других задачах этого конкурса результат проверки правильности отображается сразу. Например, в задаче «Кредитная карта» он отображается так:

Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 5

Самое время забраться под капот взламываемой программы и разобраться что же в ней собственно происходит, почему она зависает и какой серийный номер она ожидает от нас получить. Для этих целей я буду использовать интерактивный дизассемблер IDA Pro, демонстрационную версию которого можно скачать на сайте hex-rays.

Начинать поиск защитного механизма будем через перекрестные ссылки на вызов функции, вызывающей окно с сообщением «Your computer is extremely slow for this operation! You'll be a greybeard when you get the result… ;-)», которое появляется сразу после нажатия на кнопку «Check». Для этого откроем вкладку Imports и найдем функцию MessageBoxW из библиотеки USER32.

Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 6

Двойным щелчком переходим по ней к определению функции в таблице импорта. Затем открываем список перекрестных ссылок (горячая клавиша <x>).

Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 7

Достаточно проверить первые три перекрестные ссылки из списка, т. к. последние три элемента списка дублируют первые. Первые два вызова ведут к участкам кода, которые вызывают messageBox с заголовком «Internal Error:». Очевидно, это вывод сообщений о каких-то внутренних ошибках и нам лучше туда не соваться.

.text:004010A4

.text:00401090                 push    ebp
.text:00401091                 mov     ebp, esp
.text:00401093                 mov     eax, [ebp+8]
.text:00401096                 test    eax, eax
.text:00401098                 jz      short loc_4010AA
.text:0040109A                 push    10h
.text:0040109C                 push    offset aInternalError ; "Internal Error:"
.text:004010A1                 push    eax
.text:004010A2                 push    0
.text:004010A4                 call    ds:MessageBoxW

sub_4010B0+14

.text:004010B0                 push    ebp
.text:004010B1                 mov     ebp, esp
.text:004010B3                 mov     eax, [ebp+lpText]
.text:004010B6                 test    eax, eax
.text:004010B8                 jz      short loc_4010CA
.text:004010BA                 push    10h             ; uType
.text:004010BC                 push    offset aInternalError ; "Internal Error:"
.text:004010C1                 push    eax             ; lpText
.text:004010C2                 push    0               ; hWnd
.text:004010C4                 call    ds:MessageBoxW

Третья перекрестная ссылка приводит к искомому вызову функции с параметрами заголовка «Warning» и сообщением «Your computer is extremely slow….».

.text:00404E98                 push    ebx            
.text:00404E99                 push    offset Caption  ; "Warning!"
.text:00404E9E                 push    offset Text     ; "Your computer is extremely slow for thi"...
.text:00404EA3                 push    ebx             ; hWnd
.text:00404EA4                 call    ds:MessageBoxW

Это и есть то место, из которого вызывается окно с предупреждающим сообщением. Вызов происходит из функции sub_404E50.

sub_404E50

.text:00404E50
.text:00404E50 sub_404E50      proc near  ; CODE XREF: sub_401340+1C5
.text:00404E50
.text:00404E50 var_104         = dword ptr -104h
.text:00404E50 var_100         = byte ptr -100h
.text:00404E50 var_A8          = dword ptr -0A8h
.text:00404E50 var_A4          = byte ptr -0A4h
.text:00404E50 var_58          = byte ptr -58h
.text:00404E50 var_57          = byte ptr -57h
.text:00404E50 var_24          = byte ptr -24h
.text:00404E50 var_23          = dword ptr -23h
.text:00404E50 var_1F          = dword ptr -1Fh
.text:00404E50 var_1B          = dword ptr -1Bh
.text:00404E50 var_17          = word ptr -17h
.text:00404E50 var_15          = byte ptr -15h
.text:00404E50 var_14          = byte ptr -14h
.text:00404E50 var_13          = dword ptr -13h
.text:00404E50 var_F           = dword ptr -0Fh
.text:00404E50 var_B           = dword ptr -0Bh
.text:00404E50 var_7           = word ptr -7
.text:00404E50 var_5           = byte ptr -5
.text:00404E50 var_4           = dword ptr -4
.text:00404E50 arg_0           = dword ptr  8
.text:00404E50 arg_4           = dword ptr  0Ch
.text:00404E50 arg_8           = dword ptr  10h
.text:00404E50 arg_C           = dword ptr  14h
.text:00404E50
.text:00404E50                 push    ebp
.text:00404E51                 mov     ebp, esp
.text:00404E53                 sub     esp, 104h
.text:00404E59                 mov     eax, ___security_cookie
.text:00404E5E                 xor     eax, ebp
.text:00404E60                 mov     [ebp+var_4], eax
.text:00404E63                 mov     eax, [ebp+arg_8]
.text:00404E66                 push    ebx
.text:00404E67                 push    esi
.text:00404E68                 mov     esi, [ebp+arg_0]
.text:00404E6B                 xor     ebx, ebx
.text:00404E6D                 push    edi
.text:00404E6E                 mov     [ebp+var_104], eax
.text:00404E74                 cmp     esi, ebx
.text:00404E76                 jz      loc_404FBE
.text:00404E7C                 mov     edi, [ebp+arg_4]
.text:00404E7F                 cmp     edi, ebx
.text:00404E81                 jz      loc_404FBE
.text:00404E87                 cmp     eax, ebx
.text:00404E89                 jz      loc_404FBE
.text:00404E8F                 cmp     [ebp+arg_C], ebx
.text:00404E92                 jz      loc_404FBE
.text:00404E98                 push    ebx             ; uType
.text:00404E99                 push    offset Caption  ; "Warning!"
.text:00404E9E                 push    offset Text     ; "Your computer is extremely slow for thi"...
.text:00404EA3                 push    ebx             ; hWnd
.text:00404EA4                 call    ds:MessageBoxW
.text:00404EAA                 push    4Ch             ; size_t
.text:00404EAC                 lea     eax, [ebp+var_A4]
.text:00404EB2                 push    ebx             ; int
.text:00404EB3                 push    eax             ; void *
.text:00404EB4                 mov     [ebp+var_A8], ebx
.text:00404EBA                 call    _memset
.text:00404EBF                 push    31h             ; size_t
.text:00404EC1                 lea     ecx, [ebp+var_57]
.text:00404EC4                 push    ebx             ; int
.text:00404EC5                 push    ecx             ; void *
.text:00404EC6                 mov     [ebp+var_58], bl
.text:00404EC9                 call    _memset
.text:00404ECE                 lea     edx, [ebp+var_A8]
.text:00404ED4                 push    edx
.text:00404ED5                 call    sub_4047C0
.text:00404EDA                 xor     eax, eax
.text:00404EDC                 mov     [ebp+var_13], eax
.text:00404EDF                 mov     [ebp+var_F], eax
.text:00404EE2                 mov     [ebp+var_B], eax
.text:00404EE5                 mov     [ebp+var_7], ax
.text:00404EE9                 mov     [ebp+var_5], al
.text:00404EEC                 mov     [ebp+var_23], eax
.text:00404EEF                 mov     [ebp+var_1F], eax
.text:00404EF2                 mov     [ebp+var_1B], eax
.text:00404EF5                 mov     [ebp+var_17], ax
.text:00404EF9                 mov     [ebp+var_15], al
.text:00404EFC                 lea     eax, [ebp+var_100]
.text:00404F02                 push    eax
.text:00404F03                 mov     [ebp+var_14], bl
.text:00404F06                 mov     [ebp+var_24], bl
.text:00404F09                 call    sub_401C90
.text:00404F0E                 push    40h
.text:00404F10                 lea     ecx, [ebp+var_A8]
.text:00404F16                 push    ecx
.text:00404F17                 lea     edx, [ebp+var_100]
.text:00404F1D                 push    edx
.text:00404F1E                 call    sub_402410
.text:00404F23                 lea     eax, [ebp+var_14]
.text:00404F26                 push    eax
.text:00404F27                 lea     ecx, [ebp+var_100]
.text:00404F2D                 push    ecx
.text:00404F2E                 call    sub_402540
.text:00404F33                 lea     edx, [ebp+var_100]
.text:00404F39                 push    edx
.text:00404F3A                 call    sub_401C90
.text:00404F3F                 push    edi
.text:00404F40                 lea     eax, [ebp+var_100]
.text:00404F46                 push    esi
.text:00404F47                 push    eax
.text:00404F48                 call    sub_402410
.text:00404F4D                 add     esp, 44h
.text:00404F50                 lea     ecx, [ebp+var_24]
.text:00404F53                 push    ecx
.text:00404F54                 lea     edx, [ebp+var_100]
.text:00404F5A                 push    edx
.text:00404F5B                 call    sub_402540
.text:00404F60                 add     esp, 8
.text:00404F63                 xor     esi, esi
.text:00404F65                 lea     edi, [ebp+var_58]
.text:00404F68                 jmp     short loc_404F70
.text:00404F68 ; ---------------------------------------------------------------------------
.text:00404F6A                 align 10h
.text:00404F70
.text:00404F70 loc_404F70:                             ; CODE XREF: sub_404E50+118
.text:00404F70                                         ; sub_404E50+143
.text:00404F70                 mov     al, [ebp+esi+var_24]
.text:00404F74                 xor     [ebp+esi+var_14], al
.text:00404F78                 movzx   ecx, [ebp+esi+var_14]
.text:00404F7D                 push    ecx
.text:00404F7E                 push    offset a02x     ; "%02X"
.text:00404F83                 push    edi             ; char *
.text:00404F84                 call    _sprintf
.text:00404F89                 inc     esi
.text:00404F8A                 add     esp, 0Ch
.text:00404F8D                 add     edi, 2
.text:00404F90                 cmp     esi, 10h
.text:00404F93                 jl      short loc_404F70
.text:00404F95                 mov     eax, [ebp+var_104]
.text:00404F9B                 lea     edx, [ebp+var_58]
.text:00404F9E                 push    edx             ; char *
.text:00404F9F                 push    eax             ; char *
.text:00404FA0                 call    __stricmp
.text:00404FA5                 add     esp, 8
.text:00404FA8                 pop     edi
.text:00404FA9                 test    eax, eax
.text:00404FAB                 pop     esi
.text:00404FAC                 setz    al
.text:00404FAF                 pop     ebx
.text:00404FB0                 mov     ecx, [ebp+var_4]
.text:00404FB3                 xor     ecx, ebp
.text:00404FB5                 call    @__security_check_cookie@4 ; __security_check_cookie(x)
.text:00404FBA                 mov     esp, ebp
.text:00404FBC                 pop     ebp
.text:00404FBD                 retn
.text:00404FBE ; ---------------------------------------------------------------------------
.text:00404FBE
.text:00404FBE loc_404FBE:                             ; CODE XREF: sub_404E50+26
.text:00404FBE                                         ; sub_404E50+31 ...
.text:00404FBE                 mov     ecx, [ebp+var_4]
.text:00404FC1                 pop     edi
.text:00404FC2                 pop     esi
.text:00404FC3                 xor     ecx, ebp
.text:00404FC5                 xor     al, al
.text:00404FC7                 pop     ebx
.text:00404FC8                 call    @__security_check_cookie@4 ; __security_check_cookie(x)
.text:00404FCD                 mov     esp, ebp
.text:00404FCF                 pop     ebp
.text:00404FD0                 retn
.text:00404FD0 sub_404E50      endp
.text:00404FD0

Назначение функции сразу сложно понять. Пока только очевидно, что функция принимает 4 аргумента. Вначале аргументы проверяются на неравенство нулю. Если же хоть один из них равен нулю, то управление передается на ветку loc_404FBE, которая завершает выполнение функции с возвратом значения 0 в регистре al.

Попробуем взглянуть на код, вызывающий функцию sub_404E50. Для этого перейдем по перекрестной ссылке sub_401340+1C5.

sub_401340

.text:00401340
.text:00401340 sub_401340      proc near               ; CODE XREF: DialogFunc+11E
.text:00401340
.text:00401340 var_10          = dword ptr -10h
.text:00401340 var_C           = dword ptr -0Ch
.text:00401340 var_4           = dword ptr -4
.text:00401340
.text:00401340                 push    ebp
.text:00401341                 mov     ebp, esp
.text:00401343                 push    0FFFFFFFFh
.text:00401345                 push    offset sub_410040
.text:0040134A                 mov     eax, large fs:0
.text:00401350                 push    eax
.text:00401351                 push    ecx
.text:00401352                 push    ebx
.text:00401353                 push    esi
.text:00401354                 push    edi
.text:00401355                 mov     eax, ___security_cookie
.text:0040135A                 xor     eax, ebp
.text:0040135C                 push    eax
.text:0040135D                 lea     eax, [ebp+var_C]
.text:00401360                 mov     large fs:0, eax
.text:00401366                 mov     [ebp+var_10], esp
.text:00401369                 mov     esi, ecx
.text:0040136B                 mov     eax, [esi+54h]
.text:0040136E                 xor     edi, edi
.text:00401370                 push    eax
.text:00401371                 mov     [ebp+var_4], edi
.text:00401374                 call    sub_4077E5
.text:00401379                 mov     eax, [esi+4Ch]
.text:0040137C                 push    eax
.text:0040137D                 mov     [esi+54h], edi
.text:00401380                 call    sub_4077E5
.text:00401385                 mov     eax, [esi+50h]
.text:00401388                 push    eax
.text:00401389                 mov     [esi+4Ch], edi
.text:0040138C                 call    sub_4077E5
.text:00401391                 mov     eax, [esi+48h]
.text:00401394                 push    eax
.text:00401395                 mov     [esi+50h], edi
.text:00401398                 call    sub_4077E5
.text:0040139D                 mov     eax, [esi+18h]
.text:004013A0                 add     esp, 10h
.text:004013A3                 push    eax             ; hWnd
.text:004013A4                 mov     [esi+48h], edi
.text:004013A7                 call    ds:GetWindowTextLengthW
.text:004013AD                 mov     edi, eax
.text:004013AF                 xor     ecx, ecx
.text:004013B1                 lea     ebx, [edi+1]
.text:004013B4                 mov     eax, ebx
.text:004013B6                 mov     edx, 2
.text:004013BB                 mul     edx
.text:004013BD                 seto    cl
.text:004013C0                 neg     ecx
.text:004013C2                 or      ecx, eax
.text:004013C4                 push    ecx
.text:004013C5                 call    unknown_libname_2 ; Microsoft VisualC 2-11/net runtime
.text:004013CA                 mov     [esi+48h], eax
.text:004013CD                 xor     ecx, ecx
.text:004013CF                 mov     [eax+edi*2], cx
.text:004013D3                 mov     edx, [esi+48h]
.text:004013D6                 add     esp, 4
.text:004013D9                 xor     eax, eax
.text:004013DB                 mov     [edx], ax
.text:004013DE                 mov     ecx, [esi+48h]
.text:004013E1                 mov     edx, [esi+18h]
.text:004013E4                 push    ebx             ; nMaxCount
.text:004013E5                 push    ecx             ; lpString
.text:004013E6                 push    edx             ; hWnd
.text:004013E7                 call    ds:GetWindowTextW
.text:004013ED                 mov     eax, [esi+1Ch]
.text:004013F0                 push    eax             ; hWnd
.text:004013F1                 call    ds:GetWindowTextLengthW
.text:004013F7                 mov     ebx, eax
.text:004013F9                 xor     ecx, ecx
.text:004013FB                 lea     eax, [ebx+1]
.text:004013FE                 mov     edx, 2
.text:00401403                 mul     edx
.text:00401405                 seto    cl
.text:00401408                 neg     ecx
.text:0040140A                 or      ecx, eax
.text:0040140C                 push    ecx
.text:0040140D                 call    unknown_libname_2 ; Microsoft VisualC 2-11/net runtime
.text:00401412                 mov     [esi+50h], eax
.text:00401415                 xor     ecx, ecx
.text:00401417                 mov     [eax+ebx*2], cx
.text:0040141B                 mov     edx, [esi+50h]
.text:0040141E                 xor     eax, eax
.text:00401420                 mov     [edx], ax
.text:00401423                 mov     ecx, [esi+50h]
.text:00401426                 mov     edx, [esi+1Ch]
.text:00401429                 add     esp, 4
.text:0040142C                 lea     eax, [ebx+1]
.text:0040142F                 push    eax             ; nMaxCount
.text:00401430                 push    ecx             ; lpString
.text:00401431                 push    edx             ; hWnd
.text:00401432                 call    ds:GetWindowTextW
.text:00401438                 mov     eax, [esi+50h]
.text:0040143B                 mov     ecx, [esi+48h]
.text:0040143E                 push    0
.text:00401440                 push    0
.text:00401442                 push    ebx
.text:00401443                 push    eax
.text:00401444                 push    edi
.text:00401445                 push    ecx
.text:00401446                 push    7Fh
.text:00401448                 push    esi
.text:00401449                 call    sub_4012F0
.text:0040144E                 add     esp, 20h
.text:00401451                 test    eax, eax
.text:00401453                 jnz     short loc_4014A7
.text:00401455                 mov     edx, [esi+38h]
.text:00401458                 push    edx             ; lParam
.text:00401459                 push    eax             ; wParam
.text:0040145A                 mov     eax, [esi+28h]
.text:0040145D                 push    172h            ; Msg
.text:00401462                 push    eax             ; hWnd
.text:00401463                 call    ds:SendMessageW
.text:00401469                 mov     ecx, [esi+2Ch]
.text:0040146C                 push    offset String   ; "Serial is invalid"
.text:00401471                 push    ecx             ; hWnd
.text:00401472                 call    ds:SetWindowTextW
.text:00401478                 mov     edx, [esi+28h]
.text:0040147B                 mov     edi, ds:ShowWindow
.text:00401481                 push    5               ; nCmdShow
.text:00401483                 push    edx             ; hWnd
.text:00401484                 call    edi ; ShowWindow
.text:00401486                 mov     eax, [esi+2Ch]
.text:00401489                 push    5               ; nCmdShow
.text:0040148B                 push    eax             ; hWnd
.text:0040148C                 call    edi ; ShowWindow
.text:0040148E                 mov     dword ptr [esi+58h], 0
.text:00401495                 mov     ecx, [ebp+var_C]
.text:00401498                 mov     large fs:0, ecx
.text:0040149F                 pop     ecx
.text:004014A0                 pop     edi
.text:004014A1                 pop     esi
.text:004014A2                 pop     ebx
.text:004014A3                 mov     esp, ebp
.text:004014A5                 pop     ebp
.text:004014A6                 retn
.text:004014A7 ; ---------------------------------------------------------------------------
.text:004014A7
.text:004014A7 loc_4014A7:                             ; CODE XREF: sub_401340+113
.text:004014A7                 lea     eax, [edi+1]
.text:004014AA                 push    eax
.text:004014AB                 call    unknown_libname_2 ; Microsoft VisualC 2-11/net runtime
.text:004014B0                 mov     [esi+4Ch], eax
.text:004014B3                 mov     byte ptr [eax+edi], 0
.text:004014B7                 mov     ecx, [esi+4Ch]
.text:004014BA                 add     esp, 4
.text:004014BD                 mov     byte ptr [ecx], 0
.text:004014C0                 mov     edx, [esi+48h]
.text:004014C3                 lea     eax, [edi+1]
.text:004014C6                 push    eax             ; size_t
.text:004014C7                 mov     eax, [esi+4Ch]
.text:004014CA                 push    edx             ; wchar_t *
.text:004014CB                 push    eax             ; char *
.text:004014CC                 call    _wcstombs
.text:004014D1                 lea     eax, [ebx+1]
.text:004014D4                 push    eax
.text:004014D5                 call    unknown_libname_2 ; Microsoft VisualC 2-11/net runtime
.text:004014DA                 mov     [esi+54h], eax
.text:004014DD                 mov     byte ptr [eax+ebx], 0
.text:004014E1                 mov     ecx, [esi+54h]
.text:004014E4                 add     esp, 10h
.text:004014E7                 mov     byte ptr [ecx], 0
.text:004014EA                 mov     edx, [esi+50h]
.text:004014ED                 lea     eax, [ebx+1]
.text:004014F0                 push    eax             ; size_t
.text:004014F1                 mov     eax, [esi+54h]
.text:004014F4                 push    edx             ; wchar_t *
.text:004014F5                 push    eax             ; char *
.text:004014F6                 call    _wcstombs
.text:004014FB                 mov     ecx, [esi+54h]
.text:004014FE                 mov     edx, [esi+4Ch]
.text:00401501                 push    ebx
.text:00401502                 push    ecx
.text:00401503                 push    edi
.text:00401504                 push    edx
.text:00401505                 call    sub_404E50
.text:0040150A                 mov     bl, al
.text:0040150C                 add     esp, 1Ch
.text:0040150F                 test    bl, bl
.text:00401511                 jz      short loc_40151D
.text:00401513                 mov     eax, [esi+34h]
.text:00401516                 mov     edi, offset aSerialIsValid ; "Serial is valid"
.text:0040151B                 jmp     short loc_401525
.text:0040151D ; ---------------------------------------------------------------------------
.text:0040151D
.text:0040151D loc_40151D:                             ; CODE XREF: sub_401340+1D1
.text:0040151D                 mov     eax, [esi+38h]
.text:00401520                 mov     edi, offset String ; "Serial is invalid"
.text:00401525
.text:00401525 loc_401525:                             ; CODE XREF: sub_401340+1DB
.text:00401525                 push    eax             ; lParam
.text:00401526                 mov     eax, [esi+28h]
.text:00401529                 push    0               ; wParam
.text:0040152B                 push    172h            ; Msg
.text:00401530                 push    eax             ; hWnd
.text:00401531                 call    ds:SendMessageW
.text:00401537                 mov     ecx, [esi+2Ch]
.text:0040153A                 push    edi             ; lpString
.text:0040153B                 push    ecx             ; hWnd
.text:0040153C                 call    ds:SetWindowTextW
.text:00401542                 mov     edx, [esi+28h]
.text:00401545                 mov     edi, ds:ShowWindow
.text:0040154B                 push    5               ; nCmdShow
.text:0040154D                 push    edx             ; hWnd
.text:0040154E                 call    edi ; ShowWindow
.text:00401550                 mov     eax, [esi+2Ch]
.text:00401553                 push    5               ; nCmdShow
.text:00401555                 push    eax             ; hWnd
.text:00401556                 call    edi ; ShowWindow
.text:00401558                 movzx   ecx, bl
.text:0040155B                 mov     [esi+58h], ecx
.text:0040155E                 mov     ecx, [ebp+var_C]
.text:00401561                 mov     large fs:0, ecx
.text:00401568                 pop     ecx
.text:00401569                 pop     edi
.text:0040156A                 pop     esi
.text:0040156B                 pop     ebx
.text:0040156C                 mov     esp, ebp
.text:0040156E                 pop     ebp
.text:0040156F                 retn
.text:0040156F sub_401340      endp
.text:0040156F

Для наглядности перейдем в режим отображения graph view, нажав пробел.
Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 8
Теперь ясно видно, что от возвращаемого функцией sub_404E50 значения зависит выводимое пользователю сообщение о проверке серийного номера. В случае, если функция возвращает значение 0, то выводится сообщение «Serial is invalid», иначе выводится сообщение «Serial is valid». Однако в нашем случае программа не выводит ни одного из сообщений, т.к. зависает где-то раньше.
Ставим брейкпоинт (<F2>) в начале функции по адресу .text:00401340, запускаем отладку (<F9>) и, используя трассировку (<F8>), находим функцию, которая завешивает выполнение программы. Этой функцией довольно предсказуемо оказывается sub_404E50. Чтобы точно удостовериться в этом, повторно запускаем отладку, поставив брейкпоинт на вызывающей функцию строке .text:00401505, но вместо захода в функцию переходим на следующую команду (ставим курсор на следующую команду и нажимаем <ctrl + N>). После чего продолжаем выполнение программы и видим появившееся сообщение о том, что серийный номер является верным.
Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 9
Так происходит, потому что в регистре ах перед вызовом функции sub_404E50 находилось ненулевое значение, иначе выводилось бы сообщение о неверном серийном номере.
Если бы нам этого было достаточно, то можно было бы в шестнадцатеричном редакторе изменить инструкцию «call sub_404E50» на несколько инструкций «nop» и программа бы принимала любой серийный номер за действительный, но наша задача сгенерировать серийный номер для нашего email. Поэтому продолжим анализ.
Для начала разберемся с аргументами, которые передаются в функцию sub_404E50. В первом блоке инструкций .text:00401340-00401453 дважды вызывается функция GetWindowTextW с разными параметрами hWnd. С помощью отладчика узнаем, что первый вызов получает юникодную строку поля email и сохраняет её по адресу [esi+48h], являющимся предположительно полем объекта, переданного по указателю ecx.

.text:004013DE                 mov     ecx, [esi+48h]
.text:004013E1                 mov     edx, [esi+18h]
.text:004013E4                 push    ebx             ; nMaxCount
.text:004013E5                 push    ecx             ; lpString
.text:004013E6                 push    edx             ; hWnd
.text:004013E7                 call    ds:GetWindowTextW

Аналогично второй вызов сохраняет строку серийного номера по адресу [esi+50h].

.text:00401423                 mov     ecx, [esi+50h]
.text:00401426                 mov     edx, [esi+1Ch]
.text:00401429                 add     esp, 4
.text:0040142C                 lea     eax, [ebx+1]
.text:0040142F                 push    eax             ; nMaxCount
.text:00401430                 push    ecx             ; lpString
.text:00401431                 push    edx             ; hWnd
.text:00401432                 call    ds:GetWindowTextW

Экспериментальным путем обнаруживаем, что управление на ветку .text:00401455 передается в том случае, если серийный номер или email содержит расширенные юникодные символы, например кириллицу.
Если расширенных юникодных символов не обнаружено, то строки преобразуются из wchar_t* в char* с помощью функции wcstombs. Преобразованные строки email'а и серийного номера размещаются по адресам [esi+4Ch] и [esi+54h] соответственно. При этом в регистре edi хранится длина строки email, а в регистре ebx длина серийного номера.

.text:004014C0                 mov     edx, [esi+48h]
.text:004014C3                 lea     eax, [edi+1]
.text:004014C6                 push    eax             ; size_t
.text:004014C7                 mov     eax, [esi+4Ch]
.text:004014CA                 push    edx             ; wchar_t *
.text:004014CB                 push    eax             ; char *
.text:004014CC                 call    _wcstombs

.text:004014EA                 mov     edx, [esi+50h]
.text:004014ED                 lea     eax, [ebx+1]
.text:004014F0                 push    eax             ; size_t
.text:004014F1                 mov     eax, [esi+54h]
.text:004014F4                 push    edx             ; wchar_t *
.text:004014F5                 push    eax             ; char *
.text:004014F6                 call    _wcstombs
.text:004014FB                 mov     ecx, [esi+54h]
.text:004014FE                 mov     edx, [esi+4Ch]
.text:00401501                 push    ebx
.text:00401502                 push    ecx
.text:00401503                 push    edi
.text:00401504                 push    edx
.text:00401505                 call    sub_404E50

Таким образом, становится понятно, что функция sub_404E50 предназначена для проверки серийного номера, и её сигнатура выглядит примерно так:

 bool sub_404E50(char * email_str, size_t email_size, char *serial_str, size_t serial_size);

Теперь время разобраться как же эта функция устроена. Для начала определим в каком месте она зависает, для этого поставим брейкпоинт внутри и потрассируем. Трассировка показала, что зависание происходит по адресу .text:00404ED5 на вызове функции sub_4047C0. Функция sub_4047C0 принимает один аргумент: указатель на локальную переменную var_A8. Содержимое функции sub_4047C0 пугающее и его анализ будет рассмотрен в следующей статье, но для любознательных привожу её код и графическое представление.

sub_4047C0

Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 10

.text:004047C0
.text:004047C0 sub_4047C0      proc near               ; CODE XREF: sub_404E50+85
.text:004047C0
.text:004047C0 var_EC          = dword ptr -0ECh
.text:004047C0 var_E8          = dword ptr -0E8h
.text:004047C0 var_E4          = dword ptr -0E4h
.text:004047C0 var_E0          = dword ptr -0E0h
.text:004047C0 var_D8          = dword ptr -0D8h
.text:004047C0 var_D4          = dword ptr -0D4h
.text:004047C0 var_D0          = dword ptr -0D0h
.text:004047C0 var_CC          = dword ptr -0CCh
.text:004047C0 var_C8          = dword ptr -0C8h
.text:004047C0 var_C4          = dword ptr -0C4h
.text:004047C0 var_BC          = dword ptr -0BCh
.text:004047C0 var_B8          = dword ptr -0B8h
.text:004047C0 var_B4          = dword ptr -0B4h
.text:004047C0 var_B0          = dword ptr -0B0h
.text:004047C0 var_AC          = dword ptr -0ACh
.text:004047C0 var_A8          = dword ptr -0A8h
.text:004047C0 var_A4          = dword ptr -0A4h
.text:004047C0 var_A0          = dword ptr -0A0h
.text:004047C0 var_98          = dword ptr -98h
.text:004047C0 var_94          = dword ptr -94h
.text:004047C0 var_90          = dword ptr -90h
.text:004047C0 var_80          = dword ptr -80h
.text:004047C0 var_7C          = dword ptr -7Ch
.text:004047C0 var_75          = byte ptr -75h
.text:004047C0 var_74          = byte ptr -74h
.text:004047C0 var_73          = byte ptr -73h
.text:004047C0 var_10          = dword ptr -10h
.text:004047C0 var_C           = dword ptr -0Ch
.text:004047C0 var_4           = dword ptr -4
.text:004047C0 arg_0           = dword ptr  8
.text:004047C0
.text:004047C0                 push    ebp
.text:004047C1                 mov     ebp, esp
.text:004047C3                 push    0FFFFFFFFh
.text:004047C5                 push    offset sub_41065C
.text:004047CA                 mov     eax, large fs:0
.text:004047D0                 push    eax
.text:004047D1                 sub     esp, 0E0h
.text:004047D7                 mov     eax, ___security_cookie
.text:004047DC                 xor     eax, ebp
.text:004047DE                 mov     [ebp+var_10], eax
.text:004047E1                 push    ebx
.text:004047E2                 push    esi
.text:004047E3                 push    edi
.text:004047E4                 push    eax
.text:004047E5                 lea     eax, [ebp+var_C]
.text:004047E8                 mov     large fs:0, eax
.text:004047EE                 mov     eax, [ebp+arg_0]
.text:004047F1                 push    1Ch             ; size_t
.text:004047F3                 mov     [ebp+var_D8], eax
.text:004047F9                 call    ??2@YAPAXI@Z    ; operator new(uint)
.text:004047FE                 mov     esi, eax
.text:00404800                 add     esp, 4
.text:00404803                 mov     [ebp+var_B4], esi
.text:00404809                 xor     edi, edi
.text:0040480B                 mov     [ebp+var_4], edi
.text:0040480E                 cmp     esi, edi
.text:00404810                 jz      short loc_40488D
.text:00404812                 mov     dword ptr [esi], offset off_4117D4
.text:00404818                 push    30h             ; size_t
.text:0040481A                 mov     [esi+0Ch], edi
.text:0040481D                 call    ??2@YAPAXI@Z    ; operator new(uint)
.text:00404822                 add     esp, 4
.text:00404825                 cmp     eax, edi
.text:00404827                 jz      short loc_40485A
.text:00404829                 mov     [esi+8], eax
.text:0040482C                 mov     [eax], eax
.text:0040482E                 mov     eax, [esi+8]
.text:00404831                 mov     [eax+4], eax
.text:00404834                 mov     eax, [esi+8]
.text:00404837                 mov     [eax+8], eax
.text:0040483A                 mov     ecx, [esi+8]
.text:0040483D                 mov     byte ptr [ecx+2Ch], 1
.text:00404841                 mov     edx, [esi+8]
.text:00404844                 mov     byte ptr [edx+2Dh], 1
.text:00404848                 mov     dword ptr [esi+14h], 200h
.text:0040484F                 mov     [esi+18h], edi
.text:00404852                 mov     [ebp+var_98], esi
.text:00404858                 jmp     short loc_404893
.text:0040485A ; ---------------------------------------------------------------------------
.text:0040485A
.text:0040485A loc_40485A:                             ; CODE XREF: sub_4047C0+67
.text:0040485A                 lea     eax, [ebp+var_94]
.text:00404860                 push    eax
.text:00404861                 lea     ecx, [ebp+var_A4]
.text:00404867                 mov     [ebp+var_94], edi
.text:0040486D                 call    ??0exception@std@@QAE@ABQBD@Z ; std::exception::exception(char const * const &)
.text:00404872                 push    offset unk_413D14
.text:00404877                 lea     ecx, [ebp+var_A4]
.text:0040487D                 push    ecx
.text:0040487E                 mov     [ebp+var_A4], offset off_4116C0
.text:00404888                 call    __CxxThrowException@8 ; _CxxThrowException(x,x)
.text:0040488D ; ---------------------------------------------------------------------------
.text:0040488D
.text:0040488D loc_40488D:                             ; CODE XREF: sub_4047C0+50
.text:0040488D                 mov     [ebp+var_98], edi
.text:00404893
.text:00404893 loc_404893:                             ; CODE XREF: sub_4047C0+98
.text:00404893                 mov     [ebp+var_A8], edi
.text:00404899                 mov     [ebp+var_A4], edi
.text:0040489F                 mov     [ebp+var_A0], edi
.text:004048A5                 mov     [ebp+var_4], 1
.text:004048AC                 mov     [ebp+var_CC], edi
.text:004048B2                 mov     [ebp+var_C8], edi
.text:004048B8                 mov     [ebp+var_C4], edi
.text:004048BE                 push    18h             ; size_t
.text:004048C0                 mov     byte ptr [ebp+var_4], 2
.text:004048C4                 call    ??2@YAPAXI@Z    ; operator new(uint)
.text:004048C9                 add     esp, 4
.text:004048CC                 mov     [ebp+var_94], eax
.text:004048D2                 mov     byte ptr [ebp+var_4], 3
.text:004048D6                 cmp     eax, edi
.text:004048D8                 jz      short loc_4048EB
.text:004048DA                 push    60h
.text:004048DC                 mov     ecx, eax
.text:004048DE                 call    sub_4033D0
.text:004048E3                 mov     [ebp+var_B8], eax
.text:004048E9                 jmp     short loc_4048F1
.text:004048EB ; ---------------------------------------------------------------------------
.text:004048EB
.text:004048EB loc_4048EB:                             ; CODE XREF: sub_4047C0+118
.text:004048EB                 mov     [ebp+var_B8], edi
.text:004048F1
.text:004048F1 loc_4048F1:                             ; CODE XREF: sub_4047C0+129
.text:004048F1                 push    18h             ; size_t
.text:004048F3                 mov     byte ptr [ebp+var_4], 2
.text:004048F7                 call    ??2@YAPAXI@Z    ; operator new(uint)
.text:004048FC                 add     esp, 4
.text:004048FF                 mov     [ebp+var_94], eax
.text:00404905                 mov     byte ptr [ebp+var_4], 4
.text:00404909                 cmp     eax, edi
.text:0040490B                 jz      short loc_404921
.text:0040490D                 push    200h
.text:00404912                 mov     ecx, eax
.text:00404914                 call    sub_4033D0
.text:00404919                 mov     [ebp+var_AC], eax
.text:0040491F                 jmp     short loc_404927
.text:00404921 ; ---------------------------------------------------------------------------
.text:00404921
.text:00404921 loc_404921:                             ; CODE XREF: sub_4047C0+14B
.text:00404921                 mov     [ebp+var_AC], edi
.text:00404927
.text:00404927 loc_404927:                             ; CODE XREF: sub_4047C0+15F
.text:00404927                 mov     ebx, [ebp+var_C8]
.text:0040492D                 mov     [ebp+var_BC], edi
.text:00404933                 mov     edi, [ebp+var_98]
.text:00404939                 mov     byte ptr [ebp+var_4], 2
.text:0040493D
.text:0040493D loc_40493D:                             ; CODE XREF: sub_4047C0+4B9
.text:0040493D                 mov     eax, [ebp+var_BC]
.text:00404943                 inc     eax
.text:00404944                 mov     [ebp+var_94], eax
.text:0040494A                 test    eax, eax
.text:0040494C                 jle     loc_404B8A
.text:00404952                 mov     ecx, [ebp+var_A4]
.text:00404958                 sub     ecx, [ebp+var_A8]
.text:0040495E                 mov     ebx, [ebp+var_AC]
.text:00404964                 mov     eax, 92492493h
.text:00404969                 imul    ecx
.text:0040496B                 add     edx, ecx
.text:0040496D                 sar     edx, 4
.text:00404970                 mov     eax, edx
.text:00404972                 shr     eax, 1Fh
.text:00404975                 add     eax, edx
.text:00404977                 mov     edx, [ebp+var_94]
.text:0040497D                 mov     [ebp+var_D4], eax
.text:00404983                 mov     [ebp+var_B4], edx
.text:00404989                 lea     esp, [esp+0]
.text:00404990
.text:00404990 loc_404990:                             ; CODE XREF: sub_4047C0+3BE
.text:00404990                 push    63h             ; size_t
.text:00404992                 lea     eax, [ebp+var_73]
.text:00404995                 push    0               ; int
.text:00404997                 push    eax             ; void *
.text:00404998                 mov     [ebp+var_74], 0
.text:0040499C                 call    _memset
.text:004049A1                 add     esp, 0Ch
.text:004049A4                 xor     esi, esi
.text:004049A6                 call    _rand
.text:004049AB                 cdq
.text:004049AC                 mov     ecx, 28h
.text:004049B1                 idiv    ecx
.text:004049B3                 add     edx, 14h
.text:004049B6                 test    edx, edx
.text:004049B8                 jle     short loc_4049E9
.text:004049BA                 lea     ebx, [ebx+0]
.text:004049C0
.text:004049C0 loc_4049C0:                             ; CODE XREF: sub_4047C0+227
.text:004049C0                 call    _rand
.text:004049C5                 cdq
.text:004049C6                 mov     ecx, 60h
.text:004049CB                 idiv    ecx
.text:004049CD                 inc     esi
.text:004049CE                 add     dl, 20h
.text:004049D1                 mov     [ebp+esi+var_75], dl
.text:004049D5                 call    _rand
.text:004049DA                 cdq
.text:004049DB                 mov     ecx, 28h
.text:004049E0                 idiv    ecx
.text:004049E2                 add     edx, 14h
.text:004049E5                 cmp     esi, edx
.text:004049E7                 jl      short loc_4049C0
.text:004049E9
.text:004049E9 loc_4049E9:                             ; CODE XREF: sub_4047C0+1F8
.text:004049E9                 lea     eax, [ebp+var_74]
.text:004049EC                 mov     [ebp+var_7C], 0Fh
.text:004049F3                 mov     [ebp+var_80], 0
.text:004049FA                 mov     byte ptr [ebp+var_90], 0
.text:00404A01                 lea     edx, [eax+1]
.text:00404A04
.text:00404A04 loc_404A04:                             ; CODE XREF: sub_4047C0+249
.text:00404A04                 mov     cl, [eax]
.text:00404A06                 inc     eax
.text:00404A07                 test    cl, cl
.text:00404A09                 jnz     short loc_404A04
.text:00404A0B                 sub     eax, edx
.text:00404A0D                 push    eax             ; size_t
.text:00404A0E                 lea     edx, [ebp+var_74]
.text:00404A11                 push    edx             ; void *
.text:00404A12                 lea     ecx, [ebp+var_90]
.text:00404A18                 call    sub_405BB0
.text:00404A1D                 mov     eax, [edi]
.text:00404A1F                 mov     edx, [eax+4]
.text:00404A22                 lea     ecx, [ebp+var_90]
.text:00404A28                 push    ecx
.text:00404A29                 mov     ecx, edi
.text:00404A2B                 mov     byte ptr [ebp+var_4], 5
.text:00404A2F                 call    edx
.text:00404A31                 cmp     [ebp+var_7C], 10h
.text:00404A35                 mov     byte ptr [ebp+var_4], 2
.text:00404A39                 jb      short loc_404A4A
.text:00404A3B                 mov     eax, [ebp+var_90]
.text:00404A41                 push    eax             ; void *
.text:00404A42                 call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:00404A47                 add     esp, 4
.text:00404A4A
.text:00404A4A loc_404A4A:                             ; CODE XREF: sub_4047C0+279
.text:00404A4A                 cmp     [ebp+var_D4], 0
.text:00404A51                 jbe     loc_404B10
.text:00404A57                 mov     ecx, [ebp+var_D4]
.text:00404A5D                 mov     esi, [ebp+var_A8]
.text:00404A63                 mov     [ebp+var_D0], ecx
.text:00404A69                 lea     esp, [esp+0]
.text:00404A70
.text:00404A70 loc_404A70:                             ; CODE XREF: sub_4047C0+34A
.text:00404A70                 cmp     [ebp+var_BC], 3
.text:00404A77                 jl      short loc_404A8A
.text:00404A79                 mov     ecx, [ebp+var_B8]
.text:00404A7F                 mov     edx, [ecx]
.text:00404A81                 mov     eax, [edx+8]
.text:00404A84                 call    eax
.text:00404A86                 test    al, al
.text:00404A88                 jz      short loc_404B01
.text:00404A8A
.text:00404A8A loc_404A8A:                             ; CODE XREF: sub_4047C0+2B7
.text:00404A8A                 lea     eax, [ebp+var_74]
.text:00404A8D                 mov     [ebp+var_7C], 0Fh
.text:00404A94                 mov     [ebp+var_80], 0
.text:00404A9B                 mov     byte ptr [ebp+var_90], 0
.text:00404AA2                 lea     edx, [eax+1]
.text:00404AA5
.text:00404AA5 loc_404AA5:                             ; CODE XREF: sub_4047C0+2EA
.text:00404AA5                 mov     cl, [eax]
.text:00404AA7                 inc     eax
.text:00404AA8                 test    cl, cl
.text:00404AAA                 jnz     short loc_404AA5
.text:00404AAC                 sub     eax, edx
.text:00404AAE                 push    eax             ; size_t
.text:00404AAF                 lea     ecx, [ebp+var_74]
.text:00404AB2                 push    ecx             ; void *
.text:00404AB3                 lea     ecx, [ebp+var_90]
.text:00404AB9                 call    sub_405BB0
.text:00404ABE                 mov     edx, [ebx]
.text:00404AC0                 mov     edx, [edx+4]
.text:00404AC3                 sub     esp, 14h
.text:00404AC6                 mov     eax, esp
.text:00404AC8                 mov     [ebp+var_B0], esp
.text:00404ACE                 push    eax
.text:00404ACF                 mov     ecx, ebx
.text:00404AD1                 mov     byte ptr [ebp+var_4], 6
.text:00404AD5                 call    edx
.text:00404AD7                 mov     eax, [edi]
.text:00404AD9                 mov     edx, [eax+8]
.text:00404ADC                 lea     ecx, [ebp+var_90]
.text:00404AE2                 push    ecx
.text:00404AE3                 push    esi
.text:00404AE4                 mov     ecx, edi
.text:00404AE6                 call    edx
.text:00404AE8                 cmp     [ebp+var_7C], 10h
.text:00404AEC                 mov     byte ptr [ebp+var_4], 2
.text:00404AF0                 jb      short loc_404B01
.text:00404AF2                 mov     eax, [ebp+var_90]
.text:00404AF8                 push    eax             ; void *
.text:00404AF9                 call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:00404AFE                 add     esp, 4
.text:00404B01
.text:00404B01 loc_404B01:                             ; CODE XREF: sub_4047C0+2C8
.text:00404B01                                         ; sub_4047C0+330
.text:00404B01                 add     esi, 1Ch
.text:00404B04                 dec     [ebp+var_D0]
.text:00404B0A                 jnz     loc_404A70
.text:00404B10
.text:00404B10 loc_404B10:                             ; CODE XREF: sub_4047C0+291
.text:00404B10                 lea     eax, [ebp+var_74]
.text:00404B13                 mov     [ebp+var_7C], 0Fh
.text:00404B1A                 mov     [ebp+var_80], 0
.text:00404B21                 mov     byte ptr [ebp+var_90], 0
.text:00404B28                 lea     edx, [eax+1]
.text:00404B2B                 jmp     short loc_404B30
.text:00404B2B ; ---------------------------------------------------------------------------
.text:00404B2D                 align 10h
.text:00404B30
.text:00404B30 loc_404B30:                             ; CODE XREF: sub_4047C0+36B
.text:00404B30                                         ; sub_4047C0+375
.text:00404B30                 mov     cl, [eax]
.text:00404B32                 inc     eax
.text:00404B33                 test    cl, cl
.text:00404B35                 jnz     short loc_404B30
.text:00404B37                 sub     eax, edx
.text:00404B39                 push    eax             ; size_t
.text:00404B3A                 lea     ecx, [ebp+var_74]
.text:00404B3D                 push    ecx             ; void *
.text:00404B3E                 lea     ecx, [ebp+var_90]
.text:00404B44                 call    sub_405BB0
.text:00404B49                 lea     edx, [ebp+var_90]
.text:00404B4F                 push    edx
.text:00404B50                 lea     ecx, [ebp+var_CC]
.text:00404B56                 mov     byte ptr [ebp+var_4], 7
.text:00404B5A                 call    sub_4072B0
.text:00404B5F                 cmp     [ebp+var_7C], 10h
.text:00404B63                 mov     byte ptr [ebp+var_4], 2
.text:00404B67                 jb      short loc_404B78
.text:00404B69                 mov     eax, [ebp+var_90]
.text:00404B6F                 push    eax             ; void *
.text:00404B70                 call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:00404B75                 add     esp, 4
.text:00404B78
.text:00404B78 loc_404B78:                             ; CODE XREF: sub_4047C0+3A7
.text:00404B78                 dec     [ebp+var_B4]
.text:00404B7E                 jnz     loc_404990
.text:00404B84                 mov     ebx, [ebp+var_C8]
.text:00404B8A
.text:00404B8A loc_404B8A:                             ; CODE XREF: sub_4047C0+18C
.text:00404B8A                 mov     ecx, [ebp+var_A4]
.text:00404B90                 cmp     [ebp+var_A8], ecx
.text:00404B96                 jz      short loc_404BF9
.text:00404B98                 mov     edx, [ebp+var_B0]
.text:00404B9E                 mov     eax, [ebp+var_A8]
.text:00404BA4                 push    edx
.text:00404BA5                 push    eax             ; void *
.text:00404BA6                 mov     eax, ecx
.text:00404BA8                 push    eax             ; int
.text:00404BA9                 push    eax             ; int
.text:00404BAA                 call    sub_406140
.text:00404BAF                 mov     edi, eax
.text:00404BB1                 add     esp, 10h
.text:00404BB4                 mov     esi, edi
.text:00404BB6                 cmp     edi, [ebp+var_A4]
.text:00404BBC                 jz      short loc_404BED
.text:00404BBE                 mov     edi, edi
.text:00404BC0
.text:00404BC0 loc_404BC0:                             ; CODE XREF: sub_4047C0+42B
.text:00404BC0                 cmp     dword ptr [esi+14h], 10h
.text:00404BC4                 jb      short loc_404BD1
.text:00404BC6                 mov     eax, [esi]
.text:00404BC8                 push    eax             ; void *
.text:00404BC9                 call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:00404BCE                 add     esp, 4
.text:00404BD1
.text:00404BD1 loc_404BD1:                             ; CODE XREF: sub_4047C0+404
.text:00404BD1                 mov     dword ptr [esi+14h], 0Fh
.text:00404BD8                 mov     dword ptr [esi+10h], 0
.text:00404BDF                 mov     byte ptr [esi], 0
.text:00404BE2                 add     esi, 1Ch
.text:00404BE5                 cmp     esi, [ebp+var_A4]
.text:00404BEB                 jnz     short loc_404BC0
.text:00404BED
.text:00404BED loc_404BED:                             ; CODE XREF: sub_4047C0+3FC
.text:00404BED                 mov     [ebp+var_A4], edi
.text:00404BF3                 mov     edi, [ebp+var_98]
.text:00404BF9
.text:00404BF9 loc_404BF9:                             ; CODE XREF: sub_4047C0+3D6
.text:00404BF9                 lea     ecx, [ebp+var_CC]
.text:00404BFF                 push    ecx
.text:00404C00                 lea     ecx, [ebp+var_A8]
.text:00404C06                 call    sub_406F10
.text:00404C0B                 cmp     [ebp+var_CC], ebx
.text:00404C11                 jz      short loc_404C6A
.text:00404C13                 mov     edx, [ebp+var_B0]
.text:00404C19                 mov     eax, [ebp+var_CC]
.text:00404C1F                 push    edx
.text:00404C20                 push    eax             ; void *
.text:00404C21                 push    ebx             ; int
.text:00404C22                 push    ebx             ; int
.text:00404C23                 call    sub_406140
.text:00404C28                 mov     edi, eax
.text:00404C2A                 add     esp, 10h
.text:00404C2D                 mov     esi, edi
.text:00404C2F                 cmp     edi, ebx
.text:00404C31                 jz      short loc_404C5C
.text:00404C33
.text:00404C33 loc_404C33:                             ; CODE XREF: sub_4047C0+49A
.text:00404C33                 cmp     dword ptr [esi+14h], 10h
.text:00404C37                 jb      short loc_404C44
.text:00404C39                 mov     eax, [esi]
.text:00404C3B                 push    eax             ; void *
.text:00404C3C                 call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:00404C41                 add     esp, 4
.text:00404C44
.text:00404C44 loc_404C44:                             ; CODE XREF: sub_4047C0+477
.text:00404C44                 mov     dword ptr [esi+14h], 0Fh
.text:00404C4B                 mov     dword ptr [esi+10h], 0
.text:00404C52                 mov     byte ptr [esi], 0
.text:00404C55                 add     esi, 1Ch
.text:00404C58                 cmp     esi, ebx
.text:00404C5A                 jnz     short loc_404C33
.text:00404C5C
.text:00404C5C loc_404C5C:                             ; CODE XREF: sub_4047C0+471
.text:00404C5C                 mov     ebx, edi
.text:00404C5E                 mov     edi, [ebp+var_98]
.text:00404C64                 mov     [ebp+var_C8], ebx
.text:00404C6A
.text:00404C6A loc_404C6A:                             ; CODE XREF: sub_4047C0+451
.text:00404C6A                 mov     eax, [ebp+var_94]
.text:00404C70                 mov     [ebp+var_BC], eax
.text:00404C76                 cmp     eax, 32h
.text:00404C79                 jl      loc_40493D
.text:00404C7F                 mov     edi, [ebp+var_A4]
.text:00404C85                 cmp     [ebp+var_A8], edi
.text:00404C8B                 jz      short loc_404CE7
.text:00404C8D                 mov     ecx, [ebp+var_B0]
.text:00404C93                 mov     edx, [ebp+var_A8]
.text:00404C99                 push    ecx
.text:00404C9A                 push    edx             ; void *
.text:00404C9B                 push    edi             ; int
.text:00404C9C                 push    edi             ; int
.text:00404C9D                 call    sub_406140
.text:00404CA2                 mov     ebx, eax
.text:00404CA4                 add     esp, 10h
.text:00404CA7                 mov     esi, ebx
.text:00404CA9                 cmp     ebx, edi
.text:00404CAB                 jz      short loc_404CD9
.text:00404CAD                 lea     ecx, [ecx+0]
.text:00404CB0
.text:00404CB0 loc_404CB0:                             ; CODE XREF: sub_4047C0+517
.text:00404CB0                 cmp     dword ptr [esi+14h], 10h
.text:00404CB4                 jb      short loc_404CC1
.text:00404CB6                 mov     eax, [esi]
.text:00404CB8                 push    eax             ; void *
.text:00404CB9                 call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:00404CBE                 add     esp, 4
.text:00404CC1
.text:00404CC1 loc_404CC1:                             ; CODE XREF: sub_4047C0+4F4
.text:00404CC1                 mov     dword ptr [esi+14h], 0Fh
.text:00404CC8                 mov     dword ptr [esi+10h], 0
.text:00404CCF                 mov     byte ptr [esi], 0
.text:00404CD2                 add     esi, 1Ch
.text:00404CD5                 cmp     esi, edi
.text:00404CD7                 jnz     short loc_404CB0
.text:00404CD9
.text:00404CD9 loc_404CD9:                             ; CODE XREF: sub_4047C0+4EB
.text:00404CD9                 mov     edi, ebx
.text:00404CDB                 mov     ebx, [ebp+var_C8]
.text:00404CE1                 mov     [ebp+var_A4], edi
.text:00404CE7
.text:00404CE7 loc_404CE7:                             ; CODE XREF: sub_4047C0+4CB
.text:00404CE7                 mov     esi, [ebp+var_98]
.text:00404CED                 mov     eax, [esi]
.text:00404CEF                 mov     edx, [eax+10h]
.text:00404CF2                 lea     ecx, [ebp+var_EC]
.text:00404CF8                 push    ecx
.text:00404CF9                 mov     ecx, esi
.text:00404CFB                 call    edx
.text:00404CFD                 mov     eax, [ebp+var_D8]
.text:00404D03                 push    eax
.text:00404D04                 lea     ecx, [ebp+var_EC]
.text:00404D0A                 mov     byte ptr [ebp+var_4], 8
.text:00404D0E                 call    sub_402920
.text:00404D13                 mov     ecx, [ebp+var_B8]
.text:00404D19                 test    ecx, ecx
.text:00404D1B                 jz      short loc_404D25
.text:00404D1D                 mov     edx, [ecx]
.text:00404D1F                 mov     eax, [edx]
.text:00404D21                 push    1
.text:00404D23                 call    eax
.text:00404D25
.text:00404D25 loc_404D25:                             ; CODE XREF: sub_4047C0+55B
.text:00404D25                 mov     ecx, [ebp+var_AC]
.text:00404D2B                 test    ecx, ecx
.text:00404D2D                 jz      short loc_404D37
.text:00404D2F                 mov     edx, [ecx]
.text:00404D31                 mov     eax, [edx]
.text:00404D33                 push    1
.text:00404D35                 call    eax
.text:00404D37
.text:00404D37 loc_404D37:                             ; CODE XREF: sub_4047C0+56D
.text:00404D37                 mov     edx, [esi]
.text:00404D39                 mov     eax, [edx]
.text:00404D3B                 push    1
.text:00404D3D                 mov     ecx, esi
.text:00404D3F                 call    eax
.text:00404D41                 mov     eax, [ebp+var_E8]
.text:00404D47                 mov     ecx, [ebp+var_E4]
.text:00404D4D                 mov     [ebp+var_EC], offset off_41171C
.text:00404D57                 cmp     eax, ecx
.text:00404D59                 jz      short loc_404D75
.text:00404D5B                 push    0               ; size_t
.text:00404D5D                 push    ecx             ; void *
.text:00404D5E                 push    eax             ; void *
.text:00404D5F                 mov     esi, eax
.text:00404D61                 call    _memcpy_0
.text:00404D66                 mov     eax, [ebp+var_E8]
.text:00404D6C                 add     esp, 0Ch
.text:00404D6F                 mov     [ebp+var_E4], esi
.text:00404D75
.text:00404D75 loc_404D75:                             ; CODE XREF: sub_4047C0+599
.text:00404D75                 xor     esi, esi
.text:00404D77                 cmp     eax, esi
.text:00404D79                 jz      short loc_404D84
.text:00404D7B                 push    eax             ; void *
.text:00404D7C                 call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:00404D81                 add     esp, 4
.text:00404D84
.text:00404D84 loc_404D84:                             ; CODE XREF: sub_4047C0+5B9
.text:00404D84                 mov     [ebp+var_E8], esi
.text:00404D8A                 mov     [ebp+var_E4], esi
.text:00404D90                 mov     [ebp+var_E0], esi
.text:00404D96                 cmp     [ebp+var_CC], esi
.text:00404D9C                 jz      short loc_404DE2
.text:00404D9E                 mov     esi, [ebp+var_CC]
.text:00404DA4                 cmp     esi, ebx
.text:00404DA6                 jz      short loc_404DD1
.text:00404DA8
.text:00404DA8 loc_404DA8:                             ; CODE XREF: sub_4047C0+60F
.text:00404DA8                 cmp     dword ptr [esi+14h], 10h
.text:00404DAC                 jb      short loc_404DB9
.text:00404DAE                 mov     ecx, [esi]
.text:00404DB0                 push    ecx             ; void *
.text:00404DB1                 call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:00404DB6                 add     esp, 4
.text:00404DB9
.text:00404DB9 loc_404DB9:                             ; CODE XREF: sub_4047C0+5EC
.text:00404DB9                 mov     dword ptr [esi+14h], 0Fh
.text:00404DC0                 mov     dword ptr [esi+10h], 0
.text:00404DC7                 mov     byte ptr [esi], 0
.text:00404DCA                 add     esi, 1Ch
.text:00404DCD                 cmp     esi, ebx
.text:00404DCF                 jnz     short loc_404DA8
.text:00404DD1
.text:00404DD1 loc_404DD1:                             ; CODE XREF: sub_4047C0+5E6
.text:00404DD1                 mov     edx, [ebp+var_CC]
.text:00404DD7                 push    edx             ; void *
.text:00404DD8                 call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:00404DDD                 add     esp, 4
.text:00404DE0                 xor     esi, esi
.text:00404DE2
.text:00404DE2 loc_404DE2:                             ; CODE XREF: sub_4047C0+5DC
.text:00404DE2                 cmp     [ebp+var_A8], esi
.text:00404DE8                 jz      short loc_404E34
.text:00404DEA                 mov     esi, [ebp+var_A8]
.text:00404DF0                 cmp     esi, edi
.text:00404DF2                 jz      short loc_404E25
.text:00404DF4                 mov     ebx, 0Fh
.text:00404DF9                 lea     esp, [esp+0]
.text:00404E00
.text:00404E00 loc_404E00:                             ; CODE XREF: sub_4047C0+663
.text:00404E00                 cmp     dword ptr [esi+14h], 10h
.text:00404E04                 jb      short loc_404E11
.text:00404E06                 mov     eax, [esi]
.text:00404E08                 push    eax             ; void *
.text:00404E09                 call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:00404E0E                 add     esp, 4
.text:00404E11
.text:00404E11 loc_404E11:                             ; CODE XREF: sub_4047C0+644
.text:00404E11                 mov     [esi+14h], ebx
.text:00404E14                 mov     dword ptr [esi+10h], 0
.text:00404E1B                 mov     byte ptr [esi], 0
.text:00404E1E                 add     esi, 1Ch
.text:00404E21                 cmp     esi, edi
.text:00404E23                 jnz     short loc_404E00
.text:00404E25
.text:00404E25 loc_404E25:                             ; CODE XREF: sub_4047C0+632
.text:00404E25                 mov     ecx, [ebp+var_A8]
.text:00404E2B                 push    ecx             ; void *
.text:00404E2C                 call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:00404E31                 add     esp, 4
.text:00404E34
.text:00404E34 loc_404E34:                             ; CODE XREF: sub_4047C0+628
.text:00404E34                 mov     ecx, [ebp+var_C]
.text:00404E37                 mov     large fs:0, ecx
.text:00404E3E                 pop     ecx
.text:00404E3F                 pop     edi
.text:00404E40                 pop     esi
.text:00404E41                 pop     ebx
.text:00404E42                 mov     ecx, [ebp+var_10]
.text:00404E45                 xor     ecx, ebp
.text:00404E47                 call    @__security_check_cookie@4 ; __security_check_cookie(x)
.text:00404E4C                 mov     esp, ebp
.text:00404E4E                 pop     ebp
.text:00404E4F                 retn
.text:00404E4F sub_4047C0      endp
.text:00404E4F

Пока же разберемся с остальным содержимым функции sub_404E50. Вызов функции sub_401C90 инициализирует первые 18 байт переменной var_100 некоторым константным значением.

.text:00404EFC                 lea     eax, [ebp+var_100]
.text:00404F02                 push    eax
...
.text:00404F09                 call    sub_401C90

sub_401C90

.text:00401C90 sub_401C90      proc near               ; CODE XREF: sub_404E50+B9
.text:00401C90                                         ; sub_404E50+EA
.text:00401C90
.text:00401C90 arg_0           = dword ptr  8
.text:00401C90
.text:00401C90                 push    ebp
.text:00401C91                 mov     ebp, esp
.text:00401C93                 mov     eax, [ebp+arg_0]
.text:00401C96                 mov     dword ptr [eax+4], 0
.text:00401C9D                 mov     dword ptr [eax], 0
.text:00401CA3                 mov     dword ptr [eax+8], 67452301h
.text:00401CAA                 mov     dword ptr [eax+0Ch], 0EFCDAB89h
.text:00401CB1                 mov     dword ptr [eax+10h], 98BADCFEh
.text:00401CB8                 mov     dword ptr [eax+14h], 10325476h
.text:00401CBF                 pop     ebp
.text:00401CC0                 retn
.text:00401CC0 sub_401C90      endp

В результате вызовов функций sub_402410 и sub_402540 из строки var_A8 длиной 64 байта генерируется 128-битный хэш, который записывается в переменную var_14.

.text:00404F0E                 push    40h
.text:00404F10                 lea     ecx, [ebp+var_A8]
.text:00404F16                 push    ecx
.text:00404F17                 lea     edx, [ebp+var_100]
.text:00404F1D                 push    edx
.text:00404F1E                 call    sub_402410
.text:00404F23                 lea     eax, [ebp+var_14]
.text:00404F26                 push    eax
.text:00404F27                 lea     ecx, [ebp+var_100]
.text:00404F2D                 push    ecx
.text:00404F2E                 call    sub_402540

sub_402410

.text:00402410 sub_402410      proc near               ; CODE XREF: sub_402540+42
.text:00402410                                         ; sub_404E50+CE ...
.text:00402410
.text:00402410 var_44          = dword ptr -44h
.text:00402410 var_40          = dword ptr -40h
.text:00402410 var_3C          = dword ptr -3Ch
.text:00402410 var_38          = dword ptr -38h
.text:00402410 var_4           = dword ptr -4
.text:00402410 arg_0           = dword ptr  8
.text:00402410 arg_4           = dword ptr  0Ch
.text:00402410 arg_8           = dword ptr  10h
.text:00402410
.text:00402410                 push    ebp
.text:00402411                 mov     ebp, esp
.text:00402413                 sub     esp, 44h
.text:00402416                 mov     eax, ___security_cookie
.text:0040241B                 xor     eax, ebp
.text:0040241D                 mov     [ebp+var_4], eax
.text:00402420                 push    esi
.text:00402421                 mov     esi, [ebp+arg_0]
.text:00402424                 mov     ecx, [esi]
.text:00402426                 push    edi
.text:00402427                 mov     edi, [ebp+arg_8]
.text:0040242A                 mov     eax, ecx
.text:0040242C                 shr     eax, 3
.text:0040242F                 lea     edx, [ecx+edi*8]
.text:00402432                 and     eax, 3Fh
.text:00402435                 cmp     edx, ecx
.text:00402437                 jnb     short loc_40243C
.text:00402439                 inc     dword ptr [esi+4]
.text:0040243C
.text:0040243C loc_40243C:                             ; CODE XREF: sub_402410+27
.text:0040243C                 mov     ecx, edi
.text:0040243E                 shr     ecx, 1Dh
.text:00402441                 add     [esi+4], ecx
.text:00402444                 mov     [esi], edx
.text:00402446                 test    edi, edi
.text:00402448                 jz      loc_402524
.text:0040244E                 push    ebx
.text:0040244F                 nop
.text:00402450
.text:00402450 loc_402450:                             ; CODE XREF: sub_402410+10D
.text:00402450                 mov     ecx, [ebp+arg_4]
.text:00402453                 mov     dl, [ecx]
.text:00402455                 mov     [esi+eax+18h], dl
.text:00402459                 inc     eax
.text:0040245A                 inc     ecx
.text:0040245B                 dec     edi
.text:0040245C                 mov     [ebp+arg_4], ecx
.text:0040245F                 cmp     eax, 40h
.text:00402462                 jnz     loc_40251B
.text:00402468                 xor     ecx, ecx
.text:0040246A                 lea     eax, [esi+1Ah]
.text:0040246D                 lea     ecx, [ecx+0]
.text:00402470
.text:00402470 loc_402470:                             ; CODE XREF: sub_402410+F4
.text:00402470                 movzx   edx, byte ptr [eax+1]
.text:00402474                 movzx   ebx, byte ptr [eax]
.text:00402477                 shl     edx, 8
.text:0040247A                 or      edx, ebx
.text:0040247C                 movzx   ebx, byte ptr [eax-1]
.text:00402480                 shl     edx, 8
.text:00402483                 or      edx, ebx
.text:00402485                 movzx   ebx, byte ptr [eax-2]
.text:00402489                 shl     edx, 8
.text:0040248C                 or      edx, ebx
.text:0040248E                 movzx   ebx, byte ptr [eax+4]
.text:00402492                 mov     [ebp+ecx*4+var_44], edx
.text:00402496                 movzx   edx, byte ptr [eax+5]
.text:0040249A                 shl     edx, 8
.text:0040249D                 or      edx, ebx
.text:0040249F                 movzx   ebx, byte ptr [eax+3]
.text:004024A3                 shl     edx, 8
.text:004024A6                 or      edx, ebx
.text:004024A8                 movzx   ebx, byte ptr [eax+2]
.text:004024AC                 shl     edx, 8
.text:004024AF                 or      edx, ebx
.text:004024B1                 movzx   ebx, byte ptr [eax+8]
.text:004024B5                 mov     [ebp+ecx*4+var_40], edx
.text:004024B9                 movzx   edx, byte ptr [eax+9]
.text:004024BD                 shl     edx, 8
.text:004024C0                 or      edx, ebx
.text:004024C2                 movzx   ebx, byte ptr [eax+7]
.text:004024C6                 shl     edx, 8
.text:004024C9                 or      edx, ebx
.text:004024CB                 movzx   ebx, byte ptr [eax+6]
.text:004024CF                 shl     edx, 8
.text:004024D2                 or      edx, ebx
.text:004024D4                 movzx   ebx, byte ptr [eax+0Ch]
.text:004024D8                 mov     [ebp+ecx*4+var_3C], edx
.text:004024DC                 movzx   edx, byte ptr [eax+0Dh]
.text:004024E0                 shl     edx, 8
.text:004024E3                 or      edx, ebx
.text:004024E5                 movzx   ebx, byte ptr [eax+0Bh]
.text:004024E9                 shl     edx, 8
.text:004024EC                 or      edx, ebx
.text:004024EE                 movzx   ebx, byte ptr [eax+0Ah]
.text:004024F2                 shl     edx, 8
.text:004024F5                 or      edx, ebx
.text:004024F7                 mov     [ebp+ecx*4+var_38], edx
.text:004024FB                 add     ecx, 4
.text:004024FE                 add     eax, 10h
.text:00402501                 cmp     ecx, 10h
.text:00402504                 jb      loc_402470
.text:0040250A                 lea     eax, [esi+8]
.text:0040250D                 push    eax
.text:0040250E                 lea     eax, [ebp+var_44]
.text:00402511                 call    sub_401CD0
.text:00402516                 add     esp, 4
.text:00402519                 xor     eax, eax
.text:0040251B
.text:0040251B loc_40251B:                             ; CODE XREF: sub_402410+52
.text:0040251B                 test    edi, edi
.text:0040251D                 jnz     loc_402450
.text:00402523                 pop     ebx
.text:00402524
.text:00402524 loc_402524:                             ; CODE XREF: sub_402410+38
.text:00402524                 mov     ecx, [ebp+var_4]
.text:00402527                 pop     edi
.text:00402528                 xor     ecx, ebp
.text:0040252A                 pop     esi
.text:0040252B                 call    @__security_check_cookie@4 ; __security_check_cookie(x)
.text:00402530                 mov     esp, ebp
.text:00402532                 pop     ebp
.text:00402533                 retn
.text:00402533 sub_402410      endp

sub_402540

.text:00402540 sub_402540      proc near               ; CODE XREF: sub_404E50+DE
.text:00402540                                         ; sub_404E50+10B
.text:00402540
.text:00402540 var_44          = dword ptr -44h
.text:00402540 var_40          = dword ptr -40h
.text:00402540 var_C           = dword ptr -0Ch
.text:00402540 var_8           = dword ptr -8
.text:00402540 var_4           = dword ptr -4
.text:00402540 arg_0           = dword ptr  8
.text:00402540 arg_4           = dword ptr  0Ch
.text:00402540
.text:00402540                 push    ebp
.text:00402541                 mov     ebp, esp
.text:00402543                 sub     esp, 44h
.text:00402546                 mov     eax, ___security_cookie
.text:0040254B                 xor     eax, ebp
.text:0040254D                 mov     [ebp+var_4], eax
.text:00402550                 push    ebx
.text:00402551                 push    esi
.text:00402552                 mov     esi, [ebp+arg_0]
.text:00402555                 mov     eax, [esi]
.text:00402557                 mov     ecx, [esi+4]
.text:0040255A                 mov     [ebp+var_C], eax
.text:0040255D                 shr     eax, 3
.text:00402560                 and     eax, 3Fh
.text:00402563                 push    edi
.text:00402564                 mov     edi, [ebp+arg_4]
.text:00402567                 mov     [ebp+var_8], ecx
.text:0040256A                 mov     ecx, 38h
.text:0040256F                 cmp     eax, 38h
.text:00402572                 jl      short loc_402579
.text:00402574                 mov     ecx, 78h
.text:00402579
.text:00402579 loc_402579:                             ; CODE XREF: sub_402540+32
.text:00402579                 sub     ecx, eax
.text:0040257B                 push    ecx
.text:0040257C                 push    offset unk_411588
.text:00402581                 push    esi
.text:00402582                 call    sub_402410
.text:00402587                 add     esp, 0Ch
.text:0040258A                 xor     ecx, ecx
.text:0040258C                 lea     eax, [esi+1Ah]
.text:0040258F                 nop
.text:00402590
.text:00402590 loc_402590:                             ; CODE XREF: sub_402540+9E
.text:00402590                 movzx   edx, byte ptr [eax+1]
.text:00402594                 movzx   ebx, byte ptr [eax]
.text:00402597                 shl     edx, 8
.text:0040259A                 or      edx, ebx
.text:0040259C                 movzx   ebx, byte ptr [eax-1]
.text:004025A0                 shl     edx, 8
.text:004025A3                 or      edx, ebx
.text:004025A5                 movzx   ebx, byte ptr [eax-2]
.text:004025A9                 shl     edx, 8
.text:004025AC                 or      edx, ebx
.text:004025AE                 movzx   ebx, byte ptr [eax+4]
.text:004025B2                 mov     [ebp+ecx*4+var_44], edx
.text:004025B6                 movzx   edx, byte ptr [eax+5]
.text:004025BA                 shl     edx, 8
.text:004025BD                 or      edx, ebx
.text:004025BF                 movzx   ebx, byte ptr [eax+3]
.text:004025C3                 shl     edx, 8
.text:004025C6                 or      edx, ebx
.text:004025C8                 movzx   ebx, byte ptr [eax+2]
.text:004025CC                 shl     edx, 8
.text:004025CF                 or      edx, ebx
.text:004025D1                 mov     [ebp+ecx*4+var_40], edx
.text:004025D5                 add     ecx, 2
.text:004025D8                 add     eax, 8
.text:004025DB                 cmp     ecx, 0Eh
.text:004025DE                 jb      short loc_402590
.text:004025E0                 lea     ebx, [esi+8]
.text:004025E3                 push    ebx
.text:004025E4                 lea     eax, [ebp+var_44]
.text:004025E7                 call    sub_401CD0
.text:004025EC                 movzx   eax, byte ptr [ebx]
.text:004025EF                 mov     [edi], al
.text:004025F1                 movzx   ecx, byte ptr [esi+9]
.text:004025F5                 mov     [edi+1], cl
.text:004025F8                 movzx   edx, byte ptr [esi+0Ah]
.text:004025FC                 mov     [edi+2], dl
.text:004025FF                 movzx   eax, byte ptr [esi+0Bh]
.text:00402603                 mov     [edi+3], al
.text:00402606                 movzx   ecx, byte ptr [esi+0Ch]
.text:0040260A                 mov     [edi+4], cl
.text:0040260D                 movzx   edx, byte ptr [esi+0Dh]
.text:00402611                 mov     [edi+5], dl
.text:00402614                 movzx   eax, byte ptr [esi+0Eh]
.text:00402618                 mov     [edi+6], al
.text:0040261B                 movzx   ecx, byte ptr [esi+0Fh]
.text:0040261F                 mov     [edi+7], cl
.text:00402622                 movzx   edx, byte ptr [esi+10h]
.text:00402626                 mov     [edi+8], dl
.text:00402629                 movzx   eax, byte ptr [esi+11h]
.text:0040262D                 mov     [edi+9], al
.text:00402630                 movzx   ecx, byte ptr [esi+12h]
.text:00402634                 mov     [edi+0Ah], cl
.text:00402637                 movzx   edx, byte ptr [esi+13h]
.text:0040263B                 mov     [edi+0Bh], dl
.text:0040263E                 movzx   eax, byte ptr [esi+14h]
.text:00402642                 mov     [edi+0Ch], al
.text:00402645                 movzx   ecx, byte ptr [esi+15h]
.text:00402649                 mov     [edi+0Dh], cl
.text:0040264C                 movzx   edx, byte ptr [esi+16h]
.text:00402650                 mov     ecx, [ebp+var_4]
.text:00402653                 mov     [edi+0Eh], dl
.text:00402656                 movzx   eax, byte ptr [esi+17h]
.text:0040265A                 add     esp, 4
.text:0040265D                 mov     [edi+0Fh], al
.text:00402660                 pop     edi
.text:00402661                 pop     esi
.text:00402662                 xor     ecx, ebp
.text:00402664                 pop     ebx
.text:00402665                 call    @__security_check_cookie@4 ; __security_check_cookie(x)
.text:0040266A                 mov     esp, ebp
.text:0040266C                 pop     ebp
.text:0040266D                 retn
.text:0040266D sub_402540      endp

Аналогичным образом генерируется хэш от строки, содержащей email, и записывается в переменную var_24.

.text:01324F3F                 push    edi
.text:01324F40                 lea     eax, [ebp+var_100]
.text:01324F46                 push    esi
.text:01324F47                 push    eax
.text:01324F48                 call    sub_1322410
.text:01324F4D                 add     esp, 44h
.text:01324F50                 lea     ecx, [ebp+var_24]
.text:01324F53                 push    ecx
.text:01324F54                 lea     edx, [ebp+var_100]
.text:01324F5A                 push    edx
.text:01324F5B                 call    sub_1322540

После этого строки var_24 и var_14 побитово складываются и приводятся в текстовый вид. Результирующая строка записывается в переменную var_58, которая на заключительном этапе сравнивается со строкой введенного пользователем программы серийного номера, ссылка на которую хранится в переменной var_104. Если строки var_58 и var_104 совпадают (без учета регистра), то функция sub_404E50 возвращает 1, иначе 0.

Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 11

Таким образом, становится понятно, что для того, чтобы найти действительный серийный номер, который на завершающем этапе записывается в переменную var_58, требуется сначала узнать строку var_A8, которая генерируется зависающей функцией sub_4047C0. После того, как строка var_A8 станет известна, достаточно будет выполнить блок операций .text:00404EDA-00404F95 и считать строку серийного номера из переменной var_58.

Для того, чтобы убедиться, что весь остальной код отрабатывает корректно, в режиме отладки пропускаем вызов функции sub_4047C0 и доходим до места .text:00404FA0, в котором выполняется сравнение введенного и действительного серийного номера. Весь код отрабатывает исправно и результирующий серийный номер выходит равным «D1985BE6F7AEDF39E4BB93A02C854B99».

Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 12

И хотя при пропуске функции sub_4047C0 программа принимает этот серийный номер, попытка отправить этот результат вполне предсказуемо заканчивается провалом.

Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 13

Взлом Kaspersky Crackme: исследование защитного механизма (Часть 1) - 14

Подведем итоги. Поиск защитного механизма у данного crackme не занимает много времени. Функция проверки серийного номера находится простым переходом по перекрестной ссылке вызова окна сообщения. Никаких антиотладочных приемов или помех дизассемблированию программы обнаружено не было. Основным препятствием к решению задачи является тот факт, что функция sub_4047C0, инициализирующая промежуточную строку, используемую для генерации серийного номера, зависает, не выполнив инициализацию. Следующим этапом будет исследование функции sub_4047C0 и оптимизация её производительности. Для этого будет использоваться вставка X-кода, ссылкой на который будет заменен вызов неэффективной функции.

Автор: Geork

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js