Example #1
0
        static void Main(string[] args)
        {
            var stringReader = new StringReader(XElement.Load("./Bootstrapper.exe.nlog").ToString());

            using (XmlReader xmlReader = XmlReader.Create(stringReader)) {
                LogManager.Configuration = new XmlLoggingConfiguration(xmlReader, null);
            }

            ActionLookup.GetActionInfo(2);
            StatusEffectLookup.GetStatusInfo(2);
            ZoneLookup.GetZoneInfo(138);

            ActionItem action = ActionLookup.GetActionInfo(2);
            StatusItem status = StatusEffectLookup.GetStatusInfo(2);
            MapItem    zone   = ZoneLookup.GetZoneInfo(138);

            Process process = Process.GetProcessesByName("ffxiv_dx11").FirstOrDefault();

            if (process != null)
            {
                MemoryHandler.Instance.SetProcess(
                    new ProcessModel {
                    IsWin64 = true,
                    Process = process,
                });

                while (Scanner.Instance.IsScanning)
                {
                    Thread.Sleep(1000);
                    Console.WriteLine("Scanning...");
                }

                MemoryHandler.Instance.SignaturesFoundEvent += delegate(object sender, SignaturesFoundEvent e) {
                    foreach (KeyValuePair <string, Signature> kvp in e.Signatures)
                    {
                        Console.WriteLine($"{kvp.Key} => {kvp.Value.GetAddress():X}");
                    }
                };
            }

            Console.WriteLine("To exit this application press \"Enter\".");
            Console.ReadLine();
        }
Example #2
0
        public void SetProcess(ProcessModel processModel, string gameLanguage = "English", string patchVersion = "latest", bool useLocalCache = true, bool scanAllMemoryRegions = false)
        {
            this.ProcessModel  = processModel;
            this.GameLanguage  = gameLanguage;
            this.UseLocalCache = useLocalCache;

            this.UnsetProcess();

            try
            {
                this.ProcessHandle = UnsafeNativeMethods.OpenProcess(UnsafeNativeMethods.ProcessAccessFlags.PROCESS_VM_ALL, false, (uint)this.ProcessModel.ProcessID);
            }
            catch (Exception)
            {
                this.ProcessHandle = processModel.Process.Handle;
            }
            finally
            {
                Constants.ProcessHandle = this.ProcessHandle;
                this.IsAttached         = true;
            }

            if (this.IsNewInstance)
            {
                this.IsNewInstance = false;

                ActionLookup.Resolve();
                StatusEffectLookup.Resolve();
                ZoneLookup.Resolve();

                this.ResolveMemoryStructures(processModel, patchVersion);
            }

            this.AttachmentWorker = new AttachmentWorker();
            this.AttachmentWorker.StartScanning(processModel);

            this.SystemModules.Clear();
            this.GetProcessModules();

            Scanner.Instance.Locations.Clear();
            Scanner.Instance.LoadOffsets(Signatures.Resolve(processModel, patchVersion), scanAllMemoryRegions);
        }
Example #3
0
        public MemoryHandler(SharlayanConfiguration configuration)
        {
            this.Configuration = configuration;
            try {
                this.ProcessHandle = UnsafeNativeMethods.OpenProcess(UnsafeNativeMethods.ProcessAccessFlags.PROCESS_VM_ALL, false, (uint)this.Configuration.ProcessModel.ProcessID);
            }
            catch (Exception) {
                this.ProcessHandle = this.Configuration.ProcessModel.Process.Handle;
            }
            finally {
                this.IsAttached = true;
            }

            this.Configuration.ProcessModel.Process.EnableRaisingEvents = true;
            this.Configuration.ProcessModel.Process.Exited += this.Process_OnExited;

            this.GetProcessModules();

            this.Scanner = new Scanner(this);
            this.Reader  = new Reader(this);

            if (this._isNewInstance)
            {
                this._isNewInstance = false;

                Task.Run(
                    async() => {
                    await this.ResolveMemoryStructures();

                    await ActionLookup.Resolve(this.Configuration);
                    await StatusEffectLookup.Resolve(this.Configuration);
                    await ZoneLookup.Resolve(this.Configuration);
                });
            }

            Task.Run(
                async() => {
                Signature[] signatures = await Signatures.Resolve(this.Configuration);
                this.Scanner.LoadOffsets(signatures, this.Configuration.ScanAllRegions);
            });
        }
