Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Исследование Carrara Studio 2.0

Обсудить статью на форуме

Массу крэкерских инструментов, видеоуроков и статей вы сможете найти на видеокурсе от нашего сайта. Подробнее здесь.

Автор: GL#0M gl00m-crk@yandex.ru

 Цель: Carrara Studio 2.0 Demo
Инструменты: SoftICE, IDA и любой компилятор.

О программе...

"Carrara - это один из самых мощных редакторов трёхмерной графики среднего класса. В то же время по возможностям и савокупности имеющихся средств моделирования, анимации и качества рендеринга этот программный продукт вполне может быть отнесён к Hi-End. И нет таких объектов или моделей, которые требуется создать, и таких задач, стоящих перед дизайнером или художником, в том числе аниматором, которые невозможно было бы решить с помощью этой программы" - Журнал Chip 08/2003

Взлом

Поддавшись любопытству, я решил взглянуть таки на это творение от компании Eovia. Тем более, что на диске была демка. Запустив Carrara2Demo_English.exe и начав установку, я упёрся в окно с тремя полями для ввода. Кнопка Next> была неактивна. Я попытался ввести в поле Serial Number любую чушь (стандартно =). После чего кнопка Next> ожила. Что ж, нажимаем. Вылетел MessageBox и заявил, что Serial Nubmer is incorrect. Нехорошо... Значит нам и DEMO версию не посмотреть? Как же так? Гады! За что деньги плачены?


Решил копнуть поглубже...


Ладно, идём в TEMP и находим там папку {874759D2-D024-4FE8-BC84-F128D5A60662}, а в ней MCSetup.dll. Всё остальное относится к самому InstallShield'у и нас волновать не должно. Открываем его в IDA и смотрим список функций (Shift+F3). Мне сразу приглянулась MCSerialCheck. Давайте посмотрим, что там...
.text:10001630                 public MCSerialCheck
 .text:10001630                 MCSerialCheck   proc near
 .text:10001630
 .text:10001630                 SystemTime      = _SYSTEMTIME ptr -23Ch
 .text:10001630                 var_22C         = byte ptr -22Ch
 .text:10001630                 var_200         = byte ptr -200h
 .text:10001630                 Buffer          = byte ptr -100h
 .text:10001630                 arg_0           = dword ptr  4
 .text:10001630                 arg_4           = dword ptr  8
 .text:10001630                 arg_8           = dword ptr  0Ch
 .text:10001630
 .text:10001630                 sub     esp, 23Ch
 .text:10001636                 lea     eax, [esp+23Ch+SystemTime]
 .text:1000163A                 push    ebx
 .text:1000163B                 push    esi
 .text:1000163C                 push    edi
 .text:1000163D                 push    eax             ; lpSystemTime
 .text:1000163E                 call    ds:GetLocalTime
 .text:10001644                 mov     esi, dword ptr [esp+248h+SystemTime.wDay]
 .text:10001648                 mov     edi, dword ptr [esp+248h+SystemTime.wMonth]
 .text:1000164C                 mov     ecx, [esp+248h+arg_8]      // в ecx введённый сериал
 .text:10001653                 mov     ebx, dword ptr [esp+248h+SystemTime.wYear]
 .text:10001657                 push    ecx
 .text:10001658                 lea     ecx, [esp+24Ch+var_22C]
 .text:1000165C                 call    sub_10001000               // переводим буквы в верхний регистр
 .text:10001661                 push    ebx
 .text:10001662                 push    edi
 .text:10001663                 mov     edx, [esp+250h+arg_0]
 .text:1000166A                 push    esi
 .text:1000166B                 push    1
 .text:1000166D                 push    edx
 .text:1000166E                 lea     ecx, [esp+25Ch+var_22C]
 .text:10001672                 call    sub_10001190        // интересно...
 .text:10001677                 mov     esi, eax          // esi=eax
 .text:10001679                 cmp     si, 1
 .text:1000167D                 jnz     short loc_100016A4         // если si<>1, то на ошибку
 .text:1000167F                 mov     eax, [esp+248h+arg_4]
 .text:10001686                 push    offset unk_1000CFF0
 .text:1000168B                 push    eax
 .text:1000168C                 lea     ecx, [esp+250h+var_22C]
 .text:10001690                 call    sub_10001520
 .text:10001695                 pop     edi
 .text:10001696                 pop     esi
 .text:10001697                 or      eax, 0FFFFFFFFh
 .text:1000169A                 pop     ebx
 .text:1000169B                 add     esp, 23Ch
 .text:100016A1                 retn    0Ch
 
Если поставить breakpoint на GetLocalTime и тщательно рассмотреть этот кусок кода, то мы поймём, что по адресу 1000164C ecx принимает введённый нами номер, процеура по адресу 1000165C переводит все буквы введённого номера в верхний регистр, а по адресу 10001672 идёт какая-то длинная, запутанная процедура, после которой происходит сравнение регистра si с единицей, и если они не равны, то происходит прыжок на знакомую ошибку.


Зайдём в call 10001190 и попробуем разобраться, что же там происходит.


