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

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


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

Взлом MMTools

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

Очень удобно, когда все крэкерские инструменты, книги и статьи в одном месте. Используйте сборник от EXELAB - вот тут.

Автор: -= ALEX =- <alex-xakep@mail.ru>

Уж очень хорошая IDE Running Check защита!

Введение

MMTools - компоненты для Delphi и С++Builder. Они очень хорошие, можно за пару минут слепить WinAmp :) Ограничениями для этого компонента является то, что ваша прога может запускаться, если только Delphi или С++Builder запущены (обычная защита скажите вы! Не так-то все и просто...) Защита использует файл mmutil32.dll, который написан на Delphi и не сжимается ! Игнорирует имена секций. Только он один можете пихать в себя все, что захочет :) Файл имеет кустарную расшифровку по приведенной ниже схеме:
Прога проверяет запущен ли Delphi или С++Builder. Если все OK она вызывает функцию mmutil32._GetDeviceID_
_GetDeviceID_ расшифровывает _GetDeviceStatus_ и несколько других процедур _GetDeviceStatus_ проверяет выполняется ли IDE с помощью функции FindWindow () и сравнивает загруженные dll с dll, которые загружаются, если запущен Delphi.
Если все OK, то_GetDeviceStatus_ расшифровывает остальную часть mmutil32.dll В добавок имеется много скрытых и случайных проверок и если что-то не так - вылетает!
В данной статье я расскажу, как все это дерьмо убрать !

Необходимые инструменты

Win32Dasm WinHex DeDe

Поехали ...

