Взлом MMTools

Перейти на главную страницу, индексную страницу.


Автор: -= 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 =-.


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






Hosted by uCoz