![]() |
![]() |
![]() |
![]() |
![]() |
||||||||||
|
||||||||||||||
![]() |
#1
|
|||
|
|||
![]() I am attempting to crack an application protected with the newest version of {smartassembly} (3.2). I found a function which can decrypt the resources here: http://forum.tuts4you.com/index.php?showtopic=18498.
The first step I did when trying to crack was use {smartkill} and {smartassasin} which both did not work. They do not support the newest smart assembly. After that I removed the fake meta header that way I could open the application in reflector. Now, where I am stuck is attempting to remove the strong name. Every single program I use breaks the application when removing the strong name. I am told {smartassembly} uses the strong name in the string encryption so that way I must decrypt all the strings before I remove the strong name. That is where I am stuck. Any help would be appreciated. Copy of the exe, both the original one and the one patched without the fake meta header: http://rapidshare.com/files/19861594...iveLBI_1.0.rar |
#2
|
|||
|
|||
![]() @Slashmolder:
1. I have removed strong name in your file to make it work with my DeSmart. 2. I have deobfuscate your files http://www.megaupload.com/de/?d=NQG76P1R . However the string is still encrypted. 3. If someone has time and would like to help me improve my DeSmart. Then use the target above to rip the decrypted function. I get lost when rip this function. It relates to a lot of another classes. ![]()
__________________
My site: http://rongchaua.net |
#3
|
|||
|
|||
![]() Sorry to say it still breaks the exe because the strings aren't decrypted. I need to decrypt the strings before I remove the strong name because in {SA} the encrypted strings use the strong name to decrypt the strings.
|
#4
|
|||
|
|||
![]() I was working with a few protected apps myself, and the strings are the easy part.
If you disassemble a program that has been deobfuscated with DeSmart, look through the resources. One resource has a bunch of hex (in mine it's the 3rd resource). This is your strings database. Each string is base64-encoded. Before each string, there is also a byte that determines the length of the string. If the situation requires, more than that one byte will be used for the string length. If you wish to find a specific string that's referenced, I use this simple formula for finding the entry_point: DB_Entry = Given_Offset - Common_Offset The way I found the common offset was I took a string that I KNEW what it was supposed to be and plugged them in to find the Common_Offset, however there does appear to be some other way to do this as referenced by the function for making the calls. Here is the actual function used across all SmartAssembly-protected applications for strings: Code:
public static unsafe string Method_0(int num1) { byte[] buffer; Assembly assembly; byte[] buffer2; int num; int num2; int num3; int num4; byte[] buffer3; Type type; Guid guid; Monitor.Enter(type = typeof(Class_4_Object)); Label_0012: try { if (Field_0 != null) { goto Label_00A0; } assembly = Assembly.GetExecutingAssembly(); Field_0 = assembly.GetManifestResourceStream(&assembly.ManifestModule.ModuleVersionId.ToString("B")); buffer2 = assembly.GetName().GetPublicKeyToken(); if (buffer2 == null) { goto Label_0079; } num = 0; Label_0057: Field_1 ^= (buffer2[num] << 8) + buffer2[num + 1]; num += 2; if (num < (((int) buffer2.Length) - 1)) { goto Label_0057; } Label_0079: num2 = ((MethodBase.GetCurrentMethod().MetadataToken & 0xffffff) - 1) % 0xffff; Field_1 ^= num2; Label_00A0: Field_0.Position = (long) (num1 - Field_1); num3 = Field_0.ReadByte(); num4 = 0; if ((num3 & 0x80) != null) { goto Label_00CF; } num4 = num3; Label_00CF: if ((num3 & 0x40) != null) { goto Label_00EC; } num4 = ((num3 & 0x3f) << 8) + Field_0.ReadByte(); goto Label_011C; Label_00EC: num4 = ((((num3 & 0x1f) << 0x18) + (Field_0.ReadByte() << 0x10)) + (Field_0.ReadByte() << 8)) + Field_0.ReadByte(); Label_011C: buffer = new byte[num4]; Field_0.Read(buffer, 0, num4); goto Label_013D; } finally { Label_0135: Monitor.Exit(type); } Label_013D: if (((int) buffer.Length) != null) { goto Label_0148; } return string.Empty; Label_0148: buffer3 = Convert.FromBase64String(Encoding.UTF8.GetString(buffer, 0, (int) buffer.Length)); return string.Intern(Encoding.UTF8.GetString(buffer3, 0, (int) buffer3.Length)); } |
#5
|
|||
|
|||
![]() hello
i'm need help with encrypted strings saved res here: http://aftalik.firstvds.ru/ps/ps.bin this res from PocketShield (.NET CF + smartassembly v2.0.50727) look like strings are decrypting with this code: Code:
internal sealed class Class_14 { // Fields private static byte[] Field_00; private static int Field_01; // Methods static Class_14() { Assembly executingAssembly = Assembly.GetExecutingAssembly(); using (Stream stream = executingAssembly.GetManifestResourceStream("{a38ee919-3e39-4e8a-85ef-b57391248334}")) { int count = Convert.ToInt32(stream.Length); byte[] buffer = new byte[count]; stream.Read(buffer, 0, count); Field_00 = Class_00.Method_00(buffer); buffer = null; stream.Close(); } Field_01 = 0; byte[] publicKeyToken = executingAssembly.GetName().GetPublicKeyToken(); if (publicKeyToken != null) { int index = 0; do { Field_01 ^= (publicKeyToken[index] << 8) + publicKeyToken[index + 1]; index += 2; } while (index < (publicKeyToken.Length - 1)); } } public static string Method_00(int num1) { int count = 0; int index = num1 - Field_01; int num3 = Field_00[index++]; if ((num3 & 0x80) == 0) { count = num3; if (count == 0) { return string.Empty; } } else { if ((num3 & 0x40) == 0) { count = ((num3 & 0x3f) << 8) + Field_00[index++]; } count = ((((num3 & 0x1f) << 0x18) + (Field_00[index++] << 0x10)) + (Field_00[index++] << 8)) + Field_00[index++]; } try { byte[] bytes = Convert.FromBase64String(Encoding.UTF8.GetString(Field_00, index, count)); return string.Intern(Encoding.UTF8.GetString(bytes, 0, bytes.Length)); } catch { return null; } } } after desmart: http://aftalik.firstvds.ru/ps/ps_after_desmart.exe |