How to disable the mighty protections with a swift kick in the teeth.
This is the first essay I've written to this page, which i found some time ago.
This site is a real treasure, and I'm sure is widely appreciated. Its good to see it practised as an art by people willing to learn better programming. The arrogant snotty little kids can now go off and try calling them selves 'hackers' instead, and maybe even 'elite ??' (which i hate with much passion). This is the place for cooperating and making the Net what we want it to be. Not what Bill wants it to be. Remember, the net is FREE. Nobody owns it.Nobody has the right ever to own it. Crackers (or should i say reverse engineers) won't own it.
They will free it from the tyranny of Microbloat and censorship.
Now, back on task: I've been cracking on and off for quite a while now (when i have the time and a computer), with mixed success. This is one of the successes, because it has taught me how to 'knife' a protection scheme, instead of 'bulldozing' it.
The example is GetRight v3.1, an excellent program and well protected, to a certain degree ;)
Its handles downloading files, has capability to stop & resume whenever you want etc.
It can 'catch' clicks from Netscape or Microbloat's IE, which means you click on a link, and getright pops up and downloads it instead.
Man i hate writing essays, but this is different, since its not on
Shakesphere, or my feelings
in response to some stupid literature (remember english at school?)
(not that i don't like Shakespeare or anything)..
I started this the usual way, open it up and see what it does. It has two password (or number in this case) entry points. One in the about box, and one in the configuration window.
I started on the one in the about box, because it was the usual deal: enter password, click OK, your a bad boy etc. I set up softice to bpx on hmemcpy, and hit OK. This is an interesting method for breaking, which i have adopted, mainly because it works on any textbox, no matter what API-call is used to check it. The hmemcpy is called once for each textbox, so if there are 3 boxes, skip the first two breaks. Then step through some crap (hmemcpy,USER!BOZOSLIVEHERE (<--what the hell is this??!), more USER shit, GetWindowText, Kernal32!QT_Thunk, finally GetWindowTextA). That might seem like a lot of work, but just sit there tapping F10 until you get back to Getright. Thats the way i do it mostly, you might do it differently, good for you.
Hitting F10 backing out of the subroutines, you see the classic :
:00430675 8D4DF0 lea ecx, dword ptr [ebp-10]
:00430678 E8CCD2FFFF call 0042D949
:0043067D 85C0 test eax, eax <--- here, given away already.
:0043067F 741F je 004306A0 <--- naughty boy, show bad box.
:00430681 8B7E5C mov edi, dword ptr [esi+5C] <-+- good boy
:00430684 E84C4E0400 call 004754D5 | so carry on
:00430689 8B4004 mov eax, dword ptr [eax+04] V
:0043068C 57 push edi
* Possible StringData Ref from Data Obj ->"RegistrationCode" <--- Interesting, registry?
:0043068D 6828B14A00 push 004AB128
* Possible StringData Ref from Data Obj ->"Config" <--- and again, key?
:00430692 6820B14A00 push 004AB120
:00430697 8BC8 mov ecx, eax
:00430699 E884B30300 call 0046BA22
:0043069E EB0E jmp 004306AE
Anyway, you decide to set the conditional jump to the good boy part, by
changing it to
'je 430681', or what ever, and the programs says its registered. You
close the about box, and
just out of curiosity, go to the config window. The number you put in
the window is probably
not here, and it says unregistered or something. You realise your
foolishness and try to find
the reason for what you did above, but take your anger out on:
:00430678 E8CCD2FFFF call 0042D949
instead. This must be a checking routine. So you have a go stepping
Look for yourself, its too big to put all of it here.
Here's the start of a seemingly popular routine:
* Referenced by a CALL at Addresses:
|:004014B4 , :00401B98 , :004058E5 , :00406C68 , :0040929B ,
|:0040D44E , :0040F921 , :00411048 , :0041335B , :0041BD40 ,
|:0041D238 , :0041D88A , :0041DD8D , :0041DF88 , :0041FCD6
|:0042096A , :004236B3 , :00425D82 , :00426922 , :00430678 ,
|:0043F241 , :0043F384 , :00446064
:0042D949 55 push ebp
:0042D94A 8BEC mov ebp, esp
:0042D94C 83EC14 sub esp, 00000014
:0042D94F 53 push ebx
:0042D950 8BD9 mov ebx, ecx
:0042D952 57 push edi
* Possible Reference to Menu: MenuID_0001
:0042D953 6A01 push 00000001
:0042D955 8B03 mov eax, dword ptr [ebx]
:0042D957 5F pop edi
:0042D958 897DF8 mov dword ptr [ebp-08], edi
:0042D95B 8378F80C cmp dword ptr [eax-08], 0000000C <--- Password length must =12
:0042D95F 7407 je 0042D968 <--- It does, carry on
:0042D961 33C0 xor eax, eax <--- Bad, eax=0
:0042D963 E9D9040000 jmp 0042DE41 <--- Get out
* Referenced by a Jump at Address: <--- Result of my engineering, no '(C)onditional or (U)..' ;)
:0042D968 56 push esi <--- Carry on
* Referenced by a Jump at Address:0042D963(U)
:0042DE41 5F pop edi
:0042DE42 5B pop ebx
:0042DE43 C9 leave
:0042DE44 C3 ret
You possibly wonder what else this routine could be used for, since its
I've had dialogues pop up inside this routine telling me my password was bad, where above it pops up after. I don't really want to figure out the 1275 bytes of code, so skip it, i say.
If the password is too short, the routine is skipped altogether, which is good news.
Ok you say, bypass the routine all together. I forget how i did it, but it just caused it to lock up, since it kept on called this routine, expecting something to happen (eax=0 i think it was). We just can't, straight off, do a 'mov eax,1' and 'jmp 0042DE41' right at the start of the routine, because this also causes erratic behaviour. An interesting point about the string reference "RegestrationCode". If the program can't find this string, it will disable password entry, and tell you not to pirate software, as it has a list of pirated codes inside it, numbers 12-digits long. Try one and see. If the value is empty, it will assume you haven't put a code in yet. If the value is anything else, it will check it and probably delete it if it is invalid. Fiddling with it's attempts to play with this value is a waste of time, and will probably lead you to the main routine above.
Now is the time to think.
When the password is short, (or long) eax is zeroed and routine is ended.
We need a way, to have eax not zero and the routine exited in a similar fashion, so the checks outside this routine will be OK.
So, we set:
je 0042d968 to je 0042d963, which jumps over the routine.
At this point, you can see some address in EAX, and [ebp-08] is also non-zero, which holds the good\bad flag.
You can now see how, by changing one byte the program bows down before you.
Ok, sit back and smile to yourself. You've made the programmers
strenuous efforts to secure his
nice little program by making a routine that checks passwords so big and
scary that you run
screaming and buy the program instead null and void. Maybe its only when
you have a go at the
program and look at the above, you appreciate how much time could be
saved by looking and
thinking, instead of bulldozing in and reversing every conditional jump
that make the program
think its registered. A lesson well learnt.
Oh yes: To get WinDasm to show '* Referenced by a Jump at Address:' instead of the '(C)onditional or (U)nconditional Jump' search the exe for the string to the left, write 'Jump ' with the space over the above text [(C)ondi..], then terminate with a 00h.
There are (were) 2 occurrences. It worked for me.
Comments/suggestion/critisicim etc to email@example.com