How to crack
(MSVCRT.dll reverse engineering)
(15 August 1997, slightly edited by Reverser)
Courtesy of Reverser's page
of reverse engineering
Well, here is the email snippet
that precedes this essay:
>> Well, if you had the time... MSVCRT.dll reverse engineering would
>> surely be interesting...
> I did have the time.... Here's my short essay on how to crack WinHacker95
> 2.0. It is intended for Project 7 ("Most Stupid Protection")
I don't need to explain you what MSVCRT.DLL (Micro$oft Visual C++ Run Time library)
is, do I?
(A lesson for lazy and hurried shareware programmers :-)
Cracking WinHacker95 2.0 by iNCuBuS++
This target is one of those little programs that let you play with
the system settings buried deep within the system registry... settings
that are not otherwise available to the average user.
It's much like TweakUI, though it has a few options more. Since
modifying "hidden" settings in the registry is a serious thing, I expected
that this piece of shareware would have had a serious protection.
Well... I was dead wrong!
When a programmer writes his program in C++ we can be sure that he's
either in a hurry to finish his work or he's lazy to put a little more effort
in programming in C (not to mention assembler) and debugging his code (he could
be both: in a hurry and lazy, since the two things go most together :-)
Programming in C or asm would give him the power to control every aspect of
his program's functioning (including the protection scheme). But nooo! He just
wants easy money - putting together pieces of code someone else has written,
coercing them into something that he would call HIS work, in a matter of
Working in this way he will have absolutely no idea about what is
really inside his program - he just creates and manipulates objects of some "class"
from class libraries (like Micro$oft's MFC)filled with bugs and errors and written
by somebody else.
How COULD such a lazyhurried guy ever write a good protection scheme?
Well, this program is written in C++ and has the most stupid protection
scheme I have ever seen!
I was able to extract the serial number from memory in less than 15 minutes
and it would have taken me even less if I had known from the beginning that it was
so stupid and had skipped doublechecking every step of mine!
It uses MSVCRT.dll - Micro$oft Visual C++ Run Time library, so it seemed wise
to me to include MSVCRT's exports in winice.dat as well:
This particular target uses msvcrt40.dll. Now, the quickest way to
check a serial number - from a programmer's perspective - is to use some form of
strcmp function to compare the expected serial number with the one entered by the
Even in that (predictable and stupid) case it would be logical to encrypt the
serial number in some way at least to give us, crackers the hard time decrypting it!
Well, in this case it would have been funny if it had not been sad (for programmers,
that is it)! Whoever wrote this program, left the serial number untouched for anybody
to come and get it.
Entered serial number (plain, no encryption whatsoever) is being compared with
expected serial number (again, unencrypted) probably using MSVCRT's strcmp function.
Getting the expected serial number is as easy as taking the string's address from
So, we do it this way:
We start WinHacker95 and a nagscreen appears asking us to register. We enter the ICE
and do a simple
Now, we return to WH95, enter something for the user name, company and a serial number
and then click on the "Register" button.
SoftICE will pop up several times before we get to our serial number. To find the
address of the buffer into which our serial number is being read, do
That will give you a DWORD hex dump of the stack with all the parameters passed to the
function. The address of the buffer is the second parameter of the function, thus
the second dword on the stack. Once we find the serial number that we have entered,
we'll set a bpr on its buffer and let the target run.
Eventually it will break in the middle of the string comparison routine (inside
MSVCRT.dll). It is NOT MSVCRT!strcmp (which I mentioned earlier), but MSVCRT!_mbscmp
(at least a part of it).
We couldn't just set bpx on MSVCRT!_mbscmp function because only a part of it
is being used, and therefore it wouldn't break into SoftICE when called... a breakpoint
can be set only at the function's starting address!
But, from now on, when we crack password protected M$VC++ programs, we will bpx on
both string comparing functions, just to be sure. An even better idea is to bpx on the
actual code within the functions that are comparing the data that interest us!
Anyway, here's the code snippet, from _mbscmp func, used to compare 2 strings:
014F:78005D79 MOV ESI,[ESP+18] ;Addr. of entered serial number buffer
014F:78005D7D MOV EAX,[ESP+14] ;Addr. of expected serial number buffer
014F:78005D81 MOV DL,[EAX] ;Get a char from one string.
014F:78005D83 MOV BL,[ESI] ;Get a char from the other.
014F:78005D85 MOV CL,DL ;Save a char from expected serial number.
014F:78005D87 CMP DL,BL ;Compare chars.
014F:78005D89 JNZ 78005DAC ;Quit further comparing if they do not match
014F:78005D8B TEST CL,CL ;Jump if it is the end of expected
014F:78005D8D JZ 78005DB6 ;serial number string.
Now, you see how easy it is to get to the right serial number - just look
at the buffer and write it down! But, be aware that the expected serial number is
actually CALCULATED from entered user and company name, so it is always different!
Of course, it's not important, here, since we can get ANY number tweaking the
Well, that's it. Yes, there's nothing more than this. After all, this IS a
candidate for "The Most Stupid Protection!". I just hope that there will be no more
of these stupid protections or... ...we will be out of the job ! :)))))
(c) iNCuBuS++ 1997. All rights reserved
You are deep inside reverser's page of reverse engineering,
choose your way out:
Is reverse engineering illegal?