Example #4
0
        public async Task SetProcess(ProcessModel processModel, string gameLanguage = "English", string patchVersion = "latest", bool useLocalCache = true, bool scanAllMemoryRegions = false)
        {
            this.ProcessModel  = processModel;
            this.GameLanguage  = gameLanguage;
            this.UseLocalCache = useLocalCache;

            this.UnsetProcess();

            try {
                this.ProcessHandle = UnsafeNativeMethods.OpenProcess(UnsafeNativeMethods.ProcessAccessFlags.PROCESS_VM_ALL, false, (uint)this.ProcessModel.ProcessID);
            }
            catch (Exception) {
                this.ProcessHandle = processModel.Process.Handle;
            }
            finally {
                Constants.ProcessHandle = this.ProcessHandle;
                this.IsAttached         = true;
            }

            if (this.IsNewInstance)
            {
                this.IsNewInstance = false;

                //Parallel.Invoke(async () => await ActionLookup.Resolve(), async () => await StatusEffectLookup.Resolve(), async () => await ZoneLookup.Resolve());
                Task[] taskArray = new Task[3];

                taskArray[0] = Task.Factory.StartNew(async() => await ActionLookup.Resolve());
                taskArray[1] = Task.Factory.StartNew(async() => await StatusEffectLookup.Resolve());
                taskArray[2] = Task.Factory.StartNew(async() => await ZoneLookup.Resolve());

                Task.WaitAll(taskArray);
                //await ActionLookup.Resolve();
                //await StatusEffectLookup.Resolve();
                //await ZoneLookup.Resolve();


                await this.ResolveMemoryStructures(processModel, patchVersion);
            }

            this.AttachmentWorker = new AttachmentWorker();
            this.AttachmentWorker.StartScanning(processModel);

            this.SystemModules.Clear();
            this.GetProcessModules();

            Scanner.Instance.Locations.Clear();
            var signatures = await Signatures.Resolve(processModel, patchVersion);

            List <Signature> sigs = signatures as List <Signature>;

            sigs.Add(new Signature
            {
                Key         = "INVENTORYBAGS",
                PointerPath = new List <long>
                {
                    0x15786f0
                }
            });

            sigs.Add(new Signature
            {
                Key         = "INVENTORYSTART",
                PointerPath = new List <long>
                {
                    0x1c1de30
                }
            });
            Scanner.Instance.LoadOffsets(sigs, scanAllMemoryRegions);
        }