.text:10001190                 sub_10001190    proc near               ; CODE XREF: MCSerialCheck+42p
 .text:10001190
 .text:10001190                 var_20          = byte ptr -20h
 .text:10001190                 var_10          = byte ptr -10h
 .text:10001190                 var_F           = byte ptr -0Fh
 .text:10001190                 var_E           = byte ptr -0Eh
 .text:10001190                 arg_0           = dword ptr  4
 .text:10001190                 arg_4           = dword ptr  8
 .text:10001190                 arg_8           = word ptr  0Ch
 .text:10001190                 arg_C           = word ptr  10h
 .text:10001190                 arg_10          = word ptr  14h
 .text:10001190
 .text:10001190                 mov     edx, [esp+arg_0]          // edx='CD20'
 .text:10001194                 sub     esp, 20h
 .text:10001197                 xor     eax, eax
 .text:10001199                 push    ebx
 .text:1000119A                 push    ebp
 .text:1000119B                 push    esi
 .text:1000119C                 mov     ebx, ecx
 .text:1000119E                 push    edi
 .text:1000119F                 mov     edi, edx
 .text:100011A1                 or      ecx, 0FFFFFFFFh
 .text:100011A4                 repne scasb
 .text:100011A6                 not     ecx
 .text:100011A8                 dec     ecx
 .text:100011A9                 cmp     ecx, 4
 .text:100011AC                 jnz     short loc_10001205
 .text:100011AE                 mov     ax, [ebx+20h]            // ax=кол-во симв. в нашем сериале
 .text:100011B2                 cmp     ax, 13h
 .text:100011B6                 jz      short loc_100011CA           // если ax=19, то прыгаем
 .text:100011B8                 cmp     ax, 17h
 .text:100011BC                 jz      short loc_100011CA            // если ax=23, то прыгаем
 .text:100011BE                 cmp     ax, 1Ah
 .text:100011C2                 jz      short loc_100011CA             // если ax=26, то прыгаем
 .text:100011C4                 cmp     ax, 1Eh
 .text:100011C8                 jnz     short loc_10001205              // если ax<>30, то на ошибку
 .text:100011CA
 .text:100011CA                 loc_100011CA:                           ; CODE XREF: sub_10001190+26j
 .text:100011CA                                         ; sub_10001190+2Cj ...
 .text:100011CA                 mov     al, [ebx]           // al=1-й симв. нашего сериала
 .text:100011CC                 mov     cl, [edx]           // cl='C'
 .text:100011CE                 cmp     al, cl
 .text:100011D0                 jnz     short loc_10001205          // если al<>cl, то на ошибку
 .text:100011D2                 mov     cl, [ebx+1]           // cl=2-й симв. нашего сериала
 .text:100011D5                 mov     al, [edx+1]           // al='D'
 .text:100011D8                 cmp     cl, al
 .text:100011DA                 jnz     short loc_10001205         // если cl<>al, то на ошибку
 .text:100011DC                 mov     al, [ebx+2]              // al=3-й симв. нашего сериала
 .text:100011DF                 mov     cl, [edx+2]              // cl='2'
 .text:100011E2                 cmp     al, cl
 .text:100011E4                 jnz     short loc_10001205           // если al<>cl, то на ошибку
 .text:100011E6                 mov     cl, [ebx+3]                // cl=4-й симв. нашего сериала
 .text:100011E9                 mov     al, [edx+3]                // al='0'
 .text:100011EC                 cmp     cl, al
 .text:100011EE                 jnz     short loc_10001205            // если cl<>al, то на ошибку
 .text:100011F0                 mov     ax, word ptr [esp+30h+arg_4]
 .text:100011F5                 test    ax, ax
 .text:100011F8                 jnz     short loc_10001212           // если ax<>0, то прыгаем
 .text:100011FA                 mov     al, [ebx+4]                  // al=5-й симв. нашего сериала
 .text:100011FD                 cmp     al, 4Dh
 .text:100011FF                 jz      short loc_10001223             // если al='M', то прыгаем
 .text:10001201                 cmp     al, 43h
 .text:10001203                 jz      short loc_10001223            // если al='C', то прыгаем
 .text:10001205
 .text:10001205                 loc_10001205:                           ; CODE XREF: sub_10001190+1Cj
 .text:10001205                                         ; sub_10001190+38j ...
 .text:10001205                 pop     edi
 .text:10001206                 pop     esi
 .text:10001207                 pop     ebp
 .text:10001208                 xor     ax, ax            // ax=0
 .text:1000120B                 pop     ebx
 .text:1000120C                 add     esp, 20h
 .text:1000120F                 retn    14h
 .text:10001212 ; -----------------------------------------------------------------------
 .text:10001212
 .text:10001212                 loc_10001212:                           ; CODE XREF: sub_10001190+68j
 .text:10001212                 cmp     ax, 1
 .text:10001216                 jnz     short loc_10001223           // если ax<>1, то прыгаем
 .text:10001218                 mov     al, [ebx+4]               // al=5-й симв. нашего сериала
 .text:1000121B                 cmp     al, 57h
 .text:1000121D                 jz      short loc_10001223              // если al='W', то прыгаем
 .text:1000121F                 cmp     al, 43h
 .text:10001221                 jnz     short loc_10001205            // если al<>'C', то на ошибку
 .text:10001223
 .text:10001223                 loc_10001223:                           ; CODE XREF: sub_10001190+6Fj
 .text:10001223                                         ; sub_10001190+73j ...
 .text:10001223                 mov     al, [ebx+5]            // al=6-й симв. нашего сериала
 .text:10001226                 cmp     al, 42h
 .text:10001228                 jz      short loc_1000123E            // если al='B', то прыгаем
 .text:1000122A                 cmp     al, 43h
 .text:1000122C                 jz      short loc_1000123E           // если al='C', то прыгаем
 .text:1000122E                 cmp     al, 45h
 .text:10001230                 jz      short loc_1000123E           // если al='E', то прыгаем
 .text:10001232                 cmp     al, 4Eh
 .text:10001234                 jz      short loc_1000123E              // если al='N', то прыгаем
 .text:10001236                 cmp     al, 52h
 .text:10001238                 jz      short loc_1000123E               // если al='R', то прыгаем
 .text:1000123A                 cmp     al, 55h
 .text:1000123C                 jnz     short loc_10001205               // если al<>'U', то на ошибку
 .text:1000123E
 .text:1000123E                 loc_1000123E:                           ; CODE XREF: sub_10001190+98j
 .text:1000123E                                         ; sub_10001190+9Cj ...
 .text:1000123E                 mov     al, [ebx+6]               // al=7-й симв. нашего сериала
 .text:10001241                 cmp     al, 42h
 .text:10001243                 jz      short loc_10001279          // если al='B', то прыгаем
 .text:10001245                 cmp     al, 43h
 .text:10001247                 jz      short loc_10001279           // если al='C', то прыгаем
 .text:10001249                 cmp     al, 44h
 .text:1000124B                 jz      short loc_10001279            // если al='D', то прыгаем
 .text:1000124D                 cmp     al, 46h
 .text:1000124F                 jz      short loc_10001279            // если al='F', то прыгаем
 .text:10001251                 cmp     al, 47h
 .text:10001253                 jz      short loc_10001279            // если al='G', то прыгаем
 .text:10001255                 cmp     al, 4Dh
 .text:10001257                 jz      short loc_10001279            // если al='M', то прыгаем
 .text:10001259                 cmp     al, 4Ah
 .text:1000125B                 jz      short loc_10001279            // если al='J', то прыгаем
 .text:1000125D                 cmp     al, 4Bh
 .text:1000125F                 jz      short loc_10001279               // если al='K', то прыгаем
 .text:10001261                 cmp     al, 4Ch
 .text:10001263                 jz      short loc_10001279           // если al='L', то прыгаем
 .text:10001265                 cmp     al, 4Eh
 .text:10001267                 jz      short loc_10001279            // если al='N', то прыгаем
 .text:10001269                 cmp     al, 50h
 .text:1000126B                 jz      short loc_10001279              // если al='P', то прыгаем
 .text:1000126D                 cmp     al, 53h
 .text:1000126F                 jz      short loc_10001279             // если al='S', то прыгаем
 .text:10001271                 cmp     al, 54h
 .text:10001273                 jz      short loc_10001279             // если al='T', то прыгаем
 .text:10001275                 cmp     al, 5Ah
 .text:10001277                 jnz     short loc_10001205              // если al<>'Z', то на ошибку
 .text:10001279
 .text:10001279                 loc_10001279:                           ; CODE XREF: sub_10001190+B3j
 .text:10001279                                         ; sub_10001190+B7j ...
 .text:10001279                 mov     al, [ebx+7]                 // al=8-й симв. нашего сериала
 .text:1000127C                 mov     dl, 2Dh           // dl='-'
 .text:1000127E                 cmp     al, dl
 .text:10001280                 jnz     short loc_10001205           // если al<>dl, то на ошибку
 .text:10001282                 mov     ecx, 8
 .text:10001287
 .text:10001287                 loc_10001287:                           ; CODE XREF: sub_10001190+112j
 .text:10001287                 movsx   eax, cx            -
 .text:1000128A                 mov     al, [eax+ebx]       | c 9-го
 .text:1000128D                 cmp     al, 30h             | по 15-й
 .text:1000128F                 jl      loc_10001205        | символы
 .text:10001295                 cmp     al, 39h             | сериальника,
 .text:10001297                 jg      loc_10001205        | должны быть
 .text:1000129D                 inc     ecx                 | любые цыфры
 .text:1000129E                 cmp     cx, 0Fh             | от 0 до 9
 .text:100012A2                 jl      short loc_10001287 -
 .text:100012A4                 cmp     [ebx+0Fh], dl
 .text:100012A7                 jnz     loc_10001205                // если 16-й<>'-', то на ошибку
 .text:100012AD                 xor     ebp, ebp
 .text:100012AF                 mov     esi, 10h
 .text:100012B4                 mov     dl, 41h
 .text:100012B6
 .text:100012B6                 loc_100012B6:                           ; CODE XREF: sub_10001190+174j
 .text:100012B6                 movsx   ecx, si                -
 .text:100012B9                 mov     al, [ecx+ebx]
 .text:100012BC                 cmp     al, dl
 .text:100012BE                 jl      loc_10001205
 .text:100012C4                 cmp     al, 5Ah
 .text:100012C6                 jg      loc_10001205
 .text:100012CC                 cmp     al, 49h                 | c 17-го
 .text:100012CE                 jz      loc_10001205            | по 19-й
 .text:100012D4                 cmp     al, 4Fh                 | символы
 .text:100012D6                 jz      loc_10001205            | сериальника,
 .text:100012DC                 lea     ecx, [ebp+ebp*2+0]      | должны быть
 .text:100012E0                 shl     ecx, 3                  | буквы от 'A'
 .text:100012E3                 cmp     al, 50h                 | до 'Z', исключая
 .text:100012E5                 jl      short loc_100012F0      | буквы 'I' и 'O'
 .text:100012E7                 movsx   eax, al
 .text:100012EA                 lea     ebp, [ecx+eax-43h]
 .text:100012EE                 jmp     short loc_100012FF
 .text:100012F0 ; -----------------------------------------------------------------------
 .text:100012F0
 .text:100012F0                 loc_100012F0:                           ; CODE XREF: sub_10001190+155j
 .text:100012F0                 cmp     al, 4Ah
 .text:100012F2                 movsx   eax, al
 .text:100012F5                 lea     ebp, [ecx+eax-42h]
 .text:100012F9                 jge     short loc_100012FF
 .text:100012FB                 lea     ebp, [ecx+eax-41h]
 .text:100012FF
 .text:100012FF                 loc_100012FF:                           ; CODE XREF: sub_10001190+15Ej
 .text:100012FF                                         ; sub_10001190+169j
 .text:100012FF                 inc     esi
 .text:10001300                 cmp     si, 13h
 .text:10001304                 jl      short loc_100012B6     -
 ...
 
