Question: [original] analysis, debugging, and cracking of ants profiler (for. Net)
Author: tankaiha
Time: 2006-08-24, 11: 33: 35
Chain: http://bbs.pediy.com/showthread.php? T = 30953
[Article Title]: analysis, debugging, and cracking of ants profiler (for. Net)
[Author]: tankaiha
[Author's homepage]: vxer.cn
[Software name]: ants profiler
[]: Search and download by yourself
[Protection method]: obfuscation + strong naming + RSA
[Tools]: reflector, pebrowse, snremove, ultraedit
[Operating platform]:. Net V1.1
[Author's statement]: The first time I used the broken text generator, 8 Error!
--------------------------------------------------------------------------------
[Detailed process]
The main functions of ants profiler are as follows:
"Code profile. Net Applications
"Profile application memory use
"Profile both. Net desktop applications and ASP. NET web applications
"Optimize your code
Let's go through the process.
Run the command first. A 14-day trial is displayed. Enter the serial number. If the serial number is incorrect, the prompt is please enter a valid serial number ". Use reflector to open it and try again. If you are lucky, you will find that the software obfuscation intensity is weak (only a few characters are not printable), and you will find that there is a strong name.
Two files in the directory are suspicious, Redgate. licensing. client. DLL and Redgate. licensing. helper. DLL (the two files are found. One is to view the file names in the directory, and the other is to find these two modules during debugging. See the following section ). Similarly, use reflector to load. Search for the string "valid serial", and it is easy to determine the serial number. (Dizzy, key things are not obfuscated, and sensitive strings appear in plain text. I haven't encountered such a great. Net program for a long time .)
Code:
try { string text1 = this.?.Text.ToUpper().Trim(); if (text1 == "I NEED MORE TIME") { if (this.?.?()) { this.?((?.?) 6); return; } MessageBox.Show("Your trial could not be extended", "Trial extension failure", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } this.?.SerialNumber = this.?.Text; } catch (?) { MessageBox.Show("Please enter a valid serial number", "Invalid serial number", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; }
Although many characters cannot be printed, the analysis is not affected. It can be seen from the code that the wrong serial number will throw an exception. The following is the calculation code for finding the serial number. (There is also a string "I need more time", which is extended by the trial period. It can be used without any cracking in combination with the registry. It has already been posted .)
There are two methods to compare the serial number. One is to break down the pebrowse and find the place for dynamic debugging. I used this method at the time. Here I just want to briefly talk about it. Load with pebrowse (for programs that contain non-printable characters, the source code after ildasm is often not compiled with ilasm. it is inconvenient to use windbg, or it is convenient to directly debug it ), all methods are disconnected at the corresponding DLL (because you do not know which method is used to calculate the serial number). See the suspicious DLL mentioned above in the red circle. I will not talk about it any more. You can try it yourself because the program is completely static.
Second, direct analysis in reflector. Note:
This .?. Serialnumber = this .?. Text;
Click "sericalnumber" to go to its definition
Code:
public string SerialNumber { get { return this.?; } set { value = value.Trim(); if (!Licence.?(value, this.?)) { throw new ?(); } this.? = value; } }
Set is obviously called here. The significance of the code is very obvious. If the license determines that the serial number is incorrect, throw an exception, which is caught by the catch just now. The invalid serial window is displayed. Click licence. XX (an invisible character, haha) and finally find:
Code:
private static bool ?(string text5, int num1) { text5 = text5.ToUpper().Trim(); Regex regex1 = new Regex(@"[A-Z]{2}-[0-9A-Z]{1}-[0-9A-Z]{1}-/d{5}-[0-9A-F]{4}"); Regex regex2 = new Regex(@"/d{3}-/d{3}-/d{6}-[0-9A-F]{4}"); if (regex1.IsMatch(text5)) { string text1 = text5.Substring(0, 12); string text2 = string.Format("{0:X4}", Licence.?(text1)); if (!text5.EndsWith(text2)) { return false; } } else { if (!regex2.IsMatch(text5)) { return false; } string text3 = text5.Substring(0, 14); string text4 = string.Format("{0:X4}", Licence.?(text3)); if (!text5.EndsWith(text4)) { return false; } if (Convert.ToInt32(text5.Substring(0, 3)) != num1) { return false; } } return true; }
Or a regular expression. I will not talk about it here. If you do not understand it, you can read the programming documentation. After analysis, we can see the serial number format, [A-Z] {2}-[0-9a-z] {1}-[0-9a-z] {1}-/d {5}-[0-9a-f] {4 }, in addition, the value calculated from the first 14 bits is equal to the last 4 bits. Here is an example for us to continue the analysis: AA-0-0-12345-5C3B.
After entering the serial number, you can continue and find that you still need to activate it. Otherwise, you still need to try it for 14 days. Select to activate by email (Network activation is difficult), and then let you enter the activation code. Enter "the activation response is not in the correct format ". Search for the keyword here.
Code:
private bool ?(XmlDocument document1, ref Licence.? ?Ref1) { XmlNodeList list1 = document1.GetElementsByTagName("data"); XmlNodeList list2 = document1.GetElementsByTagName("signature"); if ((list1.Count != 1) || (list2.Count != 1)) { ?Ref1.? = "The activation response is not in the correct format"; return false; } string text1 = list1[0].OuterXml; string text2 = list2[0].InnerXml; if (text2.Length != 0) { ?Ref1.? = "The activation response does not contain a digital signature"; return false; } RSACryptoServiceProvider provider1 = new RSACryptoServiceProvider(); string text3 = "<RSAKeyValue><Modulus>zLizNmLUd4VlIWee1GXgn/KxEwcghPASQ+NUzZhbY2fTGzpW64T6yEOdHlIbhX1DX6yAz2gMZKfnpQL2aFqxh5ACFV9dONSTzuQzkqeXwFEARsMxGP3eTQSWMpwVhEcraSn1zOqMb3CRDeQpgasq0lv4HRFhbwalOifKarjEL/8=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"; provider1.FromXmlString(text3); byte[] buffer1 = Convert.FromBase64String(text2); byte[] buffer2 = Encoding.UTF8.GetBytes(text1); if (provider1.VerifyData(buffer2, new SHA1Managed(), buffer1)) { ?Ref1.? = "The activation response contains an incorrect digital signature"; return false; } ?Ref1.? = false;
Dizzy, with RSA, I can't do it. I can only crack it. However, the selection of blasting scope and breaking points is very skillful. For details, see the following. After analyzing the code, it seems that the activation information is in XML format, as follows:
<Activationresponse>
<DATA>
Xxxx
</Data>
<Signature>
Yyyy
</Signature>
</Activationresponse>
And the number of characters required by yyyy must be a multiple of 4. Why? Because convert. frombase64string (text2), you can try it if you don't believe it. Follow the style input above, and a new prompt is displayed: The activation response does not match the registration properties. It seems that this is not the final verification yet.
Here is a tips for using reflector. The operation is shown in the figure below: first, we will analyze which methods are used by this method and what other methods are used.
Here we look for the used relationship, and click go to member to come to the following code. Here is the key.
Code:
private bool ?(XmlDocument document1) { Licence.? ?1 = new Licence.?(); if (!this.?(document1, ref ?1)) { throw new ?(?1.?); } if (((?1.? != this.?) || (?1.? != this.?)) || (?1.? != this.?)) { throw new ?("The activation response does not match the registration properties"); } if (!?1.?) { if (?1.? != this.?) { throw new ?("The activation response does not match the registration properties"); } if (Licence.?(?1.?, this.?)) { this.? = true; return true; } throw new ?("The activation response is for a different machine"); } if (?1.? != this.?) { throw new ?("The activation response is for a different session"); } this.?(true); return false; }
We want to crack it here, but how can we crack it? Note that there is only one correct return point in this section of code, that is
This .? = True;
Return true;
Our method is to make the first statement licence .? ? 1 = new licence .? (); After execution, the above two statements of code are executed without any judgment. By the way, the previous one is that the provider1.verifydata at the RSA judgment must also be modified so that the following information can be obtained.
The modification method is located in ultraedit in combination with the ildasm disassembly code.
Article 1:
Il_00a4:/* 2D | 0e */brtrue. s il_00b4
Change 2D to 2C (brfalse. s ). The physical offset is at 0x3118h.
Second:
Il_0000:/* 73 | (06) Running 3B */newobj instance void Redgate. Licensing. Client. Licence/* 02000008 *//'? '/* 02000009 */:. ctor ()/* 0600003b */
Il_0005:/* 0a | */stloc.0
At 0x2cb4 of the physical offset. Then modify these two statements. The original file is
00002 cbah: 02 03 12 00 28 29 00 00 ;....()..
Change
00002 cbah: 02 17 7d 38 00 00 04 17;...} 8 ....
Msil code
Ldarg.0
LDC. i4.1
Stfld bool Redgate. Licensing. Client. Licence ::'? '
RET
Save changes and run. Enter the registration code and activation information according to the format, and the activation is successful. No time is displayed. The serial number generator will not be written. It is a simple algorithm. I don't know when to fix RSA.
The attachment contains the patched Redgate. Licensing. Client. DLL for your reference only!