Esempio n. 1
0
        private static void Dump(ProcessStream stream)
        {
            var fileName = $"dump_{DateTime.Now.Ticks}.bin";

            using var outStream = File.Create(fileName);
            stream.Position     = 0;
            stream.CopyTo(outStream);

            Console.WriteLine($"Dumped to {fileName}");
        }
Esempio n. 2
0
        async static Task Run(string configFileName, GameConfiguration game)
        {
            var processName = game.Process;

            Console.WriteLine($"Now searching for the process {processName}...");

            var process = await ProcessStream
                          .TryGetProcessAsync(x => x.ProcessName.Contains(processName));

            if (process == null)
            {
                throw new ExecutionException($"Failed to attach to {game.Process} in the time limit.");
            }

            Console.WriteLine($"We suppose that {processName} has {game.Name} running.\n");
            Console.WriteLine(" [c] clear console");
            Console.WriteLine(" [d] dump memory to file");
            Console.WriteLine(" [p] pause/resume watch");
            Console.WriteLine(" [x] exit");
            Console.WriteLine("Now watching to memory differences...");

            bool isWatchRunning   = true;
            bool isSupposedToExit = false;

            using var stream = new ProcessStream(process, game.Offset, game.Length);
            var taskInput = Task.Run(async() =>
            {
                while (!isSupposedToExit)
                {
                    switch (Console.ReadKey().KeyChar)
                    {
                    case 'c':
                        Console.Clear();
                        break;

                    case 'd':
                        lock (stream)
                            Dump(stream);
                        break;

                    case 'p':
                        isWatchRunning = !isWatchRunning;
                        if (isWatchRunning)
                        {
                            Console.WriteLine("Memory watcher is now scheduled to resume its watch!");
                        }
                        else
                        {
                            Console.WriteLine("Memory watcher is now scheduled to take a rest.");
                        }
                        break;

                    case 'x':
                        isSupposedToExit = true;
                        Console.WriteLine("Memory watcher is now scheduled to exit.");
                        break;
                    }

                    await Task.Delay(10);
                }
            });

            var taskWatch = Task.Run(async() =>
            {
                var length  = game.Length;
                var buffer  = new byte[length];
                var current = new byte[length];

                stream.Position = 0;
                stream.Read(buffer, 0, (int)length);

                while (!isSupposedToExit)
                {
                    await Task.Delay(1);
                    if (!isWatchRunning)
                    {
                        continue;
                    }

                    lock (stream)
                    {
                        stream.Position = 0;
                        stream.Read(current);
                    }

                    for (var i = 0U; i < length; i++)
                    {
                        if (buffer[i] != current[i])
                        {
                            LogDifference(i, buffer[i], current[i], game.Labels);
                        }
                    }

                    var tmp = buffer; // flip buffer for performance reasons
                    buffer  = current;
                    current = tmp;
                }
            });

            using var fsWatcher = new FileSystemWatcher()
                  {
                      Path                = Path.GetDirectoryName(configFileName),
                      Filter              = Path.GetFileName(configFileName),
                      NotifyFilter        = NotifyFilters.LastWrite,
                      EnableRaisingEvents = true,
                  };
            fsWatcher.Changed += (object sender, FileSystemEventArgs e) =>
            {
                Console.WriteLine($"The configuration file {e.Name} has been changed and it will be reloaded.");
                Thread.Sleep(50);

                try
                {
                    var configuration = Configuration.ReadFromYaml(configFileName);
                    var gameNew       = configuration.Games
                                        .FirstOrDefault(x => x.Name == game.Name);

                    if (gameNew == null)
                    {
                        Console.WriteLine($"The configuration for the running game can not be found, so it will not be reloaded.");
                    }
                    else
                    {
                        game = gameNew;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"An error occurred while reading the configuration: {ex.Message}.");
                }
            };

            await Task.WhenAll(taskInput, taskWatch);
        }