В данной статье я не буду писать, как удалить все проверки из вашей проги , т.к. для этого надо много времени и нервов :) Вместо этого я расскажу о наиболее интересных моментах расшифровки mmutil32.dll и проверок на запуск IDE. Для начала создаем небольшой проектик, помещаем туда компонент MMLedPanel, компилируем, получившийся ехе'шник мы будем использовать.
Для начала дизассемблим это дело с помощью Win32Dasm и DeDe. В списке импортируемых dll'ок нет mmutil32.dll, поэтому dll'ка вызывается с помощью кода. Я нашел то место, где все это происходит и покажу как все это делается. Начнем дебаггить прогу в Win32Dasm. Первые строчки выглядят так:
 00543A80   55                     push    ebp
 00543A81   8BEC                 mov     ebp, esp
 00543A83   83C4F4              add     esp, -$0C
 00543A86   B8D0335400       mov     eax, $005433D0
 00543A8B   E8A435ECFF       call    00407034  <-- это _InitExe функция
                                                     <-- она также инициализирует модули.
 
 * Possible reference to TApplication instance
 |
 00543A90   A198785400       mov     eax, dword ptr [$547898]
 00543A95   8B00                  mov     eax, [eax]
 
 * Reference to: Forms.TApplication.Initialize()
 |
 00543A97   E88090F0FF         call    0044CB1C
 00543A9C   8B0D387A5400   mov     ecx, [$547A38]
 
 .....
 
 Инициализация модулей означает запуск их инициализированного кода. Пропустим 00407034 и
 продолжим трассировать пока не достигнем InitUnits():
 004039E8   3BF3                   cmp     esi, ebx
 004039EA   7E14                   jle     00403A00
 
 004039EC   8B04DF                 mov     eax, [edi+ebx*8] <-- подготовить offset инициализации
                                                            <-- модуля
 
 004039EF   43                     inc     ebx              <-- увеличить счетчик инициализированных модулей
 004039F0   891DB0845400           mov     [$5484B0], ebx
 
 004039F6   85C0                   test    eax, eax         <-- есть ли еще инициализационные
 функции для этого модуля
 
 
 004039F8   7402                   jz      004039FC         <-- если нету, то процессим следующий модуль
 
 004039FA   FFD0                   call    eax              <-- иначе вызываем ее !
 
 004039FC   3BF3                   cmp     esi, ebx         <-- Пока не достигнем всех процессов
 004039FE   7FEC                   jnle    004039EC
 
 
 Когда EBX = $30 (hex) вызывается инициализирующая ф-я MMUtils.dcu:
 
 
 0044326C   55                     push    ebp
 0044326D   8BEC                   mov     ebp, esp
 0044326F   33C0                   xor     eax, eax
 00443271   55                     push    ebp
 00443272   68EB334400             push    $004433EB
 
 ***** TRY
 |
 00443277   64FF30                 push    dword ptr fs:[eax]
 0044327A   648920                 mov     fs:[eax], esp
 0044327D   832D0899440001         sub     dword ptr [$449908], +$01
 00443284   0F8353010000           jnb     004433DD
 
 * Reference to: MMUtils.FindIDERunning()
 |
 0044328A   E881FBFFFF             call    00442E10
 0044328F   84C0                   test    al, al
 00443291   7529                   jnz     004432BC      <-- Плохие ребята прыгают сюда !!!
 00443293   6A00                   push    $00
 00443295   B82C994400             mov     eax, $0044992C
 
 * Possible String Reference to: 'IDE not found. Please register !'
 |
 0044329A   BAFC334400             mov     edx, $004433FC
 
 * Reference to: Sysutils.StrPCopy(System.AnsiString)
 |
 0044329F   E8E04AFCFF             call    00407D84
 004432A4   8BD0                   mov     edx, eax
 
 * Possible String Reference to: 'Multimedia Tools'
 |
 004432A6   B920344400             mov     ecx, $00443420
 
 * Possible reference to TApplication instance
 |
 004432AB   A1E08D4400             mov     eax, dword ptr [$448DE0]
 004432B0   8B00                   mov     eax, [eax]
 
 * Reference to: Forms.TApplication.MessageBox()
 |
 004432B2   E899AFFFFF             call    0043E250
 
 * Reference to: System..Halt0()
 |
 004432B7   E86405FCFF             call    00403820
 
 * Reference to: MMUtils.InitMMUtils()
 |
 004432BC   E817FCFFFF             call    00442ED8
 004432C1   680C994400             push    $0044990C
 
 * Reference to: kernel32.InitializeCriticalSection()
 |
 004432C6   E8512CFCFF             call    00405F1C
 
 * Reference to: TransactionOK
 |
 004432CB   C605488B440001         mov     byte ptr [$448B48], $01
 
 * Reference to: GetDeviceID
 |
 004432D2   833D2499440000         cmp     dword ptr [$449924], +$00
 004432D9   740B                   jz      004432E6
 
 * Reference to: MMUtil32._GetDeviceID_()
 |
 004432DB   FF1524994400           call    dword ptr [$449924]  <-- Первая интересная функция
 
 * Reference to: InitCode
 |
 004432E1   A32C8B4400             mov     dword ptr [$448B2C], eax
 
 * Reference to: InitCode
 |
 004432E6   833D2C8B440000         cmp     dword ptr [$448B2C], +$00
 004432ED   7516                   jnz     00443305
 
 * Possible String Reference to: 'Initialization Error'
 |
 004432EF   B93C344400             mov     ecx, $0044343C
 004432F4   B201                   mov     dl, $01
 
 * Possible reference to class Exception
 |
 004432F6   A1806B4000             mov     eax, dword ptr [$406B80]
 
 * Reference to: Sysutils.Exception.Create(System.AnsiString)
 |
 004432FB   E86459FCFF             call    00408C64
 
 * Reference to: System..RaiseExcept()
 |
 00443300   E84301FCFF             call    00403448
 
 * Reference to: InitCode
 |
 00443305   A12C8B4400             mov     eax, dword ptr [$448B2C]
 
 * Reference to: GetDeviceStatus
 |
 0044330A   FF1528994400           call    dword ptr [$449928]   <-- И вторая интересная функция
 
 * Reference to: System.Randomize()
 |
 00443310   E813F6FBFF             call    00402928
 00443315   B850C30000             mov     eax, $0000C350
 
 ......
 ......
 
 Ok пропустим вызов MMUtil32._GetDeviceID_() и протрассируем еще немного:
 Exported fn(): _GetDeviceID_ - Ord:0002h
 :00409C48 53                      push ebx
 :00409C49 803DC0D2400000          cmp byte ptr [0040D2C0], 00
 :00409C50 7441                    je 00409C93
 :00409C52 33C0                    xor eax, eax
 :00409C54 A3D8E54000              mov dword ptr [0040E5D8], eax
 :00409C59 33C0                    xor eax, eax
 :00409C5B A3DCE54000              mov dword ptr [0040E5DC], eax
 :00409C60 BB187C4000              mov ebx, 00407C18
 :00409C65 BAC87E4000              mov edx, 00407EC8
 :00409C6A B86C874000              mov eax, 0040876C
 :00409C6F E8E8E1FFFF              call 00407E5C <-- Расшифровывает вызов по адресу 00407F28
 :00409C74 8BC3                    mov eax, ebx
 :00409C76 E8ADE2FFFF              call 00407F28 <-- Расшифровывает _GetDeviceStatus_
                                                 <-- посмотри на эту функцию:
    :00CD7F28 push ebx
    :00CD7F29 push esi
    :00CD7F2A push edi
 
    :00CD7F2B lea edx, dword ptr [eax+4C]
    :00CD7F2E mov esi, dword ptr [edx]
 
    :00CD7F30 lea edx, dword ptr [eax+64]
    :00CD7F33 sub esi, dword ptr [edx]    <-- несколько интересных параметров :))
 
    :00CD7F35 lea edx, dword ptr [eax+50]
    :00CD7F38 mov edi, dword ptr [edx]    <-- Подобно смещению процедуры расшифровки
 
    :00CD7F3A lea edx, dword ptr [eax+5C]
    :00CD7F3D mov ecx, dword ptr [edx]
 
    :00CD7F3F lea edx, dword ptr [eax+54]
    :00CD7F42 sub ecx, dword ptr [edx]    <-- И кол-во байтов, которые должны быть расшифрованы ($62E)
 
    :00CD7F44 mov edx, 07327281           <-- несколько параметров для расшифровки
    :00CD7F49 push 06262771
    :00CD7F4E push esi <- this is $0000006C
    :00CD7F4F lea ebx, dword ptr [ecx+edx] <-- Быстрое вычисление и помещает (073278AD)
    :00CD7F52 push ebx
 
    :00CD7F53 add eax, 00000054
    :00CD7F56 mov eax, dword ptr [eax]
    :00CD7F58 xchg eax,edx                <-- Более секретный материал :))
 
 (-- регистры перед вызывом
 (EIP=00CD7F59
 (EAX=07327281
 (ebx=073278ad
 (ecx=0000062c
 (EDX=00CD9618
 (esi=0000006c
 (edi=00cd7ef0
 (ebp=0069fdfc
 (esp=0069fdcc
    :00CD7F59 call edi   <-- вызывает функции расшифровки по адресу 00CD7EF0
 
 
      The decryption routine:
      -----------------------
      :00CD7EF0 push ebp
      :00CD7EF1 mov ebp, esp
      :00CD7EF3 push edi
      :00CD7EF4 push ebx
 
      :00CD7EF5 mov ebx, eax  <-- несколько значений для BL
      :00CD7EF7 mov edi, edx  <-- Указатель на поток, который должен быть расшифрован
      :00CD7EF9 imul [ebp+10]               <-- [ebp+10] = 06262771
      :00CD7EFC add eax, dword ptr [ebp+0C] <-- [ebp+0c] = 6C
      :00CD7EFF cdq
      :00CD7F00 idiv [ebp+08]               <-- [ebp+10] = 06262771
      :00CD7F03 mov eax, edx
      :00CD7F05 and eax, 800000FF
      :00CD7F0A jns 00CD7F13
      :00CD7F0C dec eax
      :00CD7F0D or eax, FFFFFF00
      :00CD7F12 inc eax
      :00CD7F13 mov ah, byte ptr [edi]      <-- хранить поток все еще не расшифрованного байта
      :00CD7F15 add byte ptr [edi], bl      <-- и BL
      :00CD7F17 sub byte ptr [edi], al      <--
      :00CD7F19 mov bl, ah                  <-- хранить зашифрованный байт в BL
      :00CD7F1B mov eax, edx                <-- хранить eax
      :00CD7F1D inc edi                     <-- следующий байт для расшифровки
      :00CD7F1E loop 00CD7EF9
 
      :00CD7F20 pop ebx
      :00CD7F21 pop edi
      :00CD7F22 pop ebp
      :00CD7F23 ret 000C
 
 
    :00CD7F5B pop edi
    :00CD7F5C pop esi
    :00CD7F5D pop ebx
    :00CD7F5E ret
 
 :00409C7B C605C8D2400001          mov byte ptr [0040D2C8], 01
 :00409C82 891DB8D24000            mov dword ptr [0040D2B8], ebx
 :00409C88 E81FECFFFF              call 004088AC
 :00409C8D 8BC3                    mov eax, ebx
 :00409C8F 03C0                    add eax, eax
 :00409C91 5B                      pop ebx
 :00409C92 C3                      ret
 
 Теперь мы знаем, где первая расшифровка завершена. Это нужно для _GetDeviceStatus_ и
 несколько других ф-ий. Посмотрим на алгоритм:
 
  D[i] = E[i]+D[i-1]-f(i)
 
  f(i) не функция от D[i] и/или E[i]
  and : f(i)  = byte [(VARi-1 * CONST1 + CONST2) mod CONST3]
        VARi  = dword[(VARi-1 * CONST1 + CONST2) mod CONST3]
        CONST1= 06262771
        CONST2= 073278AD
        CONST3= 6C
        D[-1] = 81
        VAR-1 = 07327281
 
  Здесь D[i] i-ый расшифрованный байт и E[i]  i-ый зашифрованный.
  Теперь, когда мы знаем алгоритм мы можем пропатчит необходимое в _GetDeviceStatus_ :)
  Давайте посмотрим, что для этого надо сделать.
 
 _GetDeviceStatus_()
    :00CD997C push ebx
    :00CD997D push esi
    :00CD997E push edi
    :00CD997F push ebp
    :00CD9980 add esp, FFFFFC2C
    :00CD9986 mov ebx, eax
    :00CD9988 mov ebp, 00000007
    :00CD998D shr ebx, 1
    :00CD998F xor eax, eax
    :00CD9991 mov dword ptr [esp], eax
    :00CD9994 lea eax, dword ptr [ebx+2C]
    :00CD9997 mov eax, dword ptr [eax]
    :00CD9999 mov eax, dword ptr [eax]
    :00CD999B lea edx, dword ptr [ebx+38]
    :00CD999E mov edx, dword ptr [edx]
    :00CD99A0 mov dword ptr [esp+28], edx
    :00CD99A4 lea esi, dword ptr [ebx+68]
    :00CD99A7 push 00000000
    :00CD99A9 mov edx, dword ptr [esi+38]
    :00CD99AC push edx
    :00CD99AD call eax       <-- это вызов функции FindWindowA('TAppBuilder',null)
    :00CD99AF test eax, eax  <-- если не нашли,
    :00CD99B1 je 00CD9BD9    <-- то мы плохие ребята :)
 
    /////////////////////////////////////////////////////////////////////////////////
    // чтобы всегда был хороший прыжок надо заменить je 00CD9BD9 на
    // jmp 00CD99B7, как делают хорошие ребята :)
    /////////////////////////////////////////////////////////////////////////////////
 
    :00CD99B7 lea edx, dword ptr [ebx+30]
    :00CD99BA mov edx, dword ptr [edx]
    :00CD99BC mov edx, dword ptr [edx]
    :00CD99BE push 00000050
    :00CD99C0 lea ecx, dword ptr [esp+00000384]
    :00CD99C7 push ecx
    :00CD99C8 push eax
    :00CD99C9 call edx       <-- это вызов функции GetWindowTextA()
    :00CD99CB mov eax, dword ptr [esi+3C]  <-- это указатель на 'Delphi'
    :00CD99CE mov dl, byte ptr [eax]       <-- это текст окна
    :00CD99D0 cmp dl, byte ptr [esp+00000380]  <-- сравниваем первые символы
    :00CD99D7 jne 00CD9A1D
    :00CD99D9 mov dl, byte ptr [eax+01]
    :00CD99DC cmp dl, byte ptr [esp+00000381]  <-- сравниваем вторые символы
    :00CD99E3 jne 00CD9A1D
    :00CD99E5 mov dl, byte ptr [eax+02]
    :00CD99E8 cmp dl, byte ptr [esp+00000382]  <-- о черт! это была ламерская проверка :)
    :00CD99EF jne 00CD9A1D
    :00CD99F1 mov dl, byte ptr [eax+03]
    :00CD99F4 cmp dl, byte ptr [esp+00000383]
    :00CD99FB jne 00CD9A1D
    :00CD99FD mov dl, byte ptr [eax+04]
    :00CD9A00 cmp dl, byte ptr [esp+00000384]
    :00CD9A07 jne 00CD9A1D
    :00CD9A09 mov al, byte ptr [eax+05]
    :00CD9A0C cmp al, byte ptr [esp+00000385]  <-- сравнение продолжается до пятого символа
    :00CD9A13 jne 00CD9A1D
    :00CD9A15 mov dword ptr [esp], esi  <-- указатель на 'DELPHI32.EXE'
 
    :00CD9A18 jmp MMUTIL32.00CD9A9D   <-- надеемся что этот прыжок на более полезный код :)
 
    :00CD9A1D mov eax, dword ptr [esi+40]     <-- здесь идет проверка на 'C++Builder'
    :00CD9A20 mov dl, byte ptr [eax]
    :00CD9A22 cmp dl, byte ptr [esp+00000380]
    :00CD9A29 jne 00CD9A9D
    :00CD9A2B mov dl, byte ptr [eax+01]
    :00CD9A2E cmp dl, byte ptr [esp+00000381]
    :00CD9A35 jne 00CD9A9D
    :00CD9A37 mov dl, byte ptr [eax+02]
    :00CD9A3A cmp dl, byte ptr [esp+00000382]
    :00CD9A41 jne 00CD9A9D
    :00CD9A43 mov dl, byte ptr [eax+03]
    :00CD9A46 cmp dl, byte ptr [esp+00000383]
    :00CD9A4D jne 00CD9A9D
    :00CD9A4F mov dl, byte ptr [eax+04]
    :00CD9A52 cmp dl, byte ptr [esp+00000384]
    :00CD9A59 jne 00CD9A9D
    :00CD9A5B mov dl, byte ptr [eax+05]
    :00CD9A5E cmp dl, byte ptr [esp+00000385]
    :00CD9A65 jne 00CD9A9D
    :00CD9A67 mov dl, byte ptr [eax+06]
    :00CD9A6A cmp dl, byte ptr [esp+00000386]
    :00CD9A71 jne 00CD9A9D
    :00CD9A73 mov dl, byte ptr [eax+07]
    :00CD9A76 cmp dl, byte ptr [esp+00000387]
    :00CD9A7D jne 00CD9A9D
    :00CD9A7F mov dl, byte ptr [eax+08]
    :00CD9A82 cmp dl, byte ptr [esp+00000388]
    :00CD9A89 jne 00CD9A9D
    :00CD9A8B mov al, byte ptr [eax+09]
    :00CD9A8E cmp al, byte ptr [esp+00000389]
    :00CD9A95 jne 00CD9A9D
    :00CD9A97 lea eax, dword ptr [esi+1C]
    :00CD9A9A mov dword ptr [esp], eax
 
    :00CD9A9D cmp dword ptr [esp], 00000000
    :00CD9AA1 je 00CD9BD9  <-- плохие ребята прыгают туда :)
 
    :00CD9AA7 lea eax, dword ptr [ebx+14]
    :00CD9AAA mov eax, dword ptr [eax]
    :00CD9AAC mov eax, dword ptr [eax]
    :00CD9AAE mov dword ptr [esp+18], eax  <-- EAX=82C154B8
 
    :00CD9AB2 lea eax, dword ptr [ebx+18]
    :00CD9AB5 mov eax, dword ptr [eax]
    :00CD9AB7 mov eax, dword ptr [eax]
    :00CD9AB9 mov dword ptr [esp+20], eax  <-- EAX=82C154C8
 
    :00CD9ABD lea eax, dword ptr [ebx+1C]
    :00CD9AC0 mov eax, dword ptr [eax]
    :00CD9AC2 mov eax, dword ptr [eax]
    :00CD9AC4 mov dword ptr [esp+24], eax  <-- EAX=82c154d8
 
    :00CD9AC8 lea eax, dword ptr [ebx+3C]
    :00CD9ACB mov eax, dword ptr [eax]
    :00CD9ACD mov dword ptr [esp+08], eax  <-- EAX=00CD48E8
                                           <--     00CD48E8 jmp KERNEL32.CloseHandle
 
    :00CD9AD1 lea eax, dword ptr [ebx+000000B4]
    :00CD9AD7 mov edi, dword ptr [eax]     <-- EDI=00CD9930
 
    :00CD9AD9 lea eax, dword ptr [ebx+000000C0]
    :00CD9ADF mov eax, dword ptr [eax]     <-- EAX=00CD9D08
 
    :00CD9AE1 mov dword ptr [esp+2C], eax
    :00CD9AE5 mov eax, ebx                 <-- EAX=00CD7C18
    :00CD9AE7 call edi
 
 
       :00CD9930 push ebx
       :00CD9931 push esi
       :00CD9932 mov ebx, eax  <-- EBX=EAX=00CD7C18
 
       :00CD9934 lea eax, dword ptr [ebx+000000CC]
       :00CD993A mov eax, dword ptr [eax]
 
       :00CD993C mov esi, eax  <-- ESI=EAX=00CD8F88   <-- выглядит как offset
                                                      <-- процедуры расшифровки
 
       :00CD993E mov eax, ebx  <-- EAX=EBX=00CD7C18   <-- выглядит как указатель
                                                      <-- к массиву памяти
 
       :00CD9940 call esi      <-- Интересный вызов
       :00CD9942 lea edx, dword ptr [ebx+000000BC]
       :00CD9948 mov edx, dword ptr [edx]
       :00CD994A mov byte ptr [edx], al
       :00CD994C add ebx, 000000B8
       :00CD9952 mov edx, dword ptr [ebx]
       :00CD9954 inc dword ptr [edx]
       :00CD9956 pop esi
       :00CD9957 pop ebx
       :00CD9958 ret
 
    :00CD9AE9 test al, al   <-- AL=01 в обоих случаях
    :00CD9AEB jne 00CD9AF9  <-- прыгаем в любом случае
 
    :00CD9AED call [esp+2C]
    :00CD9AF1 test al, al
    :00CD9AF3 je 00CD9BD9
 
    :00CD9AF9 lea eax, dword ptr [ebx+44]
    :00CD9AFC mov eax, dword ptr [eax]
    :00CD9AFE mov dword ptr [esp+1C], eax  <-- EAX=00CD995C (интересно!!!)
 
    :00CD9B02 lea eax, dword ptr [ebx+000000B0]
    :00CD9B08 mov eax, dword ptr [eax]
    :00CD9B0A cmp dword ptr [eax], 00000002 <-- это не случится в любом случае
    :00CD9B0D je 00CD9BD7
 
 ///////////////////////////////////////////////////////////////////////////////
 // Патч должен исправлять вышеуказанный переход, чтобы всегда переходить на
 // 00CD9BD7 offset :)
 //
 // Смотри до конца и увидишь как пропатчить это !!!
 //
 ///////////////////////////////////////////////////////////////////////////////
 
    :00CD9B13 lea eax, dword ptr [ebx+20]
    :00CD9B16 mov eax, dword ptr [eax]
    :00CD9B18 mov eax, dword ptr [eax]
    :00CD9B1A mov dword ptr [esp+04], eax
    :00CD9B1E push 00000000
    :00CD9B20 push 00000002
    :00CD9B22 call [esp+20]
 ------- ПРОПУЩЕНО МНОГО КОДА
    :00CD9B26 mov dword ptr [esp+10], eax
    :00CD9B2A lea eax, dword ptr [ebx+24]
    :00CD9B2D mov eax, dword ptr [eax]
    :00CD9B2F mov eax, dword ptr [eax]
    :00CD9B31 mov dword ptr [esp+0C], eax
    :00CD9B35 mov dword ptr [esp+00000258], 00000128
    :00CD9B40 lea eax, dword ptr [esp+00000258]
    :00CD9B47 push eax
    :00CD9B48 mov eax, dword ptr [esp+14]
    :00CD9B4C push eax
    :00CD9B4D call [esp+28]
    :00CD9B51 test eax, eax
    :00CD9B53 je 00CD9BCC
 
    :00CD9B55 mov eax, dword ptr [esp+00000260]
    :00CD9B5C push eax
    :00CD9B5D push 00000008
    :00CD9B5F call [esp+20]
    :00CD9B63 mov dword ptr [esp+14], eax
    :00CD9B67 mov [esp+30], 00000225
    :00CD9B6F lea eax, dword ptr [esp+30]
    :00CD9B73 push eax
    :00CD9B74 mov eax, dword ptr [esp+18]
    :00CD9B78 push eax
    :00CD9B79 call [esp+0C]
    :00CD9B7D test eax, eax
    :00CD9B7F je 00CD9BAE
 
 --- ПОКА НЕ УВИДИМ ЭТОТ КУСОК
    :00CD9B81 xor edi, edi
    :00CD9B83 mov eax, dword ptr [esp]        <--  указатель на 'DELPHI32.EXE'
    :00CD9B86 mov eax, dword ptr [eax+4*edi]  <--  грузим строки из массива EAX
                                              <--  Массив содержит:
                                                   'DELPHI32.EXE', 'DCC.DLL', 'DELPHIMM.DLL'
                                                   'DFWEIT.DLL', 'BORLNDMM.DLL', 'DCC40.DLL'
                                                   'DCC50.DLL', 'BCBEDIT.DLL', ...
    :00CD9B89 lea edx, dword ptr [esp+50]     <-- 'USER32.DLL'
    :00CD9B8D call [esp+28]                   <-- [ESP+28] есть 00CD9C98
 
      // Эта процедура сравнивает две строчки
    :00CD9B91 test eax, eax
    :00CD9B93 jne 00CD9B96
 
    :00CD9B95 dec ebp <-- если они равны EBP уменшен
    :00CD9B96 inc edi
 
    :00CD9B97 cmp edi, 00000007
    :00CD9B9A jne 00CD9B83 <-- сравниваем с первыми 7 строчками в этом массиве
 
 
    :00CD9B9C lea eax, dword ptr [esp+30]
    :00CD9BA0 push eax
    :00CD9BA1 mov eax, dword ptr [esp+18]
    :00CD9BA5 push eax
    :00CD9BA6 call [esp+14]
    :00CD9BAA test eax, eax
    :00CD9BAC jne 00CD9B81 <-- прыжок, чтобы обработать следующую проверку приложения
                           <-- с классом TAppBuilder и заголовками
                           <-- 'Delphi' или 'C++Builder'
 
 
 
    :00CD9BAE mov eax, dword ptr [esp+14]
    :00CD9BB2 push eax
    :00CD9BB3 call [esp+0C]
    :00CD9BB7 lea eax, dword ptr [esp+00000258]
    :00CD9BBE push eax
    :00CD9BBF mov eax, dword ptr [esp+14]
    :00CD9BC3 push eax
    :00CD9BC4 call [esp+2C]
    :00CD9BC8 test eax, eax
    :00CD9BCA jne 00CD9B55
 
 
    :00CD9BCC mov eax, dword ptr [esp+10]
    :00CD9BD0 push eax
    :00CD9BD1 call [esp+0C]
    :00CD9BD5 jmp MMUTIL32.00CD9BD9
    :00CD9BD7 xor ebp, ebp
 
    :00CD9BD9 cmp ebp, 00000003
    :00CD9BDC jg 00CD9C2E <-- Здесь не должен осуществляться переход
                          <-- если мы хотим, чтобы это работало
                          <-- на Win9x :))
 
    :00CD9BDE lea eax, dword ptr [ebx+40]
    :00CD9BE1 mov eax, dword ptr [eax]
    :00CD9BE3 cmp dword ptr [eax], 00000000
    :00CD9BE6 jne 00CD9C2E
 
    // Помните, что у нас была функция расшифровки по адресу [esp+1C] ??
    // Итак, здесь хорошие ребята имеют mmutil32.dll полностью расшифрованный :)
    :00CD9BE8 lea edx, dword ptr [ebx+58]
    :00CD9BEB mov ecx, dword ptr [edx]
    :00CD9BED lea eax, dword ptr [ebx+54]
    :00CD9BF0 sub ecx, dword ptr [eax]
    :00CD9BF2 mov edx, dword ptr [eax]
    :00CD9BF4 mov al, 7E
    :00CD9BF6 call [esp+1C]
 
    :00CD9BFA lea edx, dword ptr [ebx+60]
    :00CD9BFD mov ecx, dword ptr [edx]
    :00CD9BFF lea eax, dword ptr [ebx+000000F8]
    :00CD9C05 sub ecx, dword ptr [eax]
    :00CD9C07 mov edx, dword ptr [eax]
    :00CD9C09 mov al, D3
    :00CD9C0B call [esp+1C]
 
    :00CD9C0F lea eax, dword ptr [ebx+34]
    :00CD9C12 mov eax, dword ptr [eax]
    :00CD9C14 mov eax, dword ptr [eax]
    :00CD9C16 mov edx, dword ptr [esi+44]
    :00CD9C19 push edx
    :00CD9C1A push 00000001
    :00CD9C1C push 00000000
    :00CD9C1E push 00000000
    :00CD9C20 call eax
    :00CD9C22 lea edx, dword ptr [ebx+000000C8]
    :00CD9C28 mov edx, dword ptr [edx]
    :00CD9C2A mov dword ptr [edx], eax
    :00CD9C2C xor ebp, ebp
 
    // А плохие ребята утправляются сюда, без расшифровки mmutil32.dll !!!
    :00CD9C2E add ebx, 00000040
    :00CD9C31 mov eax, dword ptr [ebx]
    :00CD9C33 inc dword ptr [eax]
    :00CD9C35 mov eax, ebp
    :00CD9C37 add esp, 000003D4
    :00CD9C3D pop ebp
    :00CD9C3E pop edi
    :00CD9C3F pop esi
    :00CD9C40 pop ebx
    :00CD9C41 ret
 
 Тепрь давайте подсчитаем наш патч .Зашифрованные байта, которые я вычислил помогли
  мне составить небольшую утилиту, которая помогла мне. Посмотрим на алгоритм, ели вы его забыли:
 
    RVA             : 00CD99B1
    Physical Offset : 00008DB1
    Instruction     : je 00CD9BD9
    encrypted           : 5F, 8E, 90, 51, C8, 4C
    decrypted           : F0, 84, 22, 02, 00, 00 (jz  +00000222)
    patched             : 90, E9, F0, 00, 00, 00 (nop, jmp 00CD9AA7)
    patched & encrypted : E0, 72, 7A, 65, B4, 60
 
    RVA             : 00CD9B0D
    Physical Offset : 00008F0D
    Instruction     : je 00CD9BD7
    encrypted           : 1B, 4E, FE, 68, 0A, D7
    decrypted           : F0, 84, C4, 00, 00, 00 (jz +000000C4)
    patched             : 90, E9, C4, 00, 00, 00 (nop, jmp +000000C4)
    patched & encrypted : 9C, 32, 1A, 4C, 26, BB
 

Финал !

Итак это все. Чтобы полностью взломать mmutil32.dll, Вы должны применить еще несколько патчей подобно _IDERunning_, чтобы всегда возвращала истину. Но эта функция не зашифрована, так что Вы можете исправить это сами. Главным образом я хотел показать как применить патч в зашифрованном dll, без его расшифровки :)
Чтобы полностью взломать MMTOOLS компоненты, надо очень много времени. Вы можете скачать мой универсальный unclocker.

Автор: -= ALEX =-.

Обсуждение статьи: Взлом MMTools >>>


Комментарии к статье: Взлом MMTools

!!! 30.01.2005 01:28:01
А где скачать unclocker?
---
pfrofis_alex 21.03.2005 11:15:56
не могу найти unclocker? ни где.
www.ALEX-XAKEP.tk - не работает
alex-xakep@mail.ru - отсутствует или заблокирован.

---
raptor 26.04.2005 10:22:11
нашел unclocker
http://www.woodmann.com/fravia/zipped/tmgmmt2.zip
---
Vadim 10.10.2005 23:11:24
Врядли стоит искать хакера ALEX\’а, потому как данный текст просто перевод статьи \"Cracking MMTools. A very good delphi components protection\" by DaFixer
---

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



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


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