Остановимся пока здесь. Я думаю, в комментариях, всё понятно? Что мы имеем:

1) Серийный номер, должен составлять 19, 23, 26 или 30 символов.
2) Первые 4-е символа, должны быть 'CD20'. Это, предположительно, сокращённое Carrara Demo 2.0
3) Пятый символ W или C.
4) Шестой символ B, C, E, N, R или U.
5) Седьмой символ B, C, D, F, G, M, J, K, L, N, P, S, T или Z.
6) Восьмой символ, должен быть '-'.
7) Символы с 9-го по 15-й - любые цифры от 0 до 9.
8) 16-й символ, должен быть '-'.
9) Символы с 17-го по 19-й - буквы A, B, C, D, E, F, G, H, J, K, L, M, N, P, Q, R, S, T, U, V, W, X, Y, Z.

В общем серийный номер (из 19-и символов), на данный момент, может выглядеть так: CD20CRK-0313370-MCG

10) И ещё один интересный момент, смотрим на следующий листинг:


.text:100012AD                 xor     ebp, ebp            // ebp=0
 .text:100012AF                 mov     esi, 10h                // esi=16
 .text:100012B4                 mov     dl, 41h                // dl='A'
 .text:100012B6                 movsx   ecx, si
 .text:100012B9                 mov     al, [ecx+ebx]         // в al 17-19 симв. нашего сериала
 .text:100012BC                 cmp     al, dl
 .text:100012BE                 jl      loc_10001205          // если al<'A', то на ошибку
 .text:100012C4                 cmp     al, 5Ah
 .text:100012C6                 jg      loc_10001205          // если al>'Z', то на ошибку
 .text:100012CC                 cmp     al, 49h
 .text:100012CE                 jz      loc_10001205          // если al='I', то на ошибку
 .text:100012D4                 cmp     al, 4Fh
 .text:100012D6                 jz      loc_10001205           // если al='O', то на ошибку
 .text:100012DC                 lea     ecx, [ebp+ebp*2+0]            // ecx:=ebp*3
 .text:100012E0                 shl     ecx, 3                        // ecx:=ecx shl 3
 .text:100012E3                 cmp     al, 50h
 .text:100012E5                 jl      short loc_100012F0            // если al<'P', то прыгаем
 .text:100012E7                 movsx   eax, al
 .text:100012EA                 lea     ebp, [ecx+eax-43h]             // ebp:=ecx+eax-67
 .text:100012EE                 jmp     short loc_100012FF
 .text:100012F0                 cmp     al, 4Ah
 .text:100012F2                 movsx   eax, al
 .text:100012F5                 lea     ebp, [ecx+eax-42h]          // ebp:=ecx+eax-66
 .text:100012F9                 jge     short loc_100012FF           // если al>='J', то прыгаем
 .text:100012FB                 lea     ebp, [ecx+eax-41h]          // ebp:=ecx+eax-65
 .text:100012FF                 inc     esi
 .text:10001300                 cmp     si, 13h
 .text:10001304                 jl      short loc_100012B6           // если si<19, то прыгаем
 