Example #5
0
        /// <summary>
        /// </summary>
        /// <param name="statusEntriesPlayers"></param>
        private void ProcessHealingOverTime(IEnumerable <StatusItem> statusEntriesPlayers)
        {
            foreach (StatusItem statusEntry in statusEntriesPlayers)
            {
                try {
                    Sharlayan.Models.XIVDatabase.StatusItem statusInfo = StatusEffectLookup.GetStatusInfo((uint)statusEntry.StatusID);
                    var statusKey = statusInfo.Name.English;
                    switch (Constants.GameLanguage)
                    {
                    case "French":
                        statusKey = statusInfo.Name.French;
                        break;

                    case "Japanese":
                        statusKey = statusInfo.Name.Japanese;
                        break;

                    case "German":
                        statusKey = statusInfo.Name.German;
                        break;

                    case "Chinese":
                        statusKey = statusInfo.Name.Chinese;
                        break;

                    case "Korean":
                        statusKey = statusInfo.Name.Korean;
                        break;
                    }

                    if (string.IsNullOrWhiteSpace(statusKey))
                    {
                        continue;
                    }

                    var        amount     = this.NPCEntry.Level / ((60 - this.NPCEntry.Level) * .025);
                    var        key        = statusKey;
                    ActionItem actionData = null;
                    foreach (KeyValuePair <string, ActionItem> healingOverTimeAction in HealingOverTimeHelper.PlayerActions.ToList().Where(d => string.Equals(d.Key, key, Constants.InvariantComparer)))
                    {
                        actionData = healingOverTimeAction.Value;
                    }

                    if (actionData == null)
                    {
                        continue;
                    }

                    var zeroFoundInList = false;
                    var regen           = Regex.IsMatch(key, @"(リジェネ|récup|regen|再生|whispering|murmure|erhebendes|光の囁き|日光的低语)", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
                    List <KeyValuePair <string, double> > healingHistoryList = ParseHelper.LastAmountByAction.GetPlayer(this.Name).ToList();
                    var resolvedPotency = 350;
                    foreach (KeyValuePair <string, double> healingAction in healingHistoryList)
                    {
                        if (regen)
                        {
                            var found = false;
                            Dictionary <string, List <string> > cureActions   = HealingOverTimeHelper.CureActions;
                            Dictionary <string, List <string> > medicaActions = HealingOverTimeHelper.MedicaActions;
                            KeyValuePair <string, double>       action        = healingAction;
                            if (cureActions["III"].Any(cureAction => string.Equals(action.Key, cureAction, Constants.InvariantComparer)))
                            {
                                found           = zeroFoundInList = true;
                                resolvedPotency = 550;
                            }

                            if (cureActions["II"].Any(cureAction => string.Equals(action.Key, cureAction, Constants.InvariantComparer)))
                            {
                                found           = zeroFoundInList = true;
                                resolvedPotency = 650;
                            }

                            if (cureActions["I"].Any(cureAction => string.Equals(action.Key, cureAction, Constants.InvariantComparer)))
                            {
                                found           = zeroFoundInList = true;
                                resolvedPotency = 400;
                            }

                            if (medicaActions["II"].Any(medicaAction => string.Equals(action.Key, medicaAction, Constants.InvariantComparer)))
                            {
                                found           = zeroFoundInList = true;
                                resolvedPotency = 200;
                            }

                            if (medicaActions["I"].Any(medicaAction => string.Equals(action.Key, medicaAction, Constants.InvariantComparer)))
                            {
                                found           = zeroFoundInList = true;
                                resolvedPotency = 300;
                            }

                            if (found)
                            {
                                if (action.Value > 0)
                                {
                                    amount = action.Value;
                                }

                                break;
                            }
                        }

                        if (string.Equals(healingAction.Key, key, Constants.InvariantComparer))
                        {
                            amount = healingAction.Value;
                            break;
                        }
                    }

                    statusKey = $"{statusKey} [•]";
                    if (amount == 0)
                    {
                        amount = 75;
                    }

                    resolvedPotency = zeroFoundInList
                                          ? resolvedPotency
                                          : regen
                                              ? resolvedPotency
                                              : actionData.Potency;
                    var tickHealing = Math.Ceiling(amount / resolvedPotency * actionData.OverTimePotency / 3);
                    if (actionData.HasNoInitialResult && !zeroFoundInList)
                    {
                        IEnumerable <KeyValuePair <string, double> > nonZeroActions = healingHistoryList.Where(d => !d.Key.Contains("•"));
                        IList <KeyValuePair <string, double> >       keyValuePairs  = nonZeroActions as IList <KeyValuePair <string, double> > ?? nonZeroActions.ToList();
                        double healing = 0;
                        switch (regen)
                        {
                        case true:
                            healing = Math.Ceiling(amount / resolvedPotency * actionData.OverTimePotency / 3);
                            break;

                        case false:
                            if (keyValuePairs.Any())
                            {
                                amount = keyValuePairs.Sum(action => action.Value);
                                amount = amount / keyValuePairs.Count();
                            }

                            healing = Math.Ceiling(amount / resolvedPotency * actionData.OverTimePotency / 3);
                            break;
                        }

                        tickHealing = healing > 0
                                          ? healing
                                          : tickHealing;
                    }

                    var line = new Line {
                        Action         = statusKey,
                        Amount         = tickHealing,
                        EventDirection = EventDirection.Unknown,
                        EventType      = EventType.Cure,
                        EventSubject   = EventSubject.Unknown,
                        Source         = this.Name,
                        SourceEntity   = this.NPCEntry,
                        XOverTime      = true
                    };
                    try {
                        List <StatGroup> players = Controller.Timeline.Party.ToList();
                        StatusItem       entry   = statusEntry;
                        foreach (StatGroup player in players.Where(player => player.Name.Contains(entry.TargetName)))
                        {
                            line.Target = player.Name;
                            break;
                        }
                    }
                    catch (Exception ex) {
                        Logging.Log(Logger, new LogItem(ex, true));
                    }

                    if (string.IsNullOrWhiteSpace(line.Target))
                    {
                        line.Target = $"[???] {statusEntry.TargetName}";
                    }

                    Controller.Timeline.FightingRightNow = true;
                    Controller.Timeline.FightingTimer.Stop();
                    switch (Settings.Default.StoreHistoryEvent)
                    {
                    case "Any":
                        Controller.Timeline.StoreHistoryTimer.Stop();
                        break;
                    }

                    DispatcherHelper.Invoke(
                        delegate {
                        line.Hit = true;

                        // resolve player hp each tick to ensure they are not at max
                        try {
                            List <ActorItem> players = XIVInfoViewModel.Instance.CurrentPCs.Select(entity => entity.Value).ToList();
                            if (!players.Any())
                            {
                                return;
                            }

                            foreach (ActorItem actorEntity in players)
                            {
                                var playerName = actorEntity.Name;
                                Controller.Timeline.TrySetPlayerCurable(playerName, actorEntity.HPMax - actorEntity.HPCurrent);
                            }
                        }
                        catch (Exception ex) {
                            Logging.Log(Logger, new LogItem(ex, true));
                        }

                        var currentCritPercent = this.Stats.GetStatValue("HealingCritPercent");
                        if (new Random().NextDouble() * 3 < currentCritPercent)
                        {
                            line.Crit   = true;
                            line.Amount = line.Amount * 1.5;
                        }

                        Controller.Timeline.GetSetPlayer(line.Source).SetHealingOverTime(line);
                    });
                }
                catch (Exception ex) {
                    Logging.Log(Logger, new LogItem(ex, true));
                }
            }

            Controller.Timeline.FightingTimer.Start();
            switch (Settings.Default.StoreHistoryEvent)
            {
            case "Any":
                Controller.Timeline.StoreHistoryTimer.Start();
                break;
            }
        }
Example #6
0
        private void ProcessBuffs(IEnumerable <StatusItem> statusEntriesPlayers)
        {
            foreach (StatusItem statusEntry in statusEntriesPlayers)
            {
                try {
                    Sharlayan.Models.XIVDatabase.StatusItem statusInfo = StatusEffectLookup.GetStatusInfo((uint)statusEntry.StatusID);
                    var statusKey = statusInfo.Name.English;
                    switch (Constants.GameLanguage)
                    {
                    case "French":
                        statusKey = statusInfo.Name.French;
                        break;

                    case "Japanese":
                        statusKey = statusInfo.Name.Japanese;
                        break;

                    case "German":
                        statusKey = statusInfo.Name.German;
                        break;

                    case "Chinese":
                        statusKey = statusInfo.Name.Chinese;
                        break;

                    case "Korean":
                        statusKey = statusInfo.Name.Korean;
                        break;
                    }

                    if (string.IsNullOrWhiteSpace(statusKey))
                    {
                        continue;
                    }

                    var line = new Line {
                        Action         = statusKey,
                        Amount         = 0,
                        EventDirection = EventDirection.Unknown,
                        EventType      = EventType.Unknown,
                        EventSubject   = EventSubject.Unknown,
                        Source         = this.Name,
                        SourceEntity   = this.NPCEntry
                    };
                    try {
                        List <StatGroup> players = Controller.Timeline.Party.ToList();
                        StatusItem       entry   = statusEntry;
                        foreach (StatGroup player in players.Where(player => player.Name.Contains(entry.TargetName)))
                        {
                            line.Target = player.Name;
                            break;
                        }
                    }
                    catch (Exception ex) {
                        Logging.Log(Logger, new LogItem(ex, true));
                    }

                    if (string.IsNullOrWhiteSpace(line.Target))
                    {
                        line.Target = $"[???] {statusEntry.TargetName}";
                    }

                    DispatcherHelper.Invoke(() => Controller.Timeline.GetSetPlayer(line.Source).SetBuff(line));
                }
                catch (Exception ex) {
                    Logging.Log(Logger, new LogItem(ex, true));
                }
            }
        }
Example #7
0
        /// <summary>
        /// </summary>
        /// <param name="statusEntriesMonsters"></param>
        private void ProcessDamageOverTime(IEnumerable <StatusItem> statusEntriesMonsters)
        {
            foreach (StatusItem statusEntry in statusEntriesMonsters)
            {
                try {
                    Sharlayan.Models.XIVDatabase.StatusItem statusInfo = StatusEffectLookup.GetStatusInfo((uint)statusEntry.StatusID);
                    var statusKey = statusInfo.Name.English;
                    switch (Constants.GameLanguage)
                    {
                    case "French":
                        statusKey = statusInfo.Name.French;
                        break;

                    case "Japanese":
                        statusKey = statusInfo.Name.Japanese;
                        break;

                    case "German":
                        statusKey = statusInfo.Name.German;
                        break;

                    case "Chinese":
                        statusKey = statusInfo.Name.Chinese;
                        break;

                    case "Korean":
                        statusKey = statusInfo.Name.Korean;
                        break;
                    }

                    if (string.IsNullOrWhiteSpace(statusKey))
                    {
                        continue;
                    }

                    var difference = 60 - this.NPCEntry.Level;
                    if (difference <= 0)
                    {
                        difference = 10;
                    }

                    var        amount     = this.NPCEntry.Level / (difference * .025);
                    var        key        = statusKey;
                    ActionItem actionData = null;
                    foreach (KeyValuePair <string, ActionItem> damageOverTimeAction in DamageOverTimeHelper.PlayerActions.ToList().Where(d => string.Equals(d.Key, key, Constants.InvariantComparer)))
                    {
                        actionData = damageOverTimeAction.Value;
                    }

                    if (actionData == null)
                    {
                        continue;
                    }

                    var zeroFoundInList = false;
                    var bio             = Regex.IsMatch(key, @"(バイオ|bactérie|bio|毒菌)", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
                    var thunder         = Regex.IsMatch(key, @"(サンダ|foudre|blitz|thunder|闪雷)", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
                    List <KeyValuePair <string, double> > lastDamageAmountByActions = ParseHelper.LastAmountByAction.GetPlayer(this.Name).ToList();
                    var    resolvedPotency       = 80;
                    var    thunderDuration       = 24.0;
                    double originalThunderDamage = 0;
                    foreach (KeyValuePair <string, double> lastDamageAmountByAction in lastDamageAmountByActions)
                    {
                        if (thunder)
                        {
                            var found = false;
                            Dictionary <string, List <string> > thunderActions = DamageOverTimeHelper.ThunderActions;
                            KeyValuePair <string, double>       action         = lastDamageAmountByAction;
                            if (thunderActions["III"].Any(thunderAction => string.Equals(action.Key, thunderAction, Constants.InvariantComparer)))
                            {
                                found                 = true;
                                thunderDuration       = (double)DamageOverTimeHelper.PlayerActions["thunder iii"].Duration;
                                originalThunderDamage = action.Value;
                                amount                = action.Value / DamageOverTimeHelper.PlayerActions["thunder iii"].Potency * 30;
                            }

                            if (thunderActions["II"].Any(thunderAction => string.Equals(action.Key, thunderAction, Constants.InvariantComparer)))
                            {
                                found                 = true;
                                thunderDuration       = (double)DamageOverTimeHelper.PlayerActions["thunder ii"].Duration;
                                originalThunderDamage = action.Value;
                                amount                = action.Value / DamageOverTimeHelper.PlayerActions["thunder ii"].Potency * 30;
                            }

                            if (thunderActions["I"].Any(thunderAction => string.Equals(action.Key, thunderAction, Constants.InvariantComparer)))
                            {
                                found                 = true;
                                thunderDuration       = (double)DamageOverTimeHelper.PlayerActions["thunder"].Duration;
                                originalThunderDamage = action.Value;
                                amount                = action.Value;
                            }

                            if (found)
                            {
                                break;
                            }
                        }

                        if (bio)
                        {
                            var found = false;
                            Dictionary <string, List <string> > ruinActions = DamageOverTimeHelper.RuinActions;
                            KeyValuePair <string, double>       action      = lastDamageAmountByAction;
                            if (ruinActions["II"].Any(ruinAction => string.Equals(action.Key, ruinAction, Constants.InvariantComparer)))
                            {
                                found  = zeroFoundInList = true;
                                amount = action.Value;
                            }

                            if (ruinActions["I"].Any(ruinAction => string.Equals(action.Key, ruinAction, Constants.InvariantComparer)))
                            {
                                found  = zeroFoundInList = true;
                                amount = action.Value;
                            }

                            if (found)
                            {
                                break;
                            }
                        }

                        if (string.Equals(lastDamageAmountByAction.Key, key, Constants.InvariantComparer))
                        {
                            amount = lastDamageAmountByAction.Value;
                            break;
                        }
                    }

                    statusKey = $"{statusKey} [•]";
                    if (amount == 0)
                    {
                        amount = 75;
                    }

                    resolvedPotency = zeroFoundInList
                                          ? resolvedPotency
                                          : bio
                                              ? resolvedPotency
                                              : actionData.Potency;
                    var tickDamage = Math.Ceiling(amount / resolvedPotency * actionData.OverTimePotency / 3);
                    if (actionData.HasNoInitialResult && !zeroFoundInList)
                    {
                        IEnumerable <KeyValuePair <string, double> > nonZeroActions = lastDamageAmountByActions.Where(d => !d.Key.Contains("•"));
                        IList <KeyValuePair <string, double> >       keyValuePairs  = nonZeroActions as IList <KeyValuePair <string, double> > ?? nonZeroActions.ToList();
                        double damage = 0;
                        switch (bio)
                        {
                        case true:
                            damage = Math.Ceiling(amount / resolvedPotency * actionData.OverTimePotency / 3);
                            break;

                        case false:
                            if (keyValuePairs.Any())
                            {
                                amount = keyValuePairs.Sum(action => action.Value);
                                amount = amount / keyValuePairs.Count();
                            }

                            damage = Math.Ceiling(amount / resolvedPotency * actionData.OverTimePotency / 3);
                            break;
                        }

                        tickDamage = damage > 0
                                         ? damage
                                         : tickDamage;
                    }

                    if (originalThunderDamage > 300 && thunder)
                    {
                        tickDamage = Math.Ceiling(originalThunderDamage / (thunderDuration + 3));
                    }

                    var line = new Line {
                        Action         = statusKey,
                        Amount         = tickDamage,
                        EventDirection = EventDirection.Unknown,
                        EventType      = EventType.Damage,
                        EventSubject   = EventSubject.Unknown,
                        Source         = this.Name,
                        SourceEntity   = this.NPCEntry,
                        Target         = statusEntry.TargetName,
                        XOverTime      = true
                    };
                    Controller.Timeline.FightingRightNow = true;
                    Controller.Timeline.FightingTimer.Stop();
                    Controller.Timeline.StoreHistoryTimer.Stop();
                    DispatcherHelper.Invoke(
                        delegate {
                        line.Hit = true;
                        var currentCritPercent = this.Stats.GetStatValue("DamageCritPercent");
                        if (new Random().NextDouble() * 3 < currentCritPercent)
                        {
                            line.Crit   = true;
                            line.Amount = line.Amount * 1.5;
                        }

                        Controller.Timeline.GetSetPlayer(line.Source).SetDamageOverTime(line);
                        Controller.Timeline.GetSetMonster(line.Target).SetDamageTakenOverTime(line);
                    });
                }
                catch (Exception ex) {
                    Logging.Log(Logger, new LogItem(ex, true));
                }
            }

            Controller.Timeline.FightingTimer.Start();
            Controller.Timeline.StoreHistoryTimer.Start();
        }
Example #8
0
        static void Main(string[] args)
        {
            var stringReader = new StringReader(XElement.Load("./Bootstrapper.exe.nlog").ToString());

            using (XmlReader xmlReader = XmlReader.Create(stringReader)) {
                LogManager.Configuration = new XmlLoggingConfiguration(xmlReader, null);
            }

            ActionLookup.GetActionInfo(2);
            StatusEffectLookup.GetStatusInfo(2);
            ZoneLookup.GetZoneInfo(138);

            ActionItem action = ActionLookup.GetActionInfo(2);
            StatusItem status = StatusEffectLookup.GetStatusInfo(2);
            MapItem    zone   = ZoneLookup.GetZoneInfo(138);

            var processName = "ffxiv_dx11";

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                processName = "ffxiv_dx11.exe";
            }

            Process process = Process.GetProcessesByName(processName).FirstOrDefault();

            if (process == null && RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                var ps = new Process();
                ps.StartInfo = new ProcessStartInfo("ps", "-Ao pid,command");
                ps.StartInfo.RedirectStandardOutput = true;
                ps.Start();
                var content = ps.StandardOutput.ReadToEnd();
                ps.WaitForExit(2000);

                var pid = content.Split(Environment.NewLine).Where(x => x.Contains(processName)).Select(x => Enumerable.FirstOrDefault(x.Split(' '))).FirstOrDefault(x => x != null);
                if (!string.IsNullOrEmpty(pid))
                {
                    process = Process.GetProcessById(int.Parse(pid));
                }
            }

            if (process != null)
            {
                MemoryHandler.Instance.SetProcess(
                    new ProcessModel {
                    IsWin64 = true,
                    Process = process,
                });

                MemoryHandler.Instance.SignaturesFoundEvent += delegate(object sender, SignaturesFoundEvent e) {
                    foreach (KeyValuePair <string, Signature> kvp in e.Signatures)
                    {
                        Console.WriteLine($"{kvp.Key} => {kvp.Value.GetAddress():X}");
                    }
                };

                while (Scanner.Instance.IsScanning)
                {
                    Thread.Sleep(1000);
                    Console.WriteLine("Scanning...");
                }
            }

            Console.WriteLine("To exit this application press \"Enter\".");
            Console.ReadLine();
        }