示例#1
0
        private void ReplaceResources(object sender, ResponseInterceptedEventArgs e)
        {
            string absoluteUri = e.Response.ResponseUri.AbsoluteUri;

            if (ResourceReplacements.ContainsKey(absoluteUri))
            {
                var    httpResponse   = (HttpWebResponse)e.Response;
                string replacementUrl = ResourceReplacements[absoluteUri];

                if (httpResponse.StatusCode == HttpStatusCode.TemporaryRedirect)
                {
                    ResourceReplacements.Remove(absoluteUri);
                    absoluteUri = httpResponse.Headers[HttpResponseHeader.Location];
                    ResourceReplacements[absoluteUri] = replacementUrl;
                    return;
                }

                if (replacementUrl.StartsWith("http"))
                {
                    using (var webClient = new WebClient())
                        e.Payload = webClient.DownloadData(replacementUrl);
                }
                else
                {
                    e.Payload = File.ReadAllBytes(replacementUrl);
                }

                ResourceReplacements.Remove(absoluteUri);
                if (ResourceReplacements.Count < 1)
                {
                    Halt();
                    SetStatus(TanjiState.StandingBy);
                }
            }
        }
        private async Task InterceptClientPageAsync(object sender, ResponseInterceptedEventArgs e)
        {
            if (e.Content == null)
            {
                return;
            }

            string contentType = e.ContentType.ToLower();

            if (!contentType.Contains("text") && !contentType.Contains("javascript"))
            {
                return;
            }

            string body = await e.Content.ReadAsStringAsync().ConfigureAwait(false);

            if (!body.Contains("info.host") && !body.Contains("info.port"))
            {
                return;
            }

            Eavesdropper.ResponseInterceptedAsync -= InterceptClientPageAsync;
            Master.GameData.Source = body;

            body      = body.Replace(".swf", $".swf?{_randomQuery = Guid.NewGuid()}");
            e.Content = new StringContent(body);

            _ui.SetStatusMessage(Constants.INJECTING_CLIENT);
            Eavesdropper.RequestInterceptedAsync += InjectGameClientAsync;
        }
示例#3
0
        private void ReplaceClient(object sender, ResponseInterceptedEventArgs e)
        {
            if (e.Response.ContentType != "application/x-shockwave-flash" &&
                !File.Exists(e.Response.ResponseUri.LocalPath))
            {
                return;
            }

            Eavesdropper.ResponseIntercepted -= ReplaceClient;
            ushort infoPort = ushort.Parse(UI.GameData.InfoPort.Split(',')[0]);

            if (UI.Game == null)
            {
                VerifyGameClientAsync(e.Payload).Wait();
                SetState(TanjiState.ModifyingClient);

                UI.Game.BypassOriginCheck();
                UI.Game.BypassRemoteHostCheck();
                UI.Game.ReplaceRSAKeys(HandshakeManager.FAKE_EXPONENT, HandshakeManager.FAKE_MODULUS);
                UI.ModulesPg.ModifyGame(UI.Game);

                SetState(TanjiState.AssemblingClient);
                UI.Game.Assemble();

                SetState(TanjiState.CompressingClient);
                e.Payload = UI.Game.Compress();

                string clientPath = Path.Combine(
                    _modifiedClientsDir.FullName, UI.Game.GetClientRevision());

                Directory.CreateDirectory(clientPath);
                File.WriteAllBytes(clientPath + "\\Habbo.swf", e.Payload);
            }
            else
            {
                if (UI.ModulesPg.ModifyGame(UI.Game))
                {
                    UI.Game.Assemble();
                }

                e.Payload = UI.Game.ToByteArray();
            }

            if (ResourceReplacements.Count > 0)
            {
                Eavesdropper.ResponseIntercepted += ReplaceResources;
            }
            else
            {
                Halt();
            }

            SetState(TanjiState.InterceptingConnection);
            UI.Connection.ConnectAsync(UI.GameData.InfoHost,
                                       infoPort).ContinueWith(ConnectTaskCompleted);
        }