На паскале это выглядит так:

 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   var
   i, eaxx, ecxx, ebpp: integer;
   ThreeChars: string;
 
 begin
   ThreeChars := 'MCG';          // 'MCG' - это для примера
   for i := 1 to 3 do
   begin
     eaxx := ord(ThreeChars[i]);
     ecxx := ebpp*3;
     ecxx := ecxx shl 3;
     ebpp := ecxx+eaxx-$43;
     if eaxx < $50 then
       begin
         if eaxx >= $4A then ebpp := ecxx+eaxx-$42
         else ebpp := ecxx+eaxx-$41;
       end;
   end;
 end;
 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
В результате, ebpp будет равно определённому числу.
ThreeChars := 'AAA', тогда ebpp := 0;
ThreeChars := 'AAB', тогда ebpp := 1;
ThreeChars := 'MCG', тогда ebpp := 6390;
ThreeChars := 'ZZZ', тогда ebpp := 13823.

Что ж, продолжим...

.text:10001306                 mov     ecx, 8
 .text:1000130B                 mov     esi, ebx                      // esi=введённый сериал
 .text:1000130D                 lea     edi, [esp+30h+var_20]
 .text:10001311                 repe movsd
 .text:10001313                 lea     ecx, [esp+30h+var_20]          // ecx=введённый сериал
 .text:10001317                 mov     [esp+30h+var_10], dl          // 17-й симв. заменяем на 'A'
 .text:1000131B                 push    ecx
 .text:1000131C                 mov     [esp+34h+var_F], dl           // 18-й симв. заменяем на 'A'
 .text:10001320                 mov     [esp+34h+var_E], dl           // 19-й симв. заменяем на 'A'
 .text:10001324                 call    sub_100010E0               // интересно...
 .text:10001329                 add     esp, 4
 .text:1000132C                 cmp     eax, ebp
 .text:1000132E                 jnz     loc_10001205               // если eax<>ebp, то на ошибку
 
