// RSA system by Mike (Dom, s-o-m), don't work on lasts releases :( /** * * Habbo RSA SWF Crack -- http://script-o-matic.net * Author: Mike Graham * * This was my little trick for patching up the RSA on-the-fly to make crypto work with old implementation. * (With the addition to Sulake encrypting the clientkey with RSA, it makes crypto impossible unless you can get the plaintext version). * * The searching for op-codes isn't the fastest of methods (it can take quite some time)... [See FindAll() method] * It essentially works by finding the entrypoint, null'ing some bytes out to preserve SWF structure (hail the NOP op-code) and length, * and injecting a simple GETLOCAL op-code and a PUSHSCOPE. this means instead of the RSA function returning a crypted key, it returns the plaintext * version of the key which is then sent by the SocketHandler class inside the client... (getlocal 0x01 = the plaintext key passed to the function) * * Required: The SharpZipLib (DEFLATE compression algorithm) **/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; using System.Text.RegularExpressions; using System.Windows.Forms; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; using ICSharpCode.SharpZipLib.Zip.Compression; using System.Threading; namespace Lemon { public class HabboRSACrack { private static int entryPoint = 0; private static int injectPoint = 0; private static byte[] buffer; public static void CrackSWF() { WebClient wc = new WebClient(); wc.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(swfDownloaded); wc.DownloadFileAsync(new Uri("http://habbo.hs.llnwd.net/gordon/RELEASE63-201110171102-827251604/Habbo.swf"), @"C:\xampp\htdocs\SWF\Habbo.swf"); } private static void decompressSWF() { //LemonEnvironment.mainWindow._LoginEvents("decompressing with inflator...", -100); BinaryReader br = new BinaryReader(File.Open(@"C:\xampp\htdocs\SWF\Habbo.swf", FileMode.Open, FileAccess.Read), Encoding.UTF8); br.BaseStream.Position = 4; // Skip CWS and flashver int size = Convert.ToInt32(br.ReadUInt32()); // 4bytes = uint of size when decompressed byte[] uncompressed = new byte[size]; // Sig, flashver and size are uncompressed br.BaseStream.Position = 0; // Reset stream to beginning after reading size br.Read(uncompressed, 0, 8); // Read the un-compressed bytes to preserve them for re-writing byte[] compressed = br.ReadBytes(size); // Read all the compressed bytes Inflater zipInflator = new Inflater(); // Our inflater (think of it like un-compressing) zipInflator.SetInput(compressed); // Set out input bytearray as our compressed bytes as read above zipInflator.Inflate(uncompressed, 8, size - 8); // Inflate with an offset of 8 (first 8bytes aren't compressed!) zipInflator = null; // kill our inflater instance to free-up some resources br.Close(); // Close our stream buffer = uncompressed; // Copy our uncompressed buffer to main buffer //LemonEnvironment.mainWindow._LoginEvents("copying decompressed bytes...", -100); } private static void swfDownloaded(object sender, System.ComponentModel.AsyncCompletedEventArgs e) { int pos = 0; // We need to decompress this SWF :( Habbo.SWF is always compressed. decompressSWF(); //LemonEnvironment.mainWindow._LoginEvents("searching for entrypoint...", -100); var stream = new FileStream(@"C:\xampp\htdocs\SWF\Habbo.swf", FileMode.Open, FileAccess.Write); //0x63 0x04 0x62 0x04 0xd2 0xd3 0xd2 byte[] toFind = { 99, 04, 98, 04, 210, 211, 210 }; // tomodify - latest = 0xD0, 0x60, 0xE1, foreach (int i in FindAll(buffer, toFind)) { entryPoint = i; // Found our hack entrypoint break; } // LemonEnvironment.mainWindow._LoginEvents("found hax entrypoint...", -100); for (int i = entryPoint; i < buffer.Length; i++) { // next opcode to hax is pushscope (d0) (0x208) if (buffer[i] == 208) { injectPoint = i; // Found our inject point to start writing NOP opcodes and own opcodes break; } } // LemonEnvironment.mainWindow._LoginEvents("injecting hax...", -100); for (int i = injectPoint; i < buffer.Length; i++) { if (buffer[i] == 104) { pos = i - 2; break; } buffer[i] = 2; // Write NOP to keep length same } // LemonEnvironment.mainWindow._LoginEvents("wrote 0x02 at " + injectPoint.ToString() + " to " + (injectPoint + 7).ToString(), -100); buffer[pos] = 208; // pushscope (0x208) buffer[pos + 1] = 209; // getlocal1 (0x209) stream.Position = 8; // Set our stream to preserve the header again. DeflaterOutputStream deflator = new DeflaterOutputStream(stream); // Need to re-compress as our header says SWF is compressed still deflator.Write(buffer, 8, buffer.Length - 8); // Write compressed bytes to our buffer again (missing first 8bytes) deflator.Close(); stream.Close(); Thread.SpinWait(1); // huston, we are cracked... lets go. shitbrix sulake. //LemonEnvironment.mainWindow._LoginEvents("launching habbo...", 7); } private static IEnumerable FindAll(byte[] haystack, byte[] needle) { Encoding latin1 = Encoding.GetEncoding("iso-8859-1"); string sHaystack = latin1.GetString(haystack); string sNeedle = latin1.GetString(needle); for (Match m = Regex.Match(sHaystack, Regex.Escape(sNeedle)); m.Success; m = m.NextMatch()) { yield return m.Index; } } } }