A New Toy
reversing the different 'modes' of a target
by Swann
30 October 1998
Well, well, well... welcome back Swann! For those of you that don't
know nothing, Swann is practically the FOUNDER of the whole +HCU Database.
And if you give a look at aca100.htm you'll see
why.
This essay is both well written and well explained. Interesting for any
reverser or protector. A little too much code maybe (you'll notice that
this is IDA dumping) but the explanations make the effort of following
it well worth. The two tools that are here targeted have some fairly
easy protection schemes. You'll find and download an (uncracked) copy
of the Customizer on my own tools.htm page. My copy is 226304 bytes long, apparently
version 1.10 and has a
ridicolous Cinderella type protection, so I guess it's not the
same version that Swann encountered.
Anyway, enjoy this good essay and enjoy both tools. You'll be able to
see a very simple (and funny) use of customizer in my Scarecrow license
agreements and how to
defeat them, btw.
A New Toy
reversing the different 'modes' of a target
by swann 30 October 1998
Level: intermediate
Tools: standard
Recently on one of those message boards, someone mentioned two tools
I had never heard of. The person and the context were somewhat obscure,
so I was a little reluctant checking them out. Eventually I did, however,
and methinks these tools are worth taking a look at. Their purpose is
runtime editing of Windows windows. Ever had a problem with greyed out
check-boxes? Well, these programs ungrey them so you can give them
the check mark they deserve. You can also send messages to windows,
and with Customiser-- yes, that's an "s", they're from Oz-- you can
even save the changes you've made at runtime (For this purpose,
Customiser leaves shortcuts in the application directory). I tried
these programs with warfare.exe, a cute little strategy game I
had cracked years ago with a lot of effort. With Magic Mouse, this
is just a blast. You select the window, choose "enable," click, and
it's enabled. It's so easy it almost takes the fun out of it.
The programs in question are:
Magic Mouse Demo mm32.exe 137728 bytes
Customiser Demo cust.exe 215552 bytes
Magic Mouse is widely available as mm32demo.exe, Customiser seems to
be available only at the publisher Wanga International's website:
http://www.ozemail.com.au/~wanga
(Download was terribly slow).
Customiser is the more advanced program, it seems to contain all the
functionality of MagicMouse, plus the ability to save the changes. So
this is probably the one you want to get. It is also, from a reversing
point of view, less interesting, since the protection scheme is
trivial: a simple combination of time limit and a nag screen --
patching a "ret" in the beginning of the nag call takes care of both
-- and a limit to the amount of changes you an save, easily located
through string references. This is a five-minutes-crack and not in
need of further elaboration. So, in line with Frav's new policy, I
will not deal with this newer and more powerful tool, but with the
older one.
Magic Mouse, in addition to the nag-and time limit protection, also
has a feature-disabling restriction that is a little more challenging,
and an annoying switch from enabled to disabled at random intervals.
Let's take the obstacles in the order of occurrence. When I first
started the demo up, it was already expired. The usual suspect, the
call to getlocaltime cum subsequent check turns out to be guilty
again.
00401DB5 E8 D6 2F 01 00 call j__getdate
00401DBA 59 pop ecx
00401DBB 81 7D F8 CE 07 00 00 cmp dword ptr [ebp-8], 7CEh
00401DC2 7F 2B jg short loc_401DEF
00401DC4 81 7D F8 CE 07 00 00 cmp dword ptr [ebp-8], 7CEh
00401DCB 75 09 jnz short loc_401DD6
00401DCD 0F BE 4D FD movsx ecx, byte ptr [ebp-3]
00401DD1 83 F9 04 cmp ecx, 4
00401DD4 7F 19 jg short loc_401DEF ;my problem was ;here
00401DD6 loc_401DD6: ; CODE XREF: .text:00401DCBj
00401DD6 81 7D F8 CE 07 00 00 cmp dword ptr [ebp-8], 7CEh
00401DDD 75 27 jnz short loc_401E06
00401DDF 0F BE 45 FD movsx eax, byte ptr [ebp-3]
00401DE3 83 F8 04 cmp eax, 4
00401DE6 75 1E jnz short loc_401E06
00401DE8 0F BE 55 FC movsx edx, byte ptr [ebp-4]
00401DEC 4A dec edx
00401DED 7E 17 jle short loc_401E06
You make the appropriate changes, it's all fairly obvious. After this
modification, you're treated to the startup nagscreen, which also
turns up frequently during normal program execution. Breaking at
messageboxexa will take you to this beauty:
00401108
00401108 ; S u b r o u t i n e
00401108 ; Attributes: bp-based frame
00401108
00401108 sub_401108 proc near; CODE XREF: .text:00401DFCp
00401108 ; .text:00401E13p
00401108 ; .text:00401E8Cp
00401108
00401108 push ebp
00401109 8B EC mov ebp, esp
0040110B 81 C4 2C FF FF FF add esp, 0FFFFFF2Ch
00401111 53 push ebx
00401112 56 push esi
00401113 57 push edi
00401114 8B 75 0C mov esi, [ebp+arg_4]
00401117 8B 5D 08 mov ebx, [ebp+arg_0]
0040111A B8 E0 50 41 00 mov eax, offset unk_4150E0
0040111F E8 AC 33 01 00 call @__InitExceptBlockLDTC
00401124 33 D2 xor edx, edx
00401126 89 15 CC 50 41 00 mov dword_4150CC, edx
0040112C 6A 00 push 0
0040112E 53 push ebx
0040112F E8 20 3A 01 00 call j_EnableWindow
00401134 66 C7 85 3C FF FF FF 14+mov [ebp+var_C4], 14h
0040113D 56 push esi
0040113E 6A 00 push 0
00401140 8D 8D 50 FF FF FF lea ecx, [ebp+var_B0]
00401146 51 push ecx
00401147 E8 74 29 01 00 call sub_413AC0
0040114C 83 C4 0C add esp, 0Ch
0040114F 8B F8 mov edi, eax
00401151 83 85 48 FF FF FF 04 add [ebp+var_B8], 4
00401158 57 push edi
00401159 8B 47 0C mov eax, [edi+0Ch]
0040115C FF 50 14 call dword ptr [eax+14h]
0040115F 59 pop ecx
00401160 8B F8 mov edi, eax
00401162 83 AD 48 FF FF FF 04 sub [ebp+var_B8], 4
00401169 6A 02 push 2
0040116B 8D 95 50 FF FF FF lea edx, [ebp+var_B0]
00401171 52 push edx
00401172 E8 70 2A 01 00 call sub_413BE7
00401177 83 C4 08 add esp, 8
0040117A 66 C7 85 3C FF FF FF 08+mov [ebp+var_C4], 8
00401183 4F dec edi
00401184 75 03 jnz short loc_401189
00401186 4E dec esi
00401187 75 0C jnz short loc_401195
00401189
00401189 loc_401189: ; CODE XREF: sub_401108+7Cj
00401189 6A 00 push 0
0040118B 6A 00 push 0
0040118D 6A 10 push 10h
0040118F 53 push ebx
00401190 E8 13 3A 01 00 call j_PostMessageA
00401195
00401195 loc_401195: ; CODE XREF: sub_401108+7Fj
00401195 6A 01 push 1
00401197 53 push ebx
00401198 E8 B7 39 01 00 call j_EnableWindow
0040119D 8B 8D 2C FF FF FF mov ecx, [ebp+var_D4]
004011A3 64 89 0D 00 00 00 00 mov large fs:0, ecx
004011AA 5F pop edi
004011AB 5E pop esi
004011AC 5B pop ebx
004011AD 8B E5 mov esp, ebp
004011AF 5D pop ebp
004011B0 C3 retn
004011B0 sub_401108 endp
004011B0
004011B1
As you can see from the Xrefs, it's called from three different
locations. You can either cure this at the points of origin, or here
inside the call. No stack complications, just return without executing
-- should take care of this nagging problem.
Alright, now we're free to enjoy the pleasures of the program, only to
be interrupted by the program switching back from enabled to disabled
mode without asking us. Here we should be a bit careful, since we
don't want to patch away our own opportunity for disabling magic
mouse. We only want to get rid of the unmotivated switches executed by
the program without asking our permission. String references take you
to the neutral "call to switch,"
where it all comes together. It has "good" and "bad" callers. Stack
analysis shows that the good caller, i.e.: us, when we voluntarily
disable Magic Mouse, is 405a0a, while the bad, unvoluntary caller is
401e7a. This is the one we want to take care of. (The other callers
listed here by IDA didn't call while I monitored the program, they
might call later and you can then handle them accordingly).
00401ECB ; S u b r o u t i n e
00401ECB ; Attributes: bp-based frame
00401ECB
00401ECB sub_401ECB proc near ;BAD caller ; CODE XREF: .text:00401E7Ap
00401ECB ; .text:00401EA5p
00401ECB ; sub_401F6A+4Ap
00401ECB ; .text:00401FE2p
00401ECB ;GOOD caller ; .text:00405A0Ap
00401ECB ; .text:00405AB6p
00401ECB ; DATA XREF: .data:004152B8o
00401ECB ; .data:004154B0o
00401ECB
00401ECB arg_0= dword ptr 8
00401ECB
00401ECB push ebp
00401ECC 8B EC mov ebp, esp
00401ECE 53 push ebx
00401ECF 8B 5D 08 mov ebx, [ebp+arg_0]
00401ED2 83 7B 21 00 cmp dword ptr [ebx+21h], 0
00401ED6 74 0F jz short loc_401EE7
00401ED8 6A 01 push 1
00401EDA 8D 43 21 lea eax, [ebx+21h]
00401EDD 50 push eax
00401EDE 53 push ebx
00401EDF E8 93 1B 00 00 call sub_403A77
00401EE4 83 C4 0C add esp, 0Ch
00401EE7
00401EE7 loc_401EE7: ; CODE XREF: sub_401ECB+Bj
00401EE7 33 D2 xor edx, edx
00401EE9 89 53 21 mov [ebx+21h], edx
00401EEC 80 7B 4B 00 cmp byte ptr [ebx+4Bh], 0
00401EF0 74 0E jz short loc_401F00
00401EF2 C6 43 4D 00 mov byte ptr [ebx+4Dh], 0
00401EF6 53 push ebx
00401EF7 E8 41 47 00 00 call sub_40663D ;neutral switch call
00401EFC 59 pop ecx
00401EFD 5B pop ebx
00401EFE 5D pop ebp
00401EFF C3 retn
00401F00 ;
Further inspection of bad_caller shows this situation::
00401E64 ; bad_switch_caller
00401E64 loc_401E64: ; DATA XREF: .data:00415270o
00401E64 55 push ebp
00401E65 8B EC mov ebp, esp
00401E67 8B 45 08 mov eax, [ebp+8]
00401E6A 83 3D CC 50 41 00 0F cmp dword_4150CC, 0Fh
00401E71 7C 21 jl short loc_401E94
00401E73 80 78 4B 00 cmp byte ptr [eax+4Bh], 0
00401E77 74 07 jz short loc_401E80;make unconditional
00401E79 50 push eax
00401E7A E8 4C 00 00 00 call sub_401ECB ;unmotivated switch
00401E7F 59 pop ecx
00401E80
00401E80 loc_401E80: ; CODE XREF: .text:00401E77j
00401E80 6A 00 push 0
00401E82 A1 F0 B9 41 00 mov eax, dword_41B9F0
00401E87 8B 10 mov edx, [eax]
00401E89 FF 72 0C push dword ptr [edx+0Ch]
00401E8C E8 77 F2 FF FF call sub_401108
00401E91 83 C4 08 add esp, 8
00401E94
00401E94 loc_401E94: ; CODE XREF: .text:00401E71j
00401E94 5D pop ebp
00401E95 C3 retn
00401E96 ;
So we want to avoid the unmotivated switch at 401e7a, and we do this
by reverting 401e77 into an unconditional jump.
Finally, time for peaceful inspection of the program. And time to take
a look at the most interesting part of the protection: the disabling
of the "exclude mode." The full version of Magic Mouse can exclude a
user defined set of windows, gathered in the file "exlude.lst." That
should help with the reduction of complexity and the focusing on
what's important. Let's see if we can find a way to reenable that.
When you try activating the exclude mode, you get a window telling you
that this feature is not available in the demo version. But we've been
lied to so many times, we're not quite ready yet to believe this. The
caller of this disappointing message is 40659b, and it's worth looking
at it -- and at its context, that's why the following listing is a
little longer than usual.
004064CC loc_4064CC: ; DATA XREF: .data:004152D0o
004064CC 55 ; .data:00415438o
004064CC push ebp
004064CD 8B EC mov ebp, esp
004064CF 51 push ecx
004064D0 53 push ebx
004064D1 8B 5D 08 mov ebx, [ebp+8]
004064D4 33 C0 xor eax, eax ;0== NORMAL mode
004064D6 89 45 FC mov [ebp-4], eax
004064D9 8D 55 FC lea edx, [ebp-4]
004064DC 52 push edx
004064DD 53 push ebx
004064DE E8 C3 00 00 00 call sub_4065A6
004064E3 83 C4 08 add esp, 8
004064E6 80 7B 4B 00 cmp byte ptr [ebx+4Bh], 0
004064EA 74 08 jz short loc_4064F4
004064EC FF 73 19 push dword ptr [ebx+19h]
004064EF E8 D2 E6 00 00 call j_SetCursor
004064F4
004064F4 loc_4064F4: ; CODE XREF: .text:004064EAj
004064F4 5B pop ebx
004064F5 59 pop ecx
004064F6 5D pop ebp
004064F7 C3 retn
004064F8 ;
004064F8
004064F8 loc_4064F8: ; DATA XREF: .data:00415300o
004064F8 55 ; .data:00415450o
004064F8 push ebp
004064F9 8B EC mov ebp, esp
004064FB 51 push ecx
004064FC 53 push ebx
004064FD 8B 5D 08 mov ebx, [ebp+8]
00406500 C7 45 FC 02 00 00 00 mov dword ptr [ebp-4], 2; 2== MOVE mode
00406507 8D 45 FC lea eax, [ebp-4]
0040650A 50 push eax
0040650B 53 push ebx
0040650C E8 95 00 00 00 call sub_4065A6
00406511 83 C4 08 add esp, 8
00406514 80 7B 4B 00 cmp byte ptr [ebx+4Bh], 0
00406518 74 08 jz short loc_406522
0040651A FF 73 19 push dword ptr [ebx+19h]
0040651D E8 A4 E6 00 00 call j_SetCursor
00406522
00406522 loc_406522: ; CODE XREF: .text:00406518j
00406522 5B pop ebx
00406523 59 pop ecx
00406524 5D pop ebp
00406525 C3 retn
00406526 ;
00406526
00406526 loc_406526: ; DATA XREF: .data:00415330o
00406526 55 ; .data:00415468o
00406526 push ebp
00406527 8B EC mov ebp, esp
00406529 51 push ecx
0040652A 53 push ebx
0040652B 8B 5D 08 mov ebx, [ebp+8]
0040652E C7 45 FC 04 00 00 00 mov dword ptr [ebp-4], 4; 4==SEND mode
00406535 8D 45 FC lea eax, [ebp-4]
00406538 50 push eax
00406539 53 push ebx
0040653A E8 67 00 00 00 call sub_4065A6
0040653F 83 C4 08 add esp, 8
00406542 80 7B 4B 00 cmp byte ptr [ebx+4Bh], 0
00406546 74 08 jz short loc_406550
00406548 FF 73 19 push dword ptr [ebx+19h]
0040654B E8 76 E6 00 00 call j_SetCursor
00406550
00406550 loc_406550: ; CODE XREF: .text:00406546j
00406550 5B pop ebx
00406551 59 pop ecx
00406552 5D pop ebp
00406553 C3 retn
00406554 ;
00406554
00406554 loc_406554: ; DATA XREF: .data:00415318o
00406554 55 ; .data:00415480o
00406554 push ebp
00406555 8B EC mov ebp, esp
00406557 51 push ecx
00406558 53 push ebx
00406559 8B 5D 08 mov ebx, [ebp+8]
0040655C C7 45 FC 03 00 00 00 mov dword ptr [ebp-4],3 ;3=PREVIEW mode
00406563 8D 45 FC lea eax, [ebp-4]; we're gonna jump
; there later
00406566 50 push eax
00406567 53 push ebx
00406568 E8 39 00 00 00 call sub_4065A6
0040656D 83 C4 08 add esp, 8
00406570 80 7B 4B 00 cmp byte ptr [ebx+4Bh], 0
00406574 74 08 jz short loc_40657E
00406576 FF 73 19 push dword ptr [ebx+19h]
00406579 E8 48 E6 00 00 call j_SetCursor
0040657E
0040657E loc_40657E: ; CODE XREF: .text:00406574j
0040657E 5B pop ebx
0040657F 59 pop ecx
00406580 5D pop ebp
00406581 C3 retn
00406582 ;
00406582
00406582 loc_406582: ; DATA XREF: .data:004152E8o
00406582 55 ; .data:00415498o
00406582 push ebp
00406583 8B EC mov ebp, esp
00406585 53 push ebx
00406586 8B 5D 08 mov ebx, [ebp+8]
00406589 53 push ebx
0040658A E8 FD FC FF FF call sub_40628C
0040658F 59 pop ecx
00406590 A1 F0 B9 41 00 mov eax, dword_41B9F0
00406595 8B 10 mov edx, [eax]
00406597 FF 72 0C push dword ptr [edx+0Ch]
0040659A 53 push ebx
0040659B E8 CA B9 FF FF call sub_401F6A; EXCLUDE mode doesn't
; work;
004065A0 83 C4 08 add esp, 8
004065A3 5B pop ebx
004065A4 5D pop ebp
004065A5 C3 retn
004065A6
What you can observe here are some strikingly similar pieces of code
for the different "modes" you can work MagicMouse in. The first four
sections are identical, except for the value that is being moved to
[ebp-4]. Further inspection shows that it's 0 for the normal mode, 2
for move, 4 for send, and 3 for preview. It all comes together in
location [41b9e4] which holds the code for the mode of operation.
Obviously, the value that is conspicuously missing here is 1. And our
last, failing, exclude mode section is the only one that has a
different code -- leads us to the demo limit screen instead of the
desired mode of operation. So I guess it couldn't hurt to try the code
of the other sections with our missing value, especially since there
are data references to the exclude mode. The only operational problem
being that there isn't enough space in our section for the length of
code in the other sections. So we'll have to be a little creative, but
that should be worth it. We could, for instance, patch the first part
of the code, up to the decisive line "mov dword ptr [ebp-4], 1" in our
original location, and then jump to one of the other locations to
finish the rest of the code which is identical in all sections.
00406582 ; activated EXCLUDE section
00406582 loc_406582: ; DATA XREF: .data:004152E8o
00406582 55 ; .data:00415498o
00406582 push ebp
00406583 8B EC mov ebp, esp
00406585 51 push ecx
00406586 53 push ebx
00406587 8B 5D 08 mov ebx, [ebp+8]
0040658A C7 45 FC 01 00 00 00 mov dword ptr [ebp-4], 1; "magic"
value
00406591 EB D0 jmp short loc_406563; jmp to Preview--
00406593 ; continue there
00406593 90 nop
00406594 90 nop
And, what can I tell you, it works :) The program creates a file named
"exclude.lst" in which it gathers all the windows you want to exclude
from your operations. There are two restrictions remaining: the
opportunity to specifically exclude hidden windows and system windows.
I doubt that the code for these options is in the program. If it is, I
couldn't locate it. But, of course, you can achieve the same effect
with your exclude list. And you'll probably want to use the Customiser
program anyway, instead of Magic Mouse, since its functionality is
extended. And we're only in it for the reversing anyway.
homepage
links
anonymity
+ORC
students' essays
academy database
bots wars
antismut
tools
cocktails
javascript wars
search_forms
mail_fravia
Is reverse engineering illegal?