Остановимся и зайдём в call 100010E0. Посмотрим, что там:

.text:100010E0                 sub_100010E0    proc near               ; CODE XREF: sub_10001190+194p
 .text:100010E0
 .text:100010E0                 arg_0           = dword ptr  0Ch
 .text:100010E0
 .text:100010E0                 push    ebx                  // ebx=наш введённый номер
 .text:100010E1                 push    esi                       // esi=наш введённый номер
 .text:100010E2                 mov     esi, [esp+arg_0]             // с 'AAA' на конце :)))
 .text:100010E6                 xor     eax, eax
 .text:100010E8                 xor     ecx, ecx
 .text:100010EA                 mov     edx, esi
 .text:100010EC                 cmp     byte ptr [esi], 0
 .text:100010EF                 jz      short loc_100010FA
 .text:100010F1
 .text:100010F1                 loc_100010F1:                           ; CODE XREF: sub_100010E0+18j
 .text:100010F1                 mov     bl, [edx+1]         -
 .text:100010F4                 inc     edx                  | цикл подсчёта
 .text:100010F5                 inc     ecx                  | символов в
 .text:100010F6                 test    bl, bl               | введённом сериале
 .text:100010F8                 jnz     short loc_100010F1  -
 .text:100010FA
 .text:100010FA                 loc_100010FA:                           ; CODE XREF: sub_100010E0+Fj
 .text:100010FA                 movsx   ecx, cx                 // ecx=кол-во симв. в нашем сериале
 .text:100010FD                 add     ecx, 3                 // ecx:=ecx+3
 .text:10001100                 shr     ecx, 2                  // ecx:=ecx shr 2
 .text:10001103                 test    cx, cx
 .text:10001106                 jle     short loc_1000114A                 // если cx<=0, то прыгаем
 .text:10001108                 push    edi
 .text:10001109                 movsx   edi, cx
 .text:1000110C
 .text:1000110C                 loc_1000110C:                           ; CODE XREF: sub_100010E0+67j
 .text:1000110C                 xor     ecx, ecx            -
 .text:1000110E                 mov     edx, 4
 .text:10001113
 .text:10001113                 loc_10001113:                           ; CODE XREF: sub_100010E0+3Ej
 .text:10001113                 xor     ebx, ebx
 .text:10001115                 mov     bl, [esi]            | данный цыкл
 .text:10001117                 shl     ecx, 8               | трудно объяснить
 .text:1000111A                 or      ecx, ebx             | простым языком,
 .text:1000111C                 inc     esi                  | будет доходчивее
 .text:1000111D                 dec     edx                  | показать это на
 .text:1000111E                 jnz     short loc_10001113   | паскале
 .text:10001120                 xor     eax, ecx             | (см. ниже)
 .text:10001122                 test    eax, 80000000h
 .text:10001127                 jz      short loc_1000112E
 .text:10001129                 and     eax, 7FFFFFFFh
 .text:1000112E
 .text:1000112E                 loc_1000112E:                           ; CODE XREF: sub_100010E0+47j
 .text:1000112E                 test    eax, eax
 .text:10001130                 jnz     short loc_10001137
 .text:10001132                 mov     eax, 1
 .text:10001137
 .text:10001137                 loc_10001137:                           ; CODE XREF: sub_100010E0+50j
 .text:10001137                 push    eax
 .text:10001138                 call    sub_10001090
 .text:1000113D                 push    eax
 .text:1000113E                 call    sub_10001090
 .text:10001143                 add     esp, 8
 .text:10001146                 dec     edi
 .text:10001147                 jnz     short loc_1000110C  -
 
Выделенный сектор, переведённый на паскаль (разбит на несколько процедур):

   var
   i, eaxx, ebxx, ecxx, esix: integer;
   serial: string;
 
 procedure MathSubGen(num:integer);               // это call 10001090, переведённый на паскаль :)
 begin
   asm
     mov  ecx, eaxx
     mov  eax, $834E0B5F
     imul ecx
     add  edx, ecx
     sar  edx, $10
     mov  eax, edx
     shr  eax, $1F
     add  edx, eax
     lea  eax, [edx+edx*8]
     shl  eax, $3
     sub  eax, edx
     lea  eax, [eax+eax*4]
     shl  eax, $1
     sub  eax, edx
     shl  eax, $2
     mov  esix,eax
     mov  eax, ecx
     cdq
     mov  ecx, $1F31D
     idiv ecx
     mov  eax, edx
     imul eax, $41A7
     sub  eax, esix
     test eax, eax
 @@0:jg @@1
     add  eax, $7FFFFFFF
 @@1:mov  eaxx, eax
   end;
 end;                            // конец call 10001090
 
 procedure SubTest;
 begin
   eaxx:=eaxx xor ecxx;
   asm
     mov  eax, eaxx
     test eax, $80000000
     je   @@0
     and  eax, $7FFFFFFF
 @@0:test eax, eax
     jne  @@1
     mov  eax, $1
 @@1:mov  eaxx, eax
   end;
   MathSubGen(eaxx);
   MathSubGen(eaxx);
 end;
 
 begin
   serial:='CD20CRK-0313370-AAA';
   ecxx:=0;
   eaxx:=0;
   for i:=1 to 20 do
   begin
     ebxx:=ord(serial[i]);
     ecxx:=ecxx shl 8;
     ecxx:=ecxx or ebxx;
     if round(frac(i / 4)*10)=0 then SubTest;
   end;
 end;
 
Продолжим...

 .text:10001149                 pop     edi
 .text:1000114A
 .text:1000114A                 loc_1000114A:                           ; CODE XREF: sub_100010E0+26j
 .text:1000114A                 and     eax, 0FEF7FDFFh
 .text:1000114F                 pop     esi
 .text:10001150                 mov     ecx, eax
 .text:10001152                 pop     ebx
 .text:10001153                 sar     ecx, 0Bh
 .text:10001156                 and     ecx, 1FFFFFh
 .text:1000115C                 shl     eax, 15h
 .text:1000115F                 or      ecx, eax
 .text:10001161                 test    ecx, 80000000h
 .text:10001167                 jz      short loc_1000116F
 .text:10001169                 and     ecx, 7FFFFFFFh
 .text:1000116F
 .text:1000116F                 loc_1000116F:                           ; CODE XREF: sub_100010E0+87j
 .text:1000116F                 test    ecx, ecx
 .text:10001171                 jnz     short loc_10001178
 .text:10001173                 mov     ecx, 1
 .text:10001178
 .text:10001178                 loc_10001178:                           ; CODE XREF: sub_100010E0+91j
 .text:10001178                 push    ecx
 .text:10001179                 call    sub_10001090
 .text:1000117E                 cdq
 .text:1000117F                 mov     ecx, 3600h
 .text:10001184                 add     esp, 4
 .text:10001187                 idiv    ecx
 .text:10001189                 mov     eax, edx
 .text:1000118B                 retn
 .text:1000118B                 sub_100010E0    endp
 
Это, на паскале, выглядит так:

   var
   eaxx: integer;
 
 begin
   asm
     mov  eax, eaxx
     and  eax, $0FEF7FDFF
     mov  ecx, eax
     sar  ecx, $0B
     and  ecx, $1FFFFF
     shl  eax, $15
     or   ecx, eax
     test ecx, $80000000
     je   @@0
     and  ecx, $7FFFFFFF
 @@0:test ecx, ecx
     jne  @@1
     mov  ecx, $1
 @@1:mov  eaxx, ecx
   end;
   MathSubGen(eaxx);                // исходник MathSubGen (call 10001090) рассмотрен выше
   asm
     cdq
     mov  ecx, $3600
     idiv ecx
     mov  eax, edx
     mov  eaxx,eax
   end;
 end;
 
Ну, вот мы и подошли к концу call 100010E0, еcли вы забыли, то напомню:

 :10001324   call 100010E0           // эту процедуру, мы полностью рассмотрели %)
 :10001329   add  esp, 4
 :1000132C   cmp  eax, ebp
 :1000132E   jnz  10001205           // если eax<>ebp, то на ошибку
 
