Исследование 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)

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

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


Материалы находятся на сайте http://cracklab.narod.ru/doc/






Hosted by uCoz