Пример #1
0
        static object InspectUITreeNode(UITreeNode node)
        {
            var children =
                node.children
                ?.Select(InspectUITreeNode)
                ?.ToList();

            var dictEntriesWithStringKey =
                node.Dict?.Slots
                ?.Where(slot => slot.KeyStr != null)
                ?.Select(slot =>
            {
                return(new
                {
                    keyString = slot.KeyStr,
                    value_address = slot.me_value.ToString(),
                });
            }).ToList();

            return(new
            {
                address = node.BaseAddress,
                dictEntriesWithStringKey = dictEntriesWithStringKey,
                children = children,
            });
        }
Пример #2
0
        /*
         * This program reads from the memory of an EVE Online client process.
         * The memory reading approach here is based on the example from https://forum.botengine.org/t/advanced-do-it-yourself-memory-reading-in-eve-online/68
         *
         * In contrast to the original code, this version also supports reading from a file containing a sample of the client process.
         * This allows us to repeat the reading as often we want, without having to start an instance of the game client.
         * For a guide on how to save a Windows process to a file, see https://forum.botengine.org/t/how-to-collect-samples-for-memory-reading-development/50
         *
         *      Example command line:
         *      dotnet run -- --source="C:\path-to-a-process-sample-file.zip"  --output="C:\path\to\directory\with\write\access"
         */
        static void Main(string[] args)
        {
            var outputPathParamName = "--output";

            (bool isPresent, string argumentValue) argumentFromParameterName(string parameterName)
            {
                var match =
                    args
                    .Select(arg => Regex.Match(arg, parameterName + "(=(.*)|)", RegexOptions.IgnoreCase))
                    .FirstOrDefault(match => match.Success);

                if (match == null)
                {
                    return(false, null);
                }

                if (match.Groups[1].Length < 1)
                {
                    return(true, null);
                }

                return(true, match?.Groups[2].Value);
            }

            var sourceArgument     = argumentFromParameterName("--source").argumentValue;
            var outputPathArgument = argumentFromParameterName(outputPathParamName).argumentValue;

            IMemoryReader memoryReader = null;

            try
            {
                string sampleId = null;

                if (0 < sourceArgument?.Length)
                {
                    Console.WriteLine("I got the following source and will load from this file: '" + sourceArgument + "'");

                    var sampleFile = System.IO.File.ReadAllBytes(sourceArgument);

                    sampleId = CommonConversion.StringIdentifierFromValue(sampleFile);

                    Console.WriteLine("Loaded sample " + sampleId + " from '" + sourceArgument + "'");

                    var sampleStructure = BotEngine.ProcessMeasurement.MeasurementFromZipArchive(sampleFile);

                    memoryReader = new SampleMemoryReader(sampleStructure);
                }
                else
                {
                    Console.WriteLine("I did not receive a path to a sample file, so I will try to find a live EVE Online client process to read from.");

                    var MengeCandidateProcess = System.Diagnostics.Process.GetProcessesByName("exefile");

                    var gameClientProcess = MengeCandidateProcess.FirstOrDefault();

                    if (null == gameClientProcess)
                    {
                        Console.WriteLine("I did not find an EVE Online client process.");
                        return;
                    }

                    memoryReader = new ProcessMemoryReader(gameClientProcess);
                }

                var pythonMemoryReader = new PythonMemoryReader(memoryReader);

                var uiTreeRoot = EveOnline.UITreeRoot(pythonMemoryReader);

                if (null == uiTreeRoot)
                {
                    Console.WriteLine("Did not find the root of the UI tree.");
                    return;
                }

                Console.WriteLine("Found the root of the UI tree at {0} (0x{0:X})", uiTreeRoot.BaseAddress);

                var allNodes =
                    new UITreeNode[] { uiTreeRoot }
                .Concat(uiTreeRoot.EnumerateChildrenTransitive(pythonMemoryReader)).ToArray();

                Console.WriteLine("Found {0} nodes in this UI tree.", allNodes.Length);

                var representationForReading =
                    System.Text.Encoding.UTF8.GetBytes(
                        Newtonsoft.Json.JsonConvert.SerializeObject(InspectUITreeNode(uiTreeRoot), Newtonsoft.Json.Formatting.Indented));

                Console.WriteLine("The representation for reading has the id '{0}'.",
                                  CommonConversion.StringIdentifierFromValue(representationForReading));

                if (outputPathArgument == null)
                {
                    Console.WriteLine("Did not receive a path to write the results for reading. Add the '" +
                                      outputPathParamName + "' argument to specify the directory to write the results to.");
                    return;
                }

                Console.WriteLine("I write the result to '{0}'.", outputPathArgument);
                System.IO.Directory.CreateDirectory(outputPathArgument);
                var outputFilePath = System.IO.Path.Combine(outputPathArgument, "memory-reading-from-sample-" + sampleId?.Substring(0, 8) + ".json");
                System.IO.File.WriteAllBytes(outputFilePath, representationForReading);
            }
            finally
            {
                (memoryReader as IDisposable)?.Dispose();
            }
        }