Если всё это пройти в SoftICE, то на выходе в eax будет определённое число. У меня, с номером CD20CRK-0313370-MCG (последнии три символа из номера всегда заменяютя на 'AAA'), это число 13515. А регистр ebp, если вы помните, был равен 6390. После сравнения мы конечно же вылетим на ошибку. :(

На данном этапе, мы уже можем найти valid'ный серийник, воспользовавшись несложной программой (просто перебирайте буквы пока не получите нужное число, для меня это 6390). Номер получился такой: CD20CRK-0313370-ZMD. Вставив его в нужное поле (Serial Number), у нас появится возможность продолжить установку и наконец-таки опробовать возможности Carrara Studio 2 DEMO.

"Кто хочешь знать, читает Chip!" (лозунг журнала "Chip")
Да, нелёгок путь к знаниям... На этом можно было бы и остановиться. Но, если у вас вдруг появилось желание создать ключи из 23-х, 26-и и 30-и символов, то есть смысл продолжить наше исследование. Итак, перед нами следующий этап проверки:

 .text:10001334                 mov     al, [ebx+13h]               // al:=20-й символ сериала
 .text:10001337                 mov     ebp, 13h
 .text:1000133C                 cmp     al, 2Bh
 .text:1000133E                 mov     [esp+30h+arg_4], ebp
 .text:10001342                 mov     esi, 1
 .text:10001347                 jnz     short loc_10001382               // если al<>'+', то прыгаем
 .text:10001349                 mov     ecx, 14h             -
 .text:1000134E                 xor     esi, esi
 .text:10001350                 mov     eax, ecx
 .text:10001352
 .text:10001352                 loc_10001352:                           ; CODE XREF: sub_10001190+1E7j
 .text:10001352                 mov     al, [eax+ebx]
 .text:10001355                 cmp     al, 30h               | символы с
 .text:10001357                 jl      loc_10001205          | 21 по 23
 .text:1000135D                 cmp     al, 39h               | цыфры от
 .text:1000135F                 jg      loc_10001205          | 0 до 9
 .text:10001365                 movsx   ax, al                | (любые)
 .text:10001369                 lea     edx, [esi+esi*4]
 .text:1000136C                 inc     ecx
 .text:1000136D                 lea     esi, [eax+edx*2-30h]
 .text:10001371                 movsx   eax, cx
 .text:10001374                 cmp     eax, 17h
 .text:10001377                 jl      short loc_10001352   -
 
Значит, для серийного номера из 23-х символов:
1) с 1 по 19 символ аналогично серийнику из 19-и символов.
2) 20 символ - '+'.
3) с 21 по 23 - любые три цифры.

