ShakalX Ответов: 1

C# boyeralgo to boyermoore help.


Привет всем, у меня есть эта функция, которая делает сканирование в памяти, и она очень медленная, когда я увидел в некоторых местах, что говорит о том, что эта функция может быть намного быстрее, может ли кто-нибудь помочь мне с этой функцией?

private void BoyerAlgo(IntPtr baseAddress, byte[] memoryBrick, string pattern, ref List<IntPtr> addresses)
      {
          int offSet = 0;
          string[] aob = pattern.Split(' ');
          List<int> bytesPos = new List<int>();

          for (int i = 0; i < aob.Length; i++)
              if (aob[i] != "??")
                  bytesPos.Add(i);

          if (bytesPos.Count != 0)
              while ((offSet = Array.IndexOf(memoryBrick, (byte)Convert.ToInt32(aob[bytesPos[0]], 16), offSet)) != -1)
              {
                  if (bytesPos.Count > 1)
                      for (int i = 1; i < bytesPos.Count; i++)
                      {
                          if (memoryBrick.Length <= offSet + pattern.Length
                              || (byte)Convert.ToInt32(aob[bytesPos[i]], 16)
                              != memoryBrick[(offSet - bytesPos[0]) + bytesPos[i]])
                              break;

                          if (i == bytesPos.Count - 1)
                              if (aob[0] == "??")
                                  addresses.Add(baseAddress + (offSet - bytesPos[0]));
                              else addresses.Add(baseAddress + offSet);
                      }
                  else
                      addresses.Add(baseAddress + (offSet - bytesPos[0]));
                  offSet++;
              }
          else
              for (int i = 0; i < memoryBrick.Length; i++)
                  addresses.Add(baseAddress + i);
      }


Что я уже пробовал:

Это весь класс. У меня очень медленные проблемы при поиске hex с start 00 и ?? сканирование занимает много времени-около 2 минут, а начальные значения, такие как 20,2 c, 2d и т. д. идти быстрее.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
namespace WindowsFormsApp1
{
    class AobScaner
    {
        // Varibles//
        public IntPtr processhandle;
        List<IntPtr> addresses = new List<IntPtr>();
        bool isbit64;
        //         //
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead);
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] IntPtr lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead);


        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, out IntPtr lpNumberOfBytesWritten);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, out IntPtr lpNumberOfBytesWritten);
        [DllImport("kernel32.dll", SetLastError = true)]

        public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);
        [Flags]
        public enum ProcessAccessFlags : uint
        {
            All = 0x001F0FFF,
            Terminate = 0x00000001,
            CreateThread = 0x00000002,
            VirtualMemoryOperation = 0x00000008,
            VirtualMemoryRead = 0x00000010,
            VirtualMemoryWrite = 0x00000020,
            DuplicateHandle = 0x00000040,
            CreateProcess = 0x000000080,
            SetQuota = 0x00000100,
            SetInformation = 0x00000200,
            QueryInformation = 0x00000400,
            QueryLimitedInformation = 0x00001000,
            Synchronize = 0x00100000
        }
        public struct MEMORY_BASIC_INFORMATION
        {
            public IntPtr BaseAddress;
            public IntPtr AllocationBase;
            public AllocationProtectEnum AllocationProtect;
            public IntPtr RegionSize;
            public StateEnum State;
            public AllocationProtectEnum Protect;
            public TypeEnum Type;
        }

        public enum AllocationProtectEnum : uint
        {
            PAGE_EXECUTE = 0x00000010,
            PAGE_EXECUTE_READ = 0x00000020,
            PAGE_EXECUTE_READWRITE = 0x00000040,
            PAGE_EXECUTE_WRITECOPY = 0x00000080,
            PAGE_NOACCESS = 0x00000001,
            PAGE_READONLY = 0x00000002,
            PAGE_READWRITE = 0x00000004,
            PAGE_WRITECOPY = 0x00000008,
            PAGE_GUARD = 0x00000100,
            PAGE_NOCACHE = 0x00000200,
            PAGE_WRITECOMBINE = 0x00000400
        }

        public enum StateEnum : uint
        {
            MEM_COMMIT = 0x1000,
            MEM_FREE = 0x10000,
            MEM_RESERVE = 0x2000
        }

        public enum TypeEnum : uint
        {
            MEM_IMAGE = 0x1000000,
            MEM_MAPPED = 0x40000,
            MEM_PRIVATE = 0x20000
        }

        [DllImport("kernel32.dll")]
        static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);

        private static IntPtr OpenProcess(Process proc, ProcessAccessFlags flags)
        {
            return OpenProcess(ProcessAccessFlags.All, false, proc.Id);
        }

        public static bool Is64Bit(Process process)
        {
            if (Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") == "x86")
                return false;

            bool isWow64;
            if (!IsWow64Process(process.Handle, out isWow64))
                throw new System.ComponentModel.Win32Exception();
            return !isWow64;
        }

        [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process);

        public void ReadAOB(string Scancode)
        {
            if ((int)processhandle > 0)
            {
                IntPtr bytesRead = IntPtr.Zero;
                long MaxAddress = 0;
                if (isbit64)
                    MaxAddress = 0x7fffffffffffffff;
                else
                    MaxAddress = 0x7fffffff;
                long address = 0;
                addresses.Clear();
                do
                {
                    MEMORY_BASIC_INFORMATION m;
                    int result = VirtualQueryEx(processhandle, (IntPtr)address, out m, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)));
                    if (m.Protect == AllocationProtectEnum.PAGE_READWRITE)
                    {
                        byte[] buffer = new byte[(int)m.RegionSize];
                        // IntPtr buffer = IntPtr.Zero;
                        ReadProcessMemory(processhandle, m.BaseAddress, buffer, (int)m.RegionSize, out bytesRead);
                        BoyerAlgo(m.BaseAddress, buffer, Scancode, ref addresses);
                    }
                    if (address == (long)m.BaseAddress + (long)m.RegionSize)
                        break;
                    address = (long)m.BaseAddress + (long)m.RegionSize;
                    //Console.Out.WriteLine(address.ToString() + "/" + MaxAddress.ToString());
                } while (address <= MaxAddress);

            }
        }

        private void BoyerAlgo(IntPtr baseAddress, byte[] memoryBrick, string pattern, ref List<IntPtr> addresses)
        {
            int offSet = 0;
            string[] aob = pattern.Split(' ');
            List<int> bytesPos = new List<int>();

            for (int i = 0; i < aob.Length; i++)
                if (aob[i] != "??")
                    bytesPos.Add(i);

            if (bytesPos.Count != 0)
                while ((offSet = Array.IndexOf(memoryBrick, (byte)Convert.ToInt32(aob[bytesPos[0]], 16), offSet)) != -1)
                {
                    if (bytesPos.Count > 1)
                        for (int i = 1; i < bytesPos.Count; i++)
                        {
                            if (memoryBrick.Length <= offSet + pattern.Length
                                || (byte)Convert.ToInt32(aob[bytesPos[i]], 16)
                                != memoryBrick[(offSet - bytesPos[0]) + bytesPos[i]])
                                break;

                            if (i == bytesPos.Count - 1)
                                if (aob[0] == "??")
                                    addresses.Add(baseAddress + (offSet - bytesPos[0]));
                                else addresses.Add(baseAddress + offSet);
                        }
                    else
                        addresses.Add(baseAddress + (offSet - bytesPos[0]));
                    offSet++;
                }
            else
                for (int i = 0; i < memoryBrick.Length; i++)
                    addresses.Add(baseAddress + i);
        }

        public void OpenProcessid(int Pid)
        {
            isbit64 = Is64Bit(Process.GetProcessById(Pid));
            processhandle = OpenProcess(Process.GetProcessById(Pid), ProcessAccessFlags.All);

            Console.WriteLine(isbit64);
        }

        public bool WriteAOB(string Replacecode)
        {
            string[] Replace = convertaobtohex(Replacecode);
            byte[] buffer = new byte[Replace.Length];
            IntPtr Bytesread = IntPtr.Zero;
            foreach (IntPtr ChangeAddress in addresses)
            {
                ReadProcessMemory(processhandle, ChangeAddress, buffer, buffer.Length, out Bytesread);
                for (int i = 0; i < Replace.Count(); i++)
                {
                    if (Replace[i] != "XX")
                    {
                        buffer[i] = byte.Parse(Replace[i]);
                    }
                }
                WriteProcessMemory(processhandle, ChangeAddress, buffer, buffer.Length, out Bytesread);
            }
            if (addresses.Count > 0)
            {
                return true;

            }
            else
            {
                return false;
            }

        }

        private string[] convertaobtohex(string sd)
        {
            string[] BytesTo;
            int h = -1;
            sd = sd.TrimStart(' ');
            sd = sd.TrimEnd(' ');


            string[] hexValuesSplit = sd.Split(' ');

            BytesTo = new string[hexValuesSplit.Length];
            foreach (String hex in hexValuesSplit)
            {
                if (hex.Length > 0)
                {
                    h = h + 1;
                    if (hex != "??")
                    {
                        // Convert the number expressed in base-16 to an integer.
                        int value = Convert.ToInt32(hex, 16);
                        string value2 = value.ToString();
                        BytesTo.SetValue(value2, h);
                    }
                    else
                    {
                        BytesTo.SetValue("XX", h);

                    }
                }

            }
            return BytesTo;

        }


    }
}

Patrice T

"сканирование занимает много времени, около 2 минут, и начальные значения, такие как 20,2 c, 2d и т. д. идти быстрее."
Какой размер памяти и паттерн ?
Есть образец рисунка ?

ShakalX

низкое сканирование

частный недействительными методе button2_click(объект отправителя, EventArgs в электронной)
{
строка Scan1Aob = ("?? 00 00 00 FF FF FF ff 00 E1 F5 05 00 00 00 00 01");
строка Scan2Aob = ("11 00 00 00 FF FF FF ff 00 E1 F5 05 00 00 00 00 01");

кнопка 2.Текст = "10%";
Приложение.Функция doevents();
Aobscan.ReadAOB(Scan1Aob);
кнопка 2.Текст = "80%";
Приложение.Функция doevents();
если (Aobscan.WriteAOB(Scan2Aob))
{
кнопка 2.Text = "ВКЛ.";
Система.Средства массовой информации.SystemSounds.Звуковой сигнал.Играть();
}
еще
{
Система.Средства массовой информации.SystemSounds.Hand.Play();
Ящик для сообщений.Show("OPS-ERROR");
кнопка 2.Text = "выкл.";
}
}


нормальное сканирование
частный недействительными button4_Click(объект отправителя, EventArgs в электронной)
{
строка Scan1Aob = ("02 00 00 00 00 00 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 ?? ?? 00 00 ?? ?? 00 00 ?? ?? 00 00 00 00 00 00 ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01");
строка Scan2Aob = ("02 00 00 00 00 00 00 00 ?? ?? 8F F3 12 03 00 00 ?? ?? ?? ?? ?? ?? 00 00 ?? ?? 00 00 ?? ?? 00 00 ?? ?? 00 00 00 00 00 00 ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01");

button4.Текст = "10%";
Приложение.Функция doevents();
Aobscan.ReadAOB(Scan1Aob);
button4.Текст = "80%";
Приложение.Функция doevents();
если (Aobscan.WriteAOB(Scan2Aob))
{
PauseResumeProcess.ResumeProcess(пид);
button4.Text = "ВКЛ.";
Система.Средства массовой информации.SystemSounds.Звуковой сигнал.Играть();
}
еще
{
PauseResumeProcess.ResumeProcess(пид);
Система.Средства массовой информации.SystemSounds.Hand.Play();
Ящик для сообщений.Show("OPS-ERROR");
button4.Text = "выкл.";
}
}

Patrice T

Воспользуйся Улучшить вопрос чтобы обновить ваш вопрос.
Чтобы каждый мог обратить внимание на эту информацию.

1 Ответов

Рейтинг:
0

Patrice T

private void BoyerAlgo(IntPtr baseAddress, byte[] memoryBrick, string pattern, ref List<IntPtr> addresses)

Одна из ваших проблем скорости заключается в том, что вы ищете шестнадцатеричный шаблон в массиве байтов. Это означает, что вы постоянно конвертируете в шестнадцатеричную систему счисления и обратно, это происходит медленно.
Тот факт, что паттерн может иметь подстановочные знаки, также серьезно замедляет алгоритм Бойермура. без очень тщательного обновления алгоритма это еще один источник замедления.

Подстановочные знаки делают ваш шаблон более похожим на регулярное выражение для двоичных строк и шестнадцатеричных шаблонов.
Патологический паттерн вроде этого:
string Scan1Aob = ("02 00 00 00 00 00 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ??");

это будет настоящий кошмар.