示例#4
0
        private void ReplaceClient(object sender, ResponseInterceptedEventArgs e)
        {
            if (e.Response.ContentType != "application/x-shockwave-flash" &&
                !File.Exists(e.Response.ResponseUri.LocalPath))
            {
                return;
            }

            Eavesdropper.ResponseIntercepted -= ReplaceClient;
            ushort infoPort = ushort.Parse(Master.GameData.InfoPort.Split(',')[0]);

            if (Master.Game == null)
            {
                VerifyGameClientAsync(e.Payload).Wait();
                State = MODIFYING_CLIENT;

                Master.Game.BypassOriginCheck();
                Master.Game.BypassRemoteHostCheck();
                Master.Game.ReplaceRSAKeys(FAKE_EXPONENT, FAKE_MODULUS);
                // TODO: Master.ModulesPg.ModifyGame(Master.Game);

                State = ASSEMBLING_CLIENT;
                Master.Game.Assemble();

                State     = COMPRESSING_CLIENT;
                e.Payload = Master.Game.Compress();

                string clientPath = Path.Combine(
                    _modifiedClientsDir.FullName, Master.Game.GetClientRevision());

                Directory.CreateDirectory(clientPath);
                File.WriteAllBytes(clientPath + "\\Habbo.swf", e.Payload);
            }
            else
            {
                // TODO: if (Master.ModulesPg.ModifyGame(Master.Game))
                //    Master.Game.Assemble();

                e.Payload = Master.Game.ToByteArray();
            }

            if (_replacedVars.Count > 0)
            {
                Eavesdropper.ResponseIntercepted += ReplaceResources;
            }
            else
            {
                Halt();
            }

            State = INTERCEPTING_CONNECTING;
            Master.Connection.ConnectAsync(Master.GameData.InfoHost,
                                           infoPort).ContinueWith(ConnectTaskCompleted);
        }
示例#5
0
        private void ReplaceClient(object sender, ResponseInterceptedEventArgs e)
        {
            if (e.Response.ContentType != "application/x-shockwave-flash" &&
                !File.Exists(e.Response.ResponseUri.LocalPath))
            {
                return;
            }

            Eavesdropper.ResponseIntercepted -= ReplaceClient;

            ushort[] ports = GameData.Port.Split(',')
                             .Select(s => ushort.Parse(s)).ToArray();

            if (Game == null)
            {
                VerifyGameClientAsync(e.Payload).Wait();
                SetStatus(TanjiState.ModifyingClient);

                Game.BypassRemoteHostCheck();
                Game.RemoveLocalUseRestrictions();
                Game.DisableExpirationDateCheck();
                Game.ReplaceRSA(HandshakeManager.FAKE_EXPONENT, HandshakeManager.FAKE_MODULUS);

                SetStatus(TanjiState.ReconstructingClient);
                Game.Reconstruct();

                File.WriteAllBytes(
                    $"{_modifiedClientsDir.FullName}\\{GameData.MovieName}.swf",
                    Game.ToByteArray());
            }

            e.Payload = Game.ToByteArray();
            if (ResourceReplacements.Count > 0)
            {
                Eavesdropper.ResponseIntercepted += ReplaceResources;
            }
            else
            {
                Halt();
            }

            SetStatus(TanjiState.InterceptingConnection);
            UI.Connection.ConnectAsync(GameData.Host, ports)
            .ContinueWith(ConnectTaskCompleted);
        }
示例#6
0
        private void InterceptClientPage(object sender, ResponseInterceptedEventArgs e)
        {
            if (!e.Response.ContentType.Contains("text/html"))
            {
                return;
            }
            string body = Encoding.UTF8.GetString(e.Payload);

            if (!body.Contains("info.host") && !body.Contains("info.port"))
            {
                return;
            }

            Eavesdropper.ResponseIntercepted -= InterceptClientPage;
            App.Master.GameData.Source        = body;

            if (IsAutomaticServerExtraction)
            {
                string[] ports = App.Master.GameData.InfoPort.Split(',');
                if (ports.Length == 0 ||
                    !ushort.TryParse(ports[0], out ushort port) ||
                    !HotelEndPoint.TryParse(App.Master.GameData.InfoHost, port, out HotelEndPoint endpoint))
                {
                    Cancel(null);
                    return;
                }
                HotelServer = endpoint;
            }

            if (App.Master.GameData.Hotel != HHotel.Unknown)
            {
                body = body.Replace(App.Master.GameData.InfoHost, "127.0.0.1");
            }
            body = body.Replace(".swf", $".swf?Tanji-{DateTime.Now.Ticks}");

            Status = SYNCHRONIZING_GAME_DATA;
            App.Master.Synchronize(App.Master.GameData);

            e.Payload = Encoding.UTF8.GetBytes(body);

            Status = INJECTING_CLIENT;
            Eavesdropper.RequestIntercepted += InjectGameClient;
        }
示例#7
0
        private void ExtractGameData(object sender, ResponseInterceptedEventArgs e)
        {
            if (e.Response.ContentType != "text/html")
            {
                return;
            }
            if (GameData != null)
            {
                return;
            }

            string responseBody = Encoding.UTF8.GetString(e.Payload);

            if (responseBody.Contains("swfobject.embedSWF") &&
                responseBody.Contains("connection.info.host"))
            {
                Eavesdropper.ResponseIntercepted -= ExtractGameData;
                try
                {
                    GameData = new HGameData(responseBody);
                    Hotel    = SKore.ToHotel(GameData.InfoHost);

                    var    clientUri  = new Uri(GameData["flash.client.url"]);
                    string clientPath = clientUri.Segments[2].TrimEnd('/');

                    Task <bool> gameClientVerifierTask =
                        VerifyGameClientAsync($"{_modifiedClientsDir.FullName}\\{clientPath}\\Habbo.swf");

                    if (e.Response.ResponseUri.Segments.Length > 2)
                    {
                        // TODO: Set uniqueId somewhere.
                        //GameData.UniqueId =
                        //    e.Response.ResponseUri.Segments[2].TrimEnd('/');
                    }

                    string embeddedSwf  = responseBody.GetChild("embedSWF(", ',');
                    string nonCachedSwf = $"{embeddedSwf} + \"?{DateTime.Now.Ticks}-Tanji\"";

                    responseBody = responseBody.Replace(
                        "embedSWF(" + embeddedSwf, "embedSWF(" + nonCachedSwf);
                    e.Payload = Encoding.UTF8.GetBytes(responseBody);

                    var resourceKeys = ResourceReplacements.Keys.ToArray();
                    foreach (string resourceKey in resourceKeys)
                    {
                        string realValue = GameData[resourceKey]
                                           .Replace("\\/", "/");

                        string fakeValue =
                            ResourceReplacements[resourceKey];

                        ResourceReplacements.Remove(resourceKey);
                        ResourceReplacements[realValue] = fakeValue;
                    }
                    if (gameClientVerifierTask.Result)
                    {
                        SetStatus(TanjiState.InjectingClient);
                        Eavesdropper.RequestIntercepted += InjectClient;
                    }
                    else
                    {
                        SetStatus(TanjiState.InterceptingClient);
                        Eavesdropper.ResponseIntercepted += ReplaceClient;
                    }
                }
                catch (Exception ex) { WriteLog(ex); }
                finally
                {
                    if (GameData == null)
                    {
                        Eavesdropper.ResponseIntercepted += ExtractGameData;
                    }
                }
            }
        }
示例#8
0
 private static Task Eavesdropper_ResponseInterceptedAsync(object sender, ResponseInterceptedEventArgs e)
 {
     return(Task.CompletedTask);
 }
示例#9
0
        private void ExtractGameData(object sender, ResponseInterceptedEventArgs e)
        {
            if (e.Response.ContentType != "text/html")
            {
                return;
            }
            if (State != TanjiState.ExtractingGameData)
            {
                return;
            }

            string responseBody = Encoding.UTF8.GetString(e.Payload);

            if (responseBody.Contains("swfobject.embedSWF") &&
                responseBody.Contains("connection.info.host"))
            {
                byte[] replacementData = e.Payload;
                Eavesdropper.ResponseIntercepted -= ExtractGameData;
                try
                {
                    UI.GameData.Update(responseBody);
                    UI.Hotel = SKore.ToHotel(UI.GameData.InfoHost);

                    UI.ModulesPg.ModifyGameData(UI.GameData);
                    responseBody = UI.GameData.Source;

                    var    clientUri  = new Uri(UI.GameData["flash.client.url"]);
                    string clientPath = clientUri.Segments[2].TrimEnd('/');

                    Task <bool> verifyGameClientTask = null;
                    if (!string.IsNullOrWhiteSpace(CustomClientPath))
                    {
                        verifyGameClientTask =
                            VerifyGameClientAsync(CustomClientPath);
                    }
                    if (verifyGameClientTask == null || !verifyGameClientTask.Result)
                    {
                        verifyGameClientTask =
                            VerifyGameClientAsync($"{_modifiedClientsDir.FullName}\\{clientPath}\\Habbo.swf");
                    }

                    string embeddedSwf  = responseBody.GetChild("embedSWF(", ',');
                    string nonCachedSwf = $"{embeddedSwf} + \"?{DateTime.Now.Ticks}-Tanji\"";

                    responseBody = responseBody.Replace(
                        "embedSWF(" + embeddedSwf, "embedSWF(" + nonCachedSwf);

                    responseBody    = responseBody.Replace(UI.GameData.InfoHost, "127.0.0.1");
                    replacementData = Encoding.UTF8.GetBytes(responseBody);

                    string[] resourceKeys = ResourceReplacements.Keys.ToArray();
                    foreach (string resourceKey in resourceKeys)
                    {
                        string realValue = UI.GameData[resourceKey]
                                           .Replace("\\/", "/");

                        string fakeValue =
                            ResourceReplacements[resourceKey];

                        ResourceReplacements.Remove(resourceKey);
                        ResourceReplacements[realValue] = fakeValue;
                    }
                    if (verifyGameClientTask.Result)
                    {
                        SetState(TanjiState.InjectingClient);
                        Eavesdropper.RequestIntercepted += InjectClient;
                    }
                    else
                    {
                        SetState(TanjiState.InterceptingClient);
                        Eavesdropper.ResponseIntercepted += ReplaceClient;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Intercepted game data is not recognized as coming from a valid Habbo Hotel site.",
                                    "Tanji ~ Alert!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

                    WriteLog(ex);
                }
                finally
                {
                    if (State == TanjiState.ExtractingGameData)
                    {
                        Eavesdropper.ResponseIntercepted += ExtractGameData;
                    }
                    else
                    {
                        e.Payload = replacementData;
                    }
                }
            }
        }
        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();
        }
示例#11
0
 private Task ResponseInterceptedAsync(object sender, ResponseInterceptedEventArgs e)
 {
     Console.WriteLine($"Intercepted Response: " + e.Uri);
     return(null);
 }
示例#12
0
        private void InterceptGameClient(object sender, ResponseInterceptedEventArgs e)
        {
            if (!e.Response.ResponseUri.Query.StartsWith("?Tanji-"))
            {
                return;
            }
            if (e.Response.ContentType != "application/x-shockwave-flash")
            {
                return;
            }
            Eavesdropper.ResponseIntercepted -= InterceptGameClient;

            Uri    remoteUrl  = e.Response.ResponseUri;
            string clientPath = Path.GetFullPath($"Modified Clients/{remoteUrl.Host}/{remoteUrl.LocalPath}");

            string clientDirectory = Path.GetDirectoryName(clientPath);

            Directory.CreateDirectory(clientDirectory);

            Status                   = DISASSEMBLING_CLIENT;
            App.Master.Game          = new HGame(e.Payload);
            App.Master.Game.Location = clientPath;
            App.Master.Game.Disassemble();

            if (App.Master.Game.IsPostShuffle)
            {
                Status = GENERATING_MESSAGE_HASHES;
                App.Master.Game.GenerateMessageHashes();

                Status = MODIFYING_CLIENT;
                App.Master.Game.DisableHostChecks();
                App.Master.Game.InjectKeyShouter(4001);
            }

            if (App.Master.GameData.Hotel == HHotel.Unknown)
            {
                if (IsAutomaticServerExtraction)
                {
                    Tuple <string, int?> endPoint = App.Master.Game.ExtractEndPoint();
                    if (!string.IsNullOrWhiteSpace(endPoint.Item1) || endPoint.Item2 != null)
                    {
                        string host = (!string.IsNullOrWhiteSpace(endPoint.Item1) ?
                                       endPoint.Item1 : HotelServer.Host);

                        HotelServer = HotelEndPoint.Parse(host, endPoint.Item2 ?? HotelServer.Port);
                    }
                }

                Status = MODIFYING_CLIENT;
                App.Master.Game.InjectEndPoint("127.0.0.1", HotelServer.Port);
            }

            Status = SYNCHRONIZING_GAME;
            App.Master.Synchronize(App.Master.Game);

            CompressionKind compression = CompressionKind.ZLIB;

#if DEBUG
            compression = CompressionKind.None;
#endif

            Status    = ASSEMBLING_CLIENT;
            e.Payload = App.Master.Game.ToArray(compression);
            using (var clientStream = File.Open(clientPath, FileMode.Create, FileAccess.Write))
            {
                clientStream.Write(e.Payload, 0, e.Payload.Length);
            }

            TerminateProxy();
            InterceptConnection();
        }