Теперь, используя всё ту же программу, мы можем вычислить номер и из 23-х символов.
Получился такой: CD20CRK-0313370-SEV+007.
Продолжим...

 .text:10001379                 mov     ebp, 17h
 .text:1000137E                 mov     [esp+30h+arg_4], ebp
 .text:10001382
 .text:10001382                 loc_10001382:                           ; CODE XREF: sub_10001190+1B7j
 .text:10001382                 movsx   edx, bp
 .text:10001385                 xor     cl, cl
 .text:10001387                 lea     eax, [edx+ebx]
 .text:1000138A                 mov     dl, [edx+ebx]              // dl:=20-й символ
 .text:1000138D                 cmp     dl, 2Ah                // или 24-й, если сериал 30-исимв.
 .text:10001390                 jnz     loc_10001450              // если al<>'*', то прыгаем
 .text:10001396                 movsx   ecx, byte ptr [eax+1]
 .text:1000139A                 movsx   edx, byte ptr [eax+2]
 .text:1000139E                 lea     ecx, [ecx+ecx*4]      -
 .text:100013A1                 lea     edx, [edx+ecx*2-210h]  | симв. c 21 по
 .text:100013A8                 cmp     edx, 1                 | 22, или c 25 по 26
 .text:100013AB                 mov     [esp+30h+arg_0], edx   | для 30-и симв. сериала,
 .text:100013AF                 jl      loc_10001205           | число от '01' до '12'
 .text:100013B5                 cmp     edx, 0Ch               | Это имеется ввиду месяц.
 .text:100013B8                 jg      loc_10001205          -
 .text:100013BE                 movsx   ecx, byte ptr [eax+3]
 .text:100013C2                 movsx   edi, byte ptr [eax+4]
 .text:100013C6                 lea     ecx, [ecx+ecx*4]      -
 .text:100013C9                 lea     edi, [edi+ecx*2-210h]  | симв. c 23 по 24,
 .text:100013D0                 cmp     edi, 1                 | или с 27 по 28 для
 .text:100013D3                 jl      loc_10001205           | 30-исимв., чисто от
 .text:100013D9                 cmp     edi, 1Fh               | '01' до '31'. День.
 .text:100013DC                 jg      loc_10001205          -
 .text:100013E2                 movsx   ecx, byte ptr [eax+5]
 .text:100013E6                 movsx   eax, byte ptr [eax+6]
 .text:100013EA                 lea     ecx, [ecx+ecx*4]
 .text:100013ED                 lea     eax, [eax+ecx*2-210h]
 .text:100013F4                 cmp     eax, 63h              // сравниваем eax с 99. Год.
 .text:100013F7                 jnz     short loc_10001400           // если неравны, то прыгам.
 .text:100013F9                 mov     eax, 7CFh
 .text:100013FE                 jmp     short loc_10001405              // Прыг на Date of Expired. :)
 .text:10001400 ; -----------------------------------------------------------------------
 .text:10001400
 .text:10001400                 loc_10001400:                           ; CODE XREF: sub_10001190+267j
 .text:10001400                 add     eax, 7D0h
 .text:10001405
 .text:10001405                 loc_10001405:                           ; CODE XREF: sub_10001190+26Ej
 .text:10001405                 movsx   ecx, [esp+30h+arg_10]
 .text:1000140A                 movsx   ebp, [esp+30h+arg_C]
 .text:1000140F                 lea     ecx, [ecx+ecx*2]
 .text:10001412                 lea     ecx, [ebp+ecx*4+0]
 .text:10001416                 mov     ebp, ecx
 .text:10001418                 shl     ebp, 5
 .text:1000141B                 sub     ebp, ecx
 .text:1000141D                 movsx   ecx, [esp+30h+arg_8]
 .text:10001422                 add     ebp, ecx
 .text:10001424                 lea     ecx, [eax+eax*2]
 .text:10001427                 lea     ecx, [edx+ecx*4]
 .text:1000142A                 mov     edx, ecx
 .text:1000142C                 shl     edx, 5
 .text:1000142F                 sub     edx, ecx
 .text:10001431                 add     edx, edi
 .text:10001433                 cmp     ebp, edx
 .text:10001435                 jl      short loc_10001445                 //Прыг, если DateNotExpired. :)
 .text:10001437                 pop     edi
 .text:10001438                 pop     esi
 .text:10001439                 pop     ebp
 .text:1000143A                 mov     ax, 2
 .text:1000143E                 pop     ebx
 .text:1000143F                 add     esp, 20h
 .text:10001442                 retn    14h
 .text:10001445 ; -----------------------------------------------------------------------
 .text:10001445
 .text:10001445                 loc_10001445:                           ; CODE XREF: sub_10001190+2A5j
 .text:10001445                 mov     ebp, [esp+30h+arg_4]
 .text:10001449                 mov     cl, 1
 .text:1000144B                 add     ebp, 7
 .text:1000144E                 jmp     short loc_10001458
 .text:10001450 ; -----------------------------------------------------------------------
 .text:10001450
 .text:10001450                 loc_10001450:                           ; CODE XREF: sub_10001190+200j
 .text:10001450                 mov     edi, [esp+30h+arg_4]
 .text:10001454                 mov     eax, [esp+30h+arg_4]
 .text:10001458
 .text:10001458                 loc_10001458:                           ; CODE XREF: sub_10001190+2BEj
 .text:10001458                 movsx   edx, bp
 .text:1000145B                 cmp     byte ptr [edx+ebx], 0
 .text:1000145F                 jnz     loc_10001205
 .text:10001465                 mov     [ebx+28h], ax
 .text:10001469                 mov     ax, word ptr [esp+30h+arg_0]
 .text:1000146E                 mov     [ebx+24h], di
 .text:10001472                 mov     [ebx+22h], si
 .text:10001476                 pop     edi
 .text:10001477                 pop     esi
 .text:10001478                 mov     [ebx+2Ah], cl
 .text:1000147B                 mov     [ebx+26h], ax
 .text:1000147F                 pop     ebp
 .text:10001480                 mov     ax, 1
 .text:10001484                 pop     ebx
 .text:10001485                 add     esp, 20h
 .text:10001488                 retn    14h                // Завершаем Наш Поход. Ура! :)
 .text:10001488                 sub_10001190    endp
 
Для серийного номера из 26-и символов:
1) с 1 по 19 символ, аналогично серийнику из 19-и символов.
2) 20 символ - '*'.
3) с 21 по 26 - дата вида Месяц/День/Год, а какая - вам решать =)

Для серийного номера из 30-и символов:
1) с 1 по 19 символ, аналогично серийнику из 19-и символов.
2) 20 символ - '+'.
3) с 21 по 23 - любые три цифры.
4) 24 символ - '*'.
5) с 25 по 30 - дата вида Месяц/День/Год

Ну, и что же у нас получилось? А вот, что:
1) Номер из 26-и символов. CD20CRK-0313370-FSW*123130 (до 31 января 2030 года. Ха!).
2) Номер из 30-и символов. CD20CRK-0313370-UMK+007*123130.
Находятся они аналогично предыдущим.

У полной версии программы, алгоритм точно такой же. Только вместо 'CD20', там 'RF20'.
Trust me, I know what I'm doing... (Hammer)

Всё, теперь можно и генератор заделать. Удачи! А вот мой.

Этот материал опубликован в целях самообразования, за последствия которого Автор ответственности не несёт!



Обсуждение статьи: Исследование Carrara Studio 2.0 >>>


Материалы находятся на сайте https://exelab.ru



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS