Exemplo n.º 1
0
        private static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += UnhandledException;
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            Settings = LoadSettings();
            if (args.Length > 0 && args[0].EndsWith(".swf"))
            {
                var clientInfo = new FileInfo(Path.GetFullPath(args[0]));
                using (var game = new HGame(clientInfo.FullName))
                {
                    game.Disassemble();
                    game.DisableHostChecks();
                    game.InjectKeyShouter(4001);
                    game.InjectEndPointShouter(4000);
                    game.InjectEndPoint("127.0.0.1", (int)Settings["ConnectionListenPort"]);

                    string moddedClientPath = Path.Combine(clientInfo.DirectoryName, "MOD_" + clientInfo.Name);
                    using (var fileOutput = File.Open(moddedClientPath, FileMode.Create))
                        using (var output = new FlashWriter(fileOutput))
                        {
                            game.Assemble(output, CompressionKind.ZLIB);
                        }
                    MessageBox.Show($"File has been modified/re-assembled successfully at '{moddedClientPath}'.", "Tanji - Alert!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                }
                return;
            }

            Eavesdropper.Certifier = new CertificateManager("Tanji", "Tanji Certificate Authority");
            Eavesdropper.Overrides.AddRange(((string)Settings["ProxyOverrides"]).Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));

            Application.Run(new MainFrm());
        }
Exemplo n.º 2
0
 public static Task <HGame> GetGameAsync(string revision)
 {
     return(ReadContentAsync(HHotel.Com.ToUri("images"), $"/gordon/{revision}/Habbo.swf", async content =>
     {
         var game = new HGame(await content.ReadAsStreamAsync().ConfigureAwait(false));
         game.Disassemble();
         return game;
     }));
 }
        private Task InjectGameClientAsync(object sender, RequestInterceptedEventArgs e)
        {
            if (!e.Uri.Query.StartsWith("?" + _randomQuery))
            {
                return(Task.CompletedTask);
            }

            Eavesdropper.RequestInterceptedAsync -= InjectGameClientAsync;

            Uri remoteUrl = e.Request.RequestUri;

            string clientPath = Path.Combine(Master.DataDirectory.FullName,
                                             $@"Modified Clients\{remoteUrl.Host}\{remoteUrl.LocalPath}");

            if (!File.Exists(clientPath))
            {
                _ui.SetStatusMessage(Constants.INTERCEPTING_CLIENT);
                Eavesdropper.ResponseInterceptedAsync += InterceptGameClientAsync;
            }
            else
            {
                _ui.SetStatusMessage(Constants.DISASSEMBLING_CLIENT);
                using var game = new HGame(clientPath);
                game.Disassemble();

                _ui.SetStatusMessage(Constants.GENERATING_MESSAGE_HASHES);
                game.GenerateMessageHashes(Path.Combine(Master.ProgramDirectory.FullName, "Hashes.ini"));

                //We don't need this stuff in HabboGallery
                foreach (HMessage message in game.Out.Concat(game.In))
                {
                    message.Class     = null;
                    message.Parser    = null;
                    message.Structure = null;
                    message.References.Clear();
                }

                Master.In  = game.In;
                Master.Out = game.Out;

                Task interceptConnectionTask = InterceptConnectionAsync();

                e.Request = WebRequest.Create(new Uri(clientPath));
                TerminateProxy();
            }

            return(Task.CompletedTask);
        }
Exemplo n.º 4
0
        private static void PatchClient(FileInfo clientInfo)
        {
            using (var game = new HGame(clientInfo.FullName))
            {
                game.Disassemble();
                game.DisableHostChecks();
                game.InjectKeyShouter(4001);
                game.InjectEndPointShouter(4000);
                game.InjectEndPoint("127.0.0.1", (int)Settings["ConnectionListenPort"]);

                string moddedClientPath = Path.Combine(clientInfo.DirectoryName, "MOD_" + clientInfo.Name);
                using (var fileOutput = File.Open(moddedClientPath, FileMode.Create))
                    using (var output = new FlashWriter(fileOutput))
                    {
                        game.Assemble(output, CompressionKind.ZLIB);
                    }
                MessageBox.Show($"File has been modified/re-assembled successfully at '{moddedClientPath}'.", "Tanji - Alert!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
            }
        }
Exemplo n.º 5
0
        private async Task ReceiveRemoteContractorDataAsync()
        {
            try
            {
                HMessage packet = await _remoteContractor.ReceivePacketAsync().ConfigureAwait(false);

                if (packet == null)
                {
                    Environment.Exit(0);
                }
                #region Switch: packet.Header
                switch (packet.Header)
                {
                case 0:
                {
                    _initStep++;
                    _hotel = (HHotel)packet.ReadShort();
                    break;
                }

                case 1:
                {
                    _initStep++;
                    _in  = new Incoming();
                    _out = new Outgoing();

                    string location = packet.ReadString();
                    if (!string.IsNullOrWhiteSpace(location))
                    {
                        _game = new HGame(location);
                        _game.Disassemble();

                        _game.GenerateMessageHashes();
                        if (packet.Readable > 0)
                        {
                            string hashesPath = packet.ReadString();
                            _in.Load(_game, hashesPath);
                            _out.Load(_game, hashesPath);
                        }
                        _module.ModifyGame(_game);
                    }
                    break;
                }

                case 2:
                {
                    _initStep++;
                    _gameData = new HGameData(packet.ReadString());
                    _module.ModifyGameData(_gameData);
                    break;
                }

                case 3:
                {
                    _initStep++;
                    var connection = (ContractorProxy)_connection;
                    connection.Port    = packet.ReadShort();
                    connection.Host    = packet.ReadString();
                    connection.Address = packet.ReadString();
                    break;
                }

                case 4:
                case 5:
                {
                    var destination = (HDestination)(packet.Header - 4);

                    string stamp       = packet.ReadString();
                    int    step        = packet.ReadInteger();
                    bool   isBlocked   = packet.ReadBoolean();
                    int    dataLength  = packet.ReadInteger();
                    byte[] data        = packet.ReadBytes(dataLength);
                    var    interPacket = new HMessage(data, destination);

                    var args = new DataInterceptedEventArgs(interPacket, step, (destination == HDestination.Server));
                    try
                    {
                        if (destination == HDestination.Server)
                        {
                            _module.HandleOutgoing(args);
                        }
                        else
                        {
                            _module.HandleIncoming(args);
                        }
                    }
                    finally
                    {
                        await SendInterceptedDataResponseAsync(
                            stamp, args).ConfigureAwait(false);
                    }
                    break;
                }
                }
                #endregion

                if (_initStep == 4)
                {
                    _initializationSource?.SetResult(true);
                }
            }
            finally
            {
                Task receiveRemContDataTask = ReceiveRemoteContractorDataAsync();
            }
        }
Exemplo n.º 6
0
        private void Compare(string[] args)
        {
            using (var game_1 = new HGame(args[0]))
                using (var game_2 = new HGame(args[1]))
                {
                    game_1.Disassemble();
                    game_2.Disassemble();

                    var matchedHashes    = new List <string>();
                    var oldUnmatched     = new Dictionary <string, List <ASMethod> >();
                    var unmatchedMethods = new Dictionary <string, List <ASMethod> >();
                    foreach (ASMethod method in game_1.ABCFiles[0].Methods)
                    {
                        using (var hasher = new HashWriter(false))
                        {
                            hasher.Write(method);
                            string hash = hasher.GenerateMD5Hash();

                            List <ASMethod> methods = null;
                            if (!unmatchedMethods.TryGetValue(hash, out methods))
                            {
                                methods = new List <ASMethod>();
                                unmatchedMethods.Add(hash, methods);
                            }
                            methods.Add(method);
                        }
                    }

                    foreach (ASMethod method in game_2.ABCFiles[0].Methods)
                    {
                        using (var hasher = new HashWriter(false))
                        {
                            hasher.Write(method);
                            string hash = hasher.GenerateMD5Hash();

                            if (unmatchedMethods.ContainsKey(hash))
                            {
                                matchedHashes.Add(hash);
                                unmatchedMethods.Remove(hash);
                            }
                            else if (!matchedHashes.Contains(hash))
                            {
                                List <ASMethod> methods = null;
                                if (!oldUnmatched.TryGetValue(hash, out methods))
                                {
                                    methods = new List <ASMethod>();
                                    oldUnmatched.Add(hash, methods);
                                }
                                methods.Add(method);
                            }
                        }
                    }

                    var changes = string.Empty;
                    foreach (string hash in unmatchedMethods.Keys)
                    {
                        changes += $"[{hash}]\r\n{{\r\n";
                        foreach (ASMethod method in unmatchedMethods[hash])
                        {
                            changes += $"    {(method.Container?.QName.Name ?? "Anonymous")}\r\n";
                            changes += $"    {method.ToAS3()}\r\n\r\n";
                        }
                        changes += $"}}\r\n";
                    }
                }
        }
Exemplo n.º 7
0
        private void Extract()
        {
            if (Options.DumpInfo != null || Options.MatchInfo != null)
            {
                Console.Write("Generating Message Hashes...");
                Game.GenerateMessageHashes();
                ConsoleEx.WriteLineFinished();

                string hashesPath = (_baseDirectory + "Hashes.ini");
                In.Load(Game, hashesPath);
                Out.Load(Game, hashesPath);
            }

            if (Options.DumpInfo != null)
            {
                string msgsPath = Path.Combine(Options.OutputDirectory, "Messages.txt");
                using (var msgsOutput = new StreamWriter(msgsPath, false))
                {
                    msgsOutput.WriteLine("// " + Game.Revision);
                    msgsOutput.WriteLine();

                    msgsOutput.WriteLine("// Outgoing Messages | " + Game.OutMessages.Count.ToString("n0"));
                    WriteMessages(msgsOutput, "Outgoing", Game.OutMessages);

                    msgsOutput.WriteLine();

                    msgsOutput.WriteLine("// Incoming Messages | " + Game.InMessages.Count.ToString("n0"));
                    WriteMessages(msgsOutput, "Incoming", Game.InMessages);

                    Console.WriteLine("Messages Saved: " + msgsPath);
                }

                string identitiesPath = Path.Combine(Options.OutputDirectory, "Identities.ini");
                using (var output = new StreamWriter(identitiesPath))
                {
                    output.WriteLine(Game.Revision);
                    Out.Save(output);
                    output.WriteLine();
                    In.Save(output);
                }

                if (Options.DumpInfo.IsDumpingImages)
                {
                    var imgDirectory = Directory.CreateDirectory(Options.OutputDirectory + "\\ImageFiles");
                    foreach (DefineBitsLossless2Tag bitsTag in Game.Tags
                             .Where(t => t.Kind == TagKind.DefineBitsLossless2))
                    {
                        string imgPath = Path.Combine(imgDirectory.FullName, "img_" + bitsTag.Id + ".png");
                        Color[,] table = bitsTag.GetARGBMap();

                        int width  = table.GetLength(0);
                        int height = table.GetLength(1);
                        using (var asset = new Image <Rgba32>(width, height))
                        {
                            for (int y = 0; y < height; y++)
                            {
                                for (int x = 0; x < width; x++)
                                {
                                    Color pixel = table[x, y];
                                    asset[x, y] = new Rgba32(pixel.R, pixel.G, pixel.B, pixel.A);
                                }
                            }
                            using (var output = new StreamWriter(imgPath))
                            {
                                asset.SaveAsPng(output.BaseStream);
                            }
                        }
                    }
                }
                if (Options.DumpInfo.IsDumpingBinaryData)
                {
                    var binDirectory = Directory.CreateDirectory(Options.OutputDirectory + "\\BinaryDataFiles");
                    foreach (DefineBinaryDataTag binTag in Game.Tags
                             .Where(t => t.Kind == TagKind.DefineBinaryData))
                    {
                        string binPath = Path.Combine(binDirectory.FullName, "bin_" + binTag.Id + ".xml");
                        if (Options.DumpInfo.IsMergingBinaryData)
                        {
                            using (var binOutput = File.Open(Options.OutputDirectory + "\\binaryData.xml", FileMode.Append, FileAccess.Write))
                            {
                                binOutput.Write(binTag.Data, 0, binTag.Data.Length);
                            }
                        }
                        else
                        {
                            File.WriteAllBytes(binPath, binTag.Data);
                        }
                    }
                }

                if (Options.MatchInfo != null)
                {
                    MatchCommand matchInfo = Options.MatchInfo;
                    using (var previousGame = new HGame(matchInfo.PreviousGameInfo.FullName))
                    {
                        Console.Write("Preparing Hash Comparison...");
                        previousGame.Disassemble();
                        previousGame.GenerateMessageHashes();
                        ConsoleEx.WriteLineFinished();

                        Console.Write("Matching Outgoing Messages...");
                        ReplaceHeaders(matchInfo.ClientHeadersInfo, previousGame.OutMessages, previousGame.Revision);
                        ConsoleEx.WriteLineFinished();

                        Console.Write("Matching Incoming Messages...");
                        ReplaceHeaders(matchInfo.ServerHeadersInfo, previousGame.InMessages, previousGame.Revision);
                        ConsoleEx.WriteLineFinished();
                    }
                }
            }
        }
Exemplo n.º 8
0
        static async Task GenerateResults(string[] args)
        {
            var hotels = new string[] { ".com", ".fr", ".com.tr", ".nl", ".de", ".it", ".fi", ".es", ".com.br" };
            var files  = new List <string>();

            files = args.ToList();

            var incomingHashesWithNames = LoadHashesWithName("Incoming");
            var outgoingHashesWithNames = LoadHashesWithName("Outgoing");

            foreach (var file in files)
            {
                var swfBytes = await File.ReadAllBytesAsync(file);

                Console.WriteLine($"[Updater] Fetched {file}, Size: {swfBytes.Length / 1024}mb");
                var game = new HGame(swfBytes);
                Console.WriteLine($"[Updater] Disassembling SWF");
                game.Disassemble();
                game.GenerateMessageHashes();
                Console.WriteLine($"[Updater] Incoming messages: {game.In.Count}");
                Console.WriteLine($"[Updater] Outgoing messages: {game.Out.Count}");

                var revisionInfo = new RevisionInfo()
                {
                    Tag = game.Revision, FirstSeen = DateTime.UtcNow
                };

                foreach (var message in game.In)
                {
                    string name = null;
                    if (incomingHashesWithNames.ContainsKey(message.Hash))
                    {
                        name = incomingHashesWithNames[message.Hash];
                    }

                    revisionInfo.IncomingMessages.Add(message.Id, new MessageInfo()
                    {
                        Hash = message.Hash, Name = name, Structure = message.Structure, ClassName = message.ClassName, ClassNamespace = message.Class.QName.Namespace.Name, References = message.References.Count, ParserName = message.ParserName, ParserNamespace = message.Parser.QName.Namespace.Name
                    });
                }

                foreach (var message in game.Out)
                {
                    string name = null;
                    if (outgoingHashesWithNames.ContainsKey(message.Hash))
                    {
                        name = outgoingHashesWithNames[message.Hash];
                    }

                    revisionInfo.OutgoingMessages.Add(message.Id, new MessageInfo()
                    {
                        Hash = message.Hash, Name = name, Structure = message.Structure, ClassName = message.ClassName, ClassNamespace = message.Class.QName.Namespace.Name, References = message.References.Count
                    });
                }

                revisionInfo.IncomingMessages.ToList().ForEach(x => insertSQL(game.Revision, "In", x.Key, x.Value));
                revisionInfo.OutgoingMessages.ToList().ForEach(x => insertSQL(game.Revision, "Out", x.Key, x.Value));

                string json = JsonConvert.SerializeObject(revisionInfo);
                File.WriteAllText($"{basedir}/revisions/{game.Revision}.json", json);
            }
        }
        private async Task InterceptGameClientAsync(object sender, ResponseInterceptedEventArgs e)
        {
            if (e.ContentType != "application/x-shockwave-flash")
            {
                return;
            }
            if (!e.Uri.Query.StartsWith("?" + _randomQuery))
            {
                return;
            }
            Eavesdropper.ResponseInterceptedAsync -= InterceptGameClientAsync;

            string clientPath      = Path.Combine(Master.DataDirectory.FullName, $@"Modified Clients\{e.Uri.Host}\{e.Uri.LocalPath}");;
            string clientDirectory = Path.GetDirectoryName(clientPath);

            Directory.CreateDirectory(clientDirectory);

            _ui.SetStatusMessage(Constants.DISASSEMBLING_CLIENT);
            using var game = new HGame(await e.Content.ReadAsStreamAsync().ConfigureAwait(false))
                  {
                      Location = clientPath
                  };

            game.Disassemble();

            _ui.SetStatusMessage(Constants.GENERATING_MESSAGE_HASHES);
            game.GenerateMessageHashes(Path.Combine(Master.ProgramDirectory.FullName, "Hashes.ini"));

            //We don't need this stuff in HabboGallery
            foreach (HMessage message in game.Out.Concat(game.In))
            {
                message.Class     = null;
                message.Parser    = null;
                message.Structure = null;
                message.References.Clear();
            }

            Master.In  = game.In;
            Master.Out = game.Out;

            _ui.SetStatusMessage(Constants.MODIFYING_CLIENT);
            game.DisableHostChecks();
            game.InjectKeyShouter(4001);
            game.InjectEndPointShouter(4000);
            game.InjectEndPoint("127.0.0.1", Connection.ListenPort);

            CompressionKind compression = CompressionKind.ZLIB;

#if DEBUG
            compression = CompressionKind.None;
#endif

            _ui.SetStatusMessage(Constants.ASSEMBLING_CLIENT);
            byte[] payload = game.ToArray(compression);
            e.Headers[HttpResponseHeader.ContentLength] = payload.Length.ToString();

            e.Content = new ByteArrayContent(payload);
            using (FileStream clientStream = File.Open(clientPath, FileMode.Create, FileAccess.Write))
            {
                clientStream.Write(payload);
            }

            TerminateProxy();
            Task interceptConnectionTask = InterceptConnectionAsync();
        }
Exemplo n.º 10
0
        static async Task GenerateResults()
        {
            var hotels    = new string[] { ".com", ".fr", ".com.tr", ".nl", ".de", ".it", ".fi", ".es", ".com.br" };
            var revisions = new List <string>();

            Console.WriteLine($"[Updater] Checking revisions for hotels: [{string.Join(", ", hotels)}]");

            var history = new List <HistoryInfo>();

            foreach (var hotel in hotels)
            {
                var variables = await GetVariablesAsync(hotel);

                var client_url = GetClientUrl(variables);
                var revision   = new Regex("(PRODUCTION\\-\\d+\\-\\d+)").Match(client_url).Groups[1].Value;
                Console.WriteLine($"[Updater] Habbo{hotel} : {revision}");

                if (!revisions.Contains(revision))
                {
                    revisions.Add(revision);
                }

                history.Add(new HistoryInfo()
                {
                    Hotel = hotel, Revision = revision, LastChecked = DateTime.UtcNow
                });
            }

            File.WriteAllText("/var/www/sites/api.harble.net/last.json", JsonConvert.SerializeObject(history));

            var incomingHashesWithNames = LoadHashesWithName("Incoming");
            var outgoingHashesWithNames = LoadHashesWithName("Outgoing");

            foreach (var revision in revisions)
            {
                if (File.Exists($"/var/www/sites/api.harble.net/revisions/{revision}.json"))
                {
                    Console.WriteLine($"[Updater] Already fetched {revision}");
                    continue;
                }

                var swfBytes = await GetClientSwfAsync(revision);

                Console.WriteLine($"[Updater] Fetched {revision}, Size: {swfBytes.Length / 1024}mb");
                var game = new HGame(swfBytes);
                Console.WriteLine($"[Updater] Disassembling SWF");
                game.Disassemble();
                game.GenerateMessageHashes();
                Console.WriteLine($"[Updater] Incoming messages: {game.InMessages.Count}");
                Console.WriteLine($"[Updater] Outgoing messages: {game.OutMessages.Count}");

                var revisionInfo = new RevisionInfo()
                {
                    Tag = revision, FirstSeen = DateTime.UtcNow
                };

                foreach (var message in game.InMessages)
                {
                    string name = null;
                    if (incomingHashesWithNames.ContainsKey(message.Value.Hash))
                    {
                        name = incomingHashesWithNames[message.Value.Hash];
                    }

                    revisionInfo.IncomingMessages.Add(message.Key, new MessageInfo()
                    {
                        Hash = message.Value.Hash, Name = name
                    });
                }

                foreach (var message in game.OutMessages)
                {
                    string name = null;
                    if (outgoingHashesWithNames.ContainsKey(message.Value.Hash))
                    {
                        name = outgoingHashesWithNames[message.Value.Hash];
                    }

                    revisionInfo.OutgoingMessages.Add(message.Key, new MessageInfo()
                    {
                        Hash = message.Value.Hash, Name = name
                    });
                }

                string json = JsonConvert.SerializeObject(revisionInfo);
                File.WriteAllText($"/var/www/sites/api.harble.net/revisions/{revision}.json", json);
            }
        }