Let me start by saying what I'm about to show you is for educational purposes only. I do not condone hacking or cracking software. If you are a software developer I recommend you obfuscate your assemblies and secure your code base, or you will fall victim to hacking.
I started thinking more about what Pex does, it generates tests for your code. It also generates meaningful values for your methods to get the most code coverage. So could Pex be used to generate a password for software, or find holes in lincese key generators? I first started out by finding a piece of software that was written in .NET, and dropped the assemblies in good old Reflector. I will only be showing you the method, and will not be saying what the software is as to protect the software retailer. The names of the methods have been changed to protect the innocent.
I began by modifying some of the parameters to the method. I already knew things like product key from searching in reflector. I hard coded the value of the product key, which only leaves me with the license key. If I am right, then Pex should try to find all the branches of the code. This means that it will have to at least return one that is true. That true value is a valid key for this particular piece of software. Here is the snippet of code.
public bool ValidateLicenseKey(string licenseKey)
{
string productKey = "9BFE-2BFB-BFF0-2000";
if (licenseKey == null) throw new ArgumentNullException("licenseKey");
productKey = productKey.ToUpper();
licenseKey = licenseKey.ToUpper();
int length = productKey.Length;
int num2 = licenseKey.Length;
if (length > 19)
{
length = 19;
}
if (length != num2)
{
return false;
}
if (licenseKey.CompareTo(productKey) == 0)
{
return false;
}
bool flag = true;
for (int i = length - 1; i >= 0; i--)
{
char cChar = licenseKey[i];
if ((cChar != '-') && (cChar != productKey[i]))
{
int nPos = FindCharPosInLicenseKeyTable(cChar) - i;
if (nPos < 0)
{
nPos = 37 + nPos;
}
nPos--;
if (nPos < 0)
{
nPos = 36;
}
GetLicenseCharByPos(out cChar, nPos);
if (cChar == '\n')
{
flag = false;
}
else
{
flag = cChar == productKey[i];
}
if (!flag)
{
return flag;
}
}
}
return flag;
}
So let me run Pex against it, and see if my assumption has an validity. Wow, it worked! Below is the result screen from Pex, and the corresponding test that generates the correct key
[TestMethod]
[PexGeneratedBy(typeof(BadKeyGeneratorTest))]
public void ValidateLicenseKey09()
{
bool b;
BadKeyGenerator badKeyGenerator = new BadKeyGenerator();
b = this.ValidateLicenseKey(badKeyGenerator, new string('-', 19));
Assert.AreEqual(true, b);
}
The algorithm for this particular key generator has a flaw with dashes. In it's attempt to give me complete code coverage and help me unit test "My" code, Pex unwittingly helped me find a crack. There you have it, Pex could potentially be used to generate keys for software. So how do you avoid this?
Use Pex
Pex is relatively new, but you could use it on legacy code to prevent future hacks on your code.
Obfuscate
Code is what you sell, there is no excuse not to obfuscate your code when it is production ready. There are a lot of good libraries that can help do that.
Pick Better Licensing Schemes
Licensing schemes that report back to a server are always the best, but there are other good licensing schemes. Never try to homebrew your own, there is always someone smarter than you are (above is case in point).
Conclusion
There is a lot in .Net that is good, but even the good can be used to circumvent systems and do devious things.