我有这个资料,不过是全英文的,不晓得你看不看得懂了
Cracking MMTools
02/03/2001 by +DaFixer
Courtesy of Reverser's page of reverse engineering slightly edited
by +Tsehp
There is a crack, a crack in everything That's how the light gets in
Rating ( )begin
ner ( )Intermediate (x)Advanced ( )Expert
The SwiftSoft multimedia tools are not only very nice components for delphi, but also very interesting reversing target. I can honestly say that this is the hardest to crack delphi component protection i've ever seen. But it is not uncrackable
I will try to point mainly on protection itself and i assume you know how to debug and trace.
--------------------------------------------------------------------------------
Cracking MMTools
A very good delphi components protection
Written by +DaFixer
Introduction
MMtools are components for Delphi and C++Builder. They are very nice and good multimedia
components with a strong protection for delphi components
The limitations are that you can
run your applications only if your Delphi/C++Builder is active. The protection uses
mmutil32.dll which is written in Delphi and *IS NOT SHRINKED* !!! Ignore the section names.
One can put what he wants there
It has a custom/homemade decryption implemented that has
this scheme:
1) The application checks if IDE is running. If you are good boy it
calls mmutil32._GetDeviceID_ function
2) _GetDeviceID_ decrypts _GetDeviceStatus_ and some more procedures
3) _GetDeviceStatus_ checks if IDE is running with FindWindow() and comparing the
loaded modules names with the normal delphi dlls that are loaded when delphi is loaded.
4) if all is ok _GetDeviceStatus_ decrypts the rest of mmutil32.dll
5) In addition there are *hidden* and *random* checks in the executable itself that exits
immediately if it found that you are bad guy
Ido
nt like all this and will gonna fix it !
Tools required
W32Dasm,
Hex editor (i use WinHEX),
DeDe 2.44 or higher (I love this tool
) )
SoftIce -- (Optional)
Target's URL/FTP
www.swiftsoft.de
Program History
The protection has been changed from v1.5 to v2.0!
Essay
I wont explain all the crap in this protection because it is huge enough. Instead i will point on
the most interesting part that is the decryption of mmutil32.dll and the checks for is IDE running
there. As sample application you may use project2.exe. You cando
wnload it here.
For now disassemble it with D32DASM and DeDe.
The executable itselfdo
not have in imported modules this mmutil32.dll so it is loaded
from the code. I found the place where all this isdo
ne and will show you how! Start to
debug the target in win32dasm. The first lines are:
00543A80 55 push ebp
00543A81 8BEC mov ebp, esp
00543A83 83C4F4 add esp, -$0C
00543A86 B8D0335400 mov eax, $005433D0
00543A8B E8A435ECFF call 00407034 <-- this is the _InitExe routine
<-- that also initialize units.
* 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]
.....
Initiazation of units means running its initialization code. Step in 00407034 and
continue to trace until you reach the IniUnits() routine:
004039E8 3BF3 cmp esi, ebx
004039EA 7E14 jle 00403A00
004039EC 8B04DF mov eax, [edi+ebx*8] <-- prepare the offset of initialization
<-- routine of a unit
004039EF 43 inc ebx <-- increase processed units counter
004039F0 891DB0845400 mov [$5484B0], ebx
004039F6 85C0 test eax, eax <-- is there any initialization routine
<-- for this unit ?
004039F8 7402 jz 004039FC <-- if no, then
process next unit
004039FA FFD0 call eax <-- else
call it !
004039FC 3BF3 cmp esi, ebx <-- did we processed all units ?
004039FE 7FEC jnle 004039EC <-- loop until all got processed!
When EBX is $30 (hex) the initialization routine for unit MMUtils.dcu is called:
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 <-- bad boys jumps here
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] <-- The first interesting proc
* 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] <-- And the second interesting proc
* Reference to: System.Randomize()
|
00443310 E813F6FBFF call 00402928
00443315 B850C30000 mov eax, $0000C350
......
......
Ok step in the call to MMUtil32._GetDeviceID_() and lets trace a bit more:
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 <-- Decrypts the proc at 00407F28
:00409C74 8BC3 mov eax, ebx
:00409C76 E8ADE2FFFF call 00407F28 <-- Decrypts _GetDeviceStatus_ routine
<-- lets have a closer look:
: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] <-- some very secret params
)
:00CD7F35 lea edx, dword ptr [eax+50]
:00CD7F38 mov edi, dword ptr [edx] <-- like the offset of decryption procedure
: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] <-- and the count of bytes that must be decrypted ($62E)
:00CD7F44 mov edx, 07327281 <-- some parameters for the decryption
:00CD7F49 push 06262771
:00CD7F4E push esi <- this is $0000006C
:00CD7F4F lea ebx, dword ptr [ecx+edx] <-- fast calculation and push (073278AD)
:00CD7F52 push ebx
:00CD7F53 add eax, 00000054
:00CD7F56 mov eax, dword ptr [eax]
:00CD7F58 xchg eax,edx <-- and more secret stuff
)
(-- registers before the call
(EIP=00CD7F59
(EAX=07327281
(ebx=073278ad
(ecx=0000062c
(EDX=00CD9618
(esi=0000006c
(edi=00cd7ef0
(ebp=0069fdfc
(esp=0069fdcc
:00CD7F59 call edi <-- calls decryption routine at 00CD7EF0
The decryption routine:
-----------------------
:00CD7EF0 push ebp
:00CD7EF1 mov ebp, esp
:00CD7EF3 push edi
:00CD7EF4 push ebx
:00CD7EF5 mov ebx, eax <-- some initial value for BL
:00CD7EF7 mov edi, edx <-- pointer to the stream that should be decrypted
: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 <-- gets the modulo
:00CD7F05 and eax, 800000FF <-- as byte
:00CD7F0A jns 00CD7F13
:00CD7F0C dec eax
:00CD7F0D or eax, FFFFFF00
:00CD7F12 inc eax
:00CD7F13 mov ah, byte ptr [edi] <-- store the current still not decrypted byte
:00CD7F15 add byte ptr [edi], bl <-- add BL
:00CD7F17 sub byte ptr [edi], al <-- and substract the prev calc. modulo as byte
:00CD7F19 mov bl, ah <-- store the encrypted byte in BL
:00CD7F1B mov eax, edx <-- store eax
:00CD7F1D inc edi <-- next byte to be decrypted
: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
Well now we know where the first decryption isdo
ne. It is applied for _GetDeviceStatus_ and
some more routines. Lets look at the algo:
D
= E+D[i-1]-f(i)
f(i) is not function of D and/or E
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
Here D is the i-th decrypted byte and E is the i-th encrypted.
Now when we know this algo we can commit patches in _GetDeviceStatus_
Lets look at it what needs to be patched )
_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 <-- This is a call to FindWindowA('TAppBuilder',null)
:00CD99AF test eax, eax <-- if not found
:00CD99B1 je 00CD9BD9 <-- then
you are bad guy
/////////////////////////////////////////////////////////////////////////////////
// to always have the good jump we can patch this je 00CD9BD9 to
// jmp 00CD99B7, where the good guys goes
/////////////////////////////////////////////////////////////////////////////////
: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 <-- This is a call to GetWindowTextA()
:00CD99CB mov eax, dword ptr [esi+3C] <-- This points to 'Delphi'
:00CD99CE mov dl, byte ptr [eax] <-- This is the window text
:00CD99D0 cmp dl, byte ptr [esp+00000380] <-- compares the 1-st letters
:00CD99D7 jne 00CD9A1D
:00CD99D9 mov dl, byte ptr [eax+01]
:00CD99DC cmp dl, byte ptr [esp+00000381] <-- compares the 2-nd letters
:00CD99E3 jne 00CD9A1D
:00CD99E5 mov dl, byte ptr [eax+02]
:00CD99E8 cmp dl, byte ptr [esp+00000382] <-- oh **** the coder of this crap has been lamer
: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] <-- compares till the 5-th letter
:00CD9A13 jne 00CD9A1D
:00CD9A15 mov dword ptr [esp], esi <-- point to string 'DELPHI32.EXE'
:00CD9A18 jmp MMUTIL32.00CD9A9D <-- hope that this jumps to some more usefull code
:00CD9A1D mov eax, dword ptr [esi+40] <-- and here comes the check for '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 <-- bad boys jumps there
: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 <-- looks like offset
<-- of decrypting procedure
:00CD993E mov eax, ebx <-- EAX=EBX=00CD7C18 <-- looks like pointer
<-- to memory array
:00CD9940 call esi <-- interesting routine that creates semaphor with the name
<-- of DHH serail as int (if itdo
es not exists)
: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 in both cases
:00CD9AEB jne 00CD9AF9 <-- jumps in all cases
: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 (interesting routine)
:00CD9B02 lea eax, dword ptr [ebx+000000B0]
:00CD9B08 mov eax, dword ptr [eax]
:00CD9B0A cmp dword ptr [eax], 00000002 <-- thisdo
esnt happen in both cases
:00CD9B0D je 00CD9BD7
///////////////////////////////////////////////////////////////////////////////
// What cames here is comparison of module names of the found
// process with class 'TAppBuilder' with hardcoded strings.
// But this happens only if we run Win9X. else
the jump above to
// 00CD9BD7 is executed and the next crap **** is skiped going
// directly to the routine that decrypts the rest of this funny
// mmutil32.dll. This is the reason why at first the crack run only under
// WinNT2K !!!
//
// Good patch is to patch the above jump to always jump to our good
// 00CD9BD7 offset
//
// See at the end how to patch it !!!
//
// note: When i traced this i still didnt know what type of routine follows below
///////////////////////////////////////////////////////////////////////////////
: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] <-- hmm. I cant trace these calls with W32DASM (
------- LOTS OF CRAP CODE HERE
: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
--- UNTIL THIS PLACE
:00CD9B81 xor edi, edi
:00CD9B83 mov eax, dword ptr [esp] <-- points to 'DELPHI32.EXE'
:00CD9B86 mov eax, dword ptr [eax+4*edi] <-- loads string from an array in EAX
<-- the array is:
'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] is 00CD9C98
// This procedure compares the two strings
:00CD9B91 test eax, eax
:00CD9B93 jne 00CD9B96
:00CD9B95 dec ebp <-- if they are equal EBP is decreased
:00CD9B96 inc edi
:00CD9B97 cmp edi, 00000007
:00CD9B9A jne 00CD9B83 <-- compares with first 7 entries in this array
: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 <-- jump to process next module of found app
<-- with class TAppBuilder and caption starting
<-- with 'Delphi' or '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 <-- This shouldn't jump
<-- if we like to have this **** running
<-- on our Win9x machine )
:00CD9BDE lea eax, dword ptr [ebx+40]
:00CD9BE1 mov eax, dword ptr [eax]
:00CD9BE3 cmp dword ptr [eax], 00000000
:00CD9BE6 jne 00CD9C2E
// Remember that we had some nice decryption routine in [esp+1C] ??
// Well here the good guys have their mmutil32.dll fully decrypted
: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
// And the bad guys come direclty here, without decription
// of 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
Ok now lets calculate our patches we want to commit. The encrypted bytes i calculated
coding a little util that helped me.
look at the algo again if youdo
nt remember it
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
Final Notes
Well this was all. To completely crack mmutil32.dll you need to apply some more patches
like _IDERunning_ to always return true. But this function is not encrypted so you can
patch it yourself. What i mostly wanted to show is how to apply patch in crypted dll
without decrypting it
To completely crack MMTools components we need more work. You cando
wnload my unlocker
here.
Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period than the allowed one. Should you want to STEAL this software instead, youdo
n't need to crack its protection scheme at all: you'll find it on most Warez sites, complete and already regged, farewell,do
n't come back.
--------------------------------------------------------------------------------
You are deep inside reverser's page of reverse engineering, choose your way out: