Перейти к содержанию

Очень быстрый сканер сигнатур на C#


Рекомендуемые сообщения

Всем привет. Возможно кто-нибудь уже видел этот сканер сигнатур, реализованный на си шарпе.

 

В нем используется алгоритм Boyer–Moore–Horspool и он сканирует весь процесс.

Ссылка на википедию: https://en.wikipedia.org/wiki/Boyer–Moore–Horspool_algorithm

За счет этого алгоритма, этот сканер сигнатур работает довольно шустро.

 

Я очень много времени уделил на гугл (поиск сканера сигнатур на c#), пересмотрел большое количество видеоуроков и разобрал множество реализаций (поиск по модулям, поиск всего процесса и т. д.). И этот сканер сигнатур оказался самый быстрый и мощный.

 

В чем проблема: Хотелось бы добавить к этому сканеру функцию FindPattern (поиск сигнатуры с "неопределенными" байтами(опкодами). Пример: 8B 0C ?? ?? 3A 00 21 ??).

 

Вот сама функция сравнения сигнатуры с буффером (вот тут нужно, что-то изменить, чтобы сделать FindPattern).

 

byte[] sIn - это буффер для поиска.

byte[] sFor - это сигнатура.

 

Сколько бы я не пробовал, дополнить сканер этой функцией у меня не получается. Я очень был бы признателен, если кто-нибудь поможет мне разобраться с этим.

 

Вызывать функцию поиска сигнатуры вот так:

Вывести найденный адрес, можно в label:

 

label1.Text = string.Format("0x{0:X6}", Address);

XWKkss7C8hU.jpg

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows.Forms;using System.Diagnostics;using System.Runtime.InteropServices;namespace HackMemory         //Название вашего проекта!!!{public class AOBScan{//ReadProcessMemory[DllImport("kernel32.dll")]protected static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, uint size, int lpNumberOfBytesRead);//VirtualQueryEx[DllImport("kernel32.dll")]protected static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, int dwLength);[StructLayout(LayoutKind.Sequential)]protected struct MEMORY_BASIC_INFORMATION{public IntPtr BaseAddress;public IntPtr AllocationBase;public uint AllocationProtect;public uint RegionSize;public uint State;public uint Protect;public uint Type;}protected List MemoryRegion { get; set; } protected void MemInfo(IntPtr pHandle){IntPtr Addy = new IntPtr();while (true){MEMORY_BASIC_INFORMATION MemInfo = new MEMORY_BASIC_INFORMATION();int MemDump = VirtualQueryEx(pHandle, Addy, out MemInfo, Marshal.SizeOf(MemInfo));if (MemDump == 0) break;if ((MemInfo.State & 0x1000) != 0 && (MemInfo.Protect & 0x100) == 0)MemoryRegion.Add(MemInfo);Addy = new IntPtr(MemInfo.BaseAddress.ToInt32() + (int)MemInfo.RegionSize);}} protected IntPtr Scan(byte[] sIn, byte[] sFor){int[] sBytes = new int[256]; int Pool = 0;int End = sFor.Length - 1;for (int i = 0; i < 256; i++)sBytes[i] = sFor.Length;for (int i = 0; i < End; i++)sBytes[sFor[i]] = End - i;while (Pool <= sIn.Length - sFor.Length){for (int i = End; sIn[Pool + i] == sFor[i]; i--)if (i == 0) return new IntPtr(Pool);Pool += sBytes[sIn[Pool + End]];}return IntPtr.Zero;} public IntPtr AobScan(byte[] Pattern, IntPtr handle){MemoryRegion = new List();MemInfo(handle);//сюда записываем handle процессаfor (int i = 0; i < MemoryRegion.Count; i++){byte[] buff = new byte[MemoryRegion[i].RegionSize];ReadProcessMemory(handle, MemoryRegion[i].BaseAddress, buff, MemoryRegion[i].RegionSize, 0);IntPtr Result = Scan(buff, Pattern);if (Result != IntPtr.Zero)return new IntPtr(MemoryRegion[i].BaseAddress.ToInt32() + Result.ToInt32());}return IntPtr.Zero;}}}
protected IntPtr Scan(byte[] sIn, byte[] sFor){int[] sBytes = new int[256]; int Pool = 0;int End = sFor.Length - 1;for (int i = 0; i < 256; i++)sBytes[i] = sFor.Length;for (int i = 0; i < End; i++)sBytes[sFor[i]] = End - i;while (Pool <= sIn.Length - sFor.Length){for (int i = End; sIn[Pool + i] == sFor[i]; i--)if (i == 0) return new IntPtr(Pool);Pool += sBytes[sIn[Pool + End]];}return IntPtr.Zero;}
AOBScan aobscan = new AOBScan();      [color=#008000]//ссылка на класс[/color]int Address;                                               [color=#008000]//найденный адрес[/color]int pID = 666;                                            [color=#008000]//индификатор процесса[/color] IntPtr handle = OpenProcess(0x001F0FFF, false, pID);Address = (int)aobscan.AobScan(new byte[] { 0x00, 0x8B, 0x4A, 0x24, 0x85, 0xC0, 0x0F, 0x84 }, handle);
Изменено пользователем NullAlex
  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

Привет

Вот сама функция сравнения сигнатуры с буффером (вот тут нужно, что-то изменить, чтобы сделать FindPattern).

Думаю все просто

Address = (int)aobscan.AobScan(new byte[] { 0x00, 0x8B, 0x4A, 0x24, 0x85, 0xC0, 0x0F, 0x84 }, "xx?x?xxx", handle); // "xx?x?xxx" это маскаpublic IntPtr AobScan(byte[] Pattern, string mask, IntPtr handle){   ...   IntPtr Result = Scan(buff, Patternб mask); //Передаем маску   ...}protected IntPtr Scan(byte[] sIn, byte[] sFor, string mask){   //for (int i = End; sIn[Pool + i] == sFor[i]; i--) тут булеан выводим в отдельный метод.   for (int i = End; equal(sIn[Pool + i], sFor[i], mask, i); i--) // как то так.}bool equal(byte sIn, byte sFor, string mask, int maskNumber){   Дальше я думаю сообразишь, если нет то попробую помочь дальше, просто времени мало}
  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

Хорошо , что ты ответил , я тут с такой шнягой столкнулся 

va994RZlkao.jpg

Ну наверно так

 

protected List<MEMORY_BASIC_INFORMATION> MemoryRegion { get; set; }
  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

Хорошо было бы ещё исходник дать ...

http://pastebin.com/wmBT5QWT

Привет

Думаю все просто

Address = (int)aobscan.AobScan(new byte[] { 0x00, 0x8B, 0x4A, 0x24, 0x85, 0xC0, 0x0F, 0x84 }, "xx?x?xxx", handle); // "xx?x?xxx" это маскаpublic IntPtr AobScan(byte[] Pattern, string mask, IntPtr handle){   ...   IntPtr Result = Scan(buff, Patternб mask); //Передаем маску   ...}protected IntPtr Scan(byte[] sIn, byte[] sFor, string mask){   //for (int i = End; sIn[Pool + i] == sFor[i]; i--) тут булеан выводим в отдельный метод.   for (int i = End; equal(sIn[Pool + i], sFor[i], mask, i); i--) // как то так.}bool equal(byte sIn, byte sFor, string mask, int maskNumber){   Дальше я думаю сообразишь, если нет то попробую помочь дальше, просто времени мало}
Привет. Спасибо за ответ. Но к сожалению, я так и не понял вашу идею полностью.

Я пытался модернизировать код таким способом:

protected IntPtr Scan(byte[] sIn, byte[] sFor){int[] sBytes = new int[256]; int Pool = 0;int End = sFor.Length - 1;for (int i = 0; i < 256; i++)sBytes[i] = sFor.Length;for (int i = 0; i < End; i++)sBytes[sFor[i]] = End - i;while (Pool <= sIn.Length - sFor.Length){for (int i = End; sIn[Pool + i] == sFor[i] | sFor[i] == 0xFF; i--)// Если (смещение + длина сигнатуры равна i-евому байту сигнатуры) или (i-евый байт сигнатуры равен -1),то цикл вычитаетсяif (i == 0) return new IntPtr(Pool);Pool += sBytes[sIn[Pool + End]];}return IntPtr.Zero;}

Но сигнатуру таким способом не находит. Я пробовал и копаться в откладчике c#, но так и не понял в чем проблема.

NullAlex: Любой код должен быть обрамлен тегом кода. Это неизменное правило не только нашего форума, но и всех остальных. Подробнее - в FAQ

Изменено пользователем NullAlex
Ссылка на комментарий
Поделиться на другие сайты

Если что вот оно

З.Ы. Мне кажется не фига не быстрый это... Хотя особо не проверял

using System;using System.Collections.Generic;using System.Linq;using System.Runtime.InteropServices;using System.Text;namespace temp1{    class AOBScan    {        [DllImport("kernel32.dll")]        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        }        //ReadProcessMemory        [DllImport("kernel32.dll")]        protected static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, uint size, int lpNumberOfBytesRead);        //VirtualQueryEx        [DllImport("kernel32.dll")]        protected static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, int dwLength);        [StructLayout(LayoutKind.Sequential)]        protected struct MEMORY_BASIC_INFORMATION        {            public IntPtr BaseAddress;            public IntPtr AllocationBase;            public uint AllocationProtect;            public uint RegionSize;            public uint State;            public uint Protect;            public uint Type;        }        protected List<MEMORY_BASIC_INFORMATION> MemoryRegion { get; set; }        protected void MemInfo(IntPtr pHandle)        {            IntPtr Addy = new IntPtr();            while (true)            {                MEMORY_BASIC_INFORMATION MemInfo = new MEMORY_BASIC_INFORMATION();                int MemDump = VirtualQueryEx(pHandle, Addy, out MemInfo, Marshal.SizeOf(MemInfo));                if (MemDump == 0) break;                if ((MemInfo.State & 0x1000) != 0 && (MemInfo.Protect & 0x100) == 0)                    MemoryRegion.Add(MemInfo);                Addy = new IntPtr(MemInfo.BaseAddress.ToInt32() + (int)MemInfo.RegionSize);            }        }        protected IntPtr Scan_withOutMask(byte[] sIn, byte[] sFor)        {            int[] sBytes = new int[256]; int Pool = 0;            int End = sFor.Length - 1;            for (int i = 0; i < 256; i++)                sBytes[i] = sFor.Length;            for (int i = 0; i < End; i++)                sBytes[sFor[i]] = End - i;            while (Pool <= sIn.Length - sFor.Length)            {                for (int i = End; sIn[Pool + i] == sFor[i]; i--)                    if (i == 0) return new IntPtr(Pool);                Pool += sBytes[sIn[Pool + End]];            }            return IntPtr.Zero;        }        protected IntPtr Scan_withMask(byte[] sIn, byte[] sFor, bool[] mask)        {            int[] sBytes = new int[256]; int Pool = 0;            int End = sFor.Length - 1;            for (int i = 0; i < 256; i++)                sBytes[i] = sFor.Length;            for (int i = 0; i < End; i++)                sBytes[sFor[i]] = End - i;            while (Pool <= sIn.Length - sFor.Length)            {                for (int i = End; equal(sIn[Pool + i], sFor[i], mask, i); i--)                    if (i == 0) return new IntPtr(Pool);                Pool += sBytes[sIn[Pool + End]];            }            return IntPtr.Zero;        }        bool equal(byte sIn, byte sFor, bool[] mask, int maskNumber)        {            if (mask[maskNumber])            {                return true;            }            else if(sIn == sFor)            {                return true;            }            return false;        }        /// <summary>        /// Поиск по байтам. Если маски нету то, там где "mask" пишем null        /// </summary>        /// <param name="Pattern"></param>        /// <param name="mask">Маска или null</param>        /// <param name="handle"></param>        /// <returns></returns>        public IntPtr AobScan(byte[] Pattern, string mask, IntPtr handle)        {            MemoryRegion = new List<MEMORY_BASIC_INFORMATION>();            MemInfo(handle);//сюда записываем handle процесса            if (string.IsNullOrEmpty(mask)) // если маски нету            {                for (int i = 0; i < MemoryRegion.Count; i++)                {                    byte[] buff = new byte[MemoryRegion[i].RegionSize];                    ReadProcessMemory(handle, MemoryRegion[i].BaseAddress, buff, MemoryRegion[i].RegionSize, 0);                    IntPtr Result = Scan_withOutMask(buff, Pattern);                    if (Result != IntPtr.Zero)                        return new IntPtr(MemoryRegion[i].BaseAddress.ToInt32() + Result.ToInt32());                }                            }            else            {                bool[] maskBool = new bool[mask.Length/2];                for (int i = 0; i <= mask.Length - 2; i += 2)                {                    maskBool[i/2] = mask.Substring(i, 2) == "xx" ? true : false;                }                for (int i = 0; i < MemoryRegion.Count; i++)                {                    byte[] buff = new byte[MemoryRegion[i].RegionSize];                    ReadProcessMemory(handle, MemoryRegion[i].BaseAddress, buff, MemoryRegion[i].RegionSize, 0);                    IntPtr Result = Scan_withMask(buff, Pattern, maskBool);                    if (Result != IntPtr.Zero)                        return new IntPtr(MemoryRegion[i].BaseAddress.ToInt32() + Result.ToInt32());                }            }            return IntPtr.Zero;        }    }}
   AOBScan aobscan = new AOBScan();   int address;   int pID = 4180;   IntPtr handle = AOBScan.OpenProcess(AOBScan.ProcessAccessFlags.All, false, pID);   address = (int)aobscan.AobScan(new byte[] { 0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x8B, 0x45, 0x08, 0x85, 0xC0, 0x74, 0x0F, 0x50, 0x6A, 0x00, 0xFF, 0x35, 0x08, 0x30, 0x88, 0x76, 0xFF, 0x15, 0x2C, 0x40, 0x88, 0x76, 0x8B, 0x45, 0x0C, 0x85, 0xC0 }, "8Bxxxx8Bxx8Bxxxx85xx74xxxx6AxxFFxxxxxxxxxxFFxxxxxxxxxx8Bxxxx85xx", handle); или   address = (int)aobscan.AobScan(new byte[] { 0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x8B, 0x45, 0x08, 0x85, 0xC0, 0x74, 0x0F, 0x50, 0x6A, 0x00, 0xFF, 0x35, 0x08, 0x30, 0x88, 0x76, 0xFF, 0x15, 0x2C, 0x40, 0x88, 0x76, 0x8B, 0x45, 0x0C, 0x85, 0xC0 }, null, handle);   если нету маски
  • Плюс 2
Ссылка на комментарий
Поделиться на другие сайты

for (int i = End; sIn[Pool + i] == sFor[i] | sFor[i] == 0xFF; i--)// Если (смещение + длина сигнатуры равна i-евому байту сигнатуры) или (i-евый байт сигнатуры равен -1),то цикл вычитается
Но сигнатуру таким способом не находит. Я пробовал и копаться в откладчике c#, но так и не понял в чем проблема.

 

Где тут по меняющем сигнатурам (по маскам) поиск так и не понял, или идея в другом?... не понятно

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

Где тут по меняющем сигнатурам (по маскам) поиск так и не понял, или идея в другом?... не понятно

Тут идея не в поиске по маске, а в том, что если байт в сигнатуре равен -1(0xFF), то это и есть "неопределенный" байт, который может меняться.

Пример:

Address = (int)aobscan.AobScan(new byte[] { 0xFF, 0x8B, 0x4A, 0x24, 0xFF, 0xC0, 0x0F, 0xFF });//  {??, 8B, 4A, 24, ??, C0, 0F, ??}

Изначально код был такой:

for (int i = End; sIn[Pool + i] == sFor[i]; i--) 

Я изменил на вот это:

for (int i = End; sIn[Pool + i] == sFor[i] | sFor[i] == 0xFF; i--) 

Но такой способ не работает.

З.Ы. Мне кажется не фига не быстрый это... Хотя особо не проверял

 

Насчет скорости, я проверил около 4 алгоритмов сравнения буффера с сигнатурой. И этот оказался самый быстрый (возможно, есть способ шустрее, но я такой не наблюдал).

 

Например, если подставить алгоритм, который написал Keng, в этот сканер, то поиск сигнатуры может занять очень долгое время (у меня поиск занимал около 20 секунд, и то адрес находился в начале памяти. А если адрес лежал бы в памяти  0x7FFF1000 ?, то вобще бы минут 5 сканировал).

 

А в алгоритме Boyer–Moore–Horspool, сканирование этой же сигнатуры, происходило меньше одной секунды.

 

Так что, все кто говорит, что c# медленный и из-за этого сканирует долго, то они не правы.

Конечно же c# уступает по скорости c++, но все же главную роль играет быстрый (правильный) алгоритм сравнения.

 

Алгоритм Кенга:

 

Алгоритм Boyer–Moore–Horspool:

 

Если интересна производительность, можешь подставить алгоритм keng'a или другой в этот сканер и увидишь результат.

Если что вот оно

Огромное спасибо вам за помощь (принцип понял), код проверил, все отлично работает. Переделаю под себя.

using System;using System.Collections.Generic;using System.Linq;using System.Runtime.InteropServices;using System.Text;namespace temp1{    class AOBScan    {        [DllImport("kernel32.dll")]        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        }        //ReadProcessMemory        [DllImport("kernel32.dll")]        protected static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, uint size, int lpNumberOfBytesRead);        //VirtualQueryEx        [DllImport("kernel32.dll")]        protected static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, int dwLength);        [StructLayout(LayoutKind.Sequential)]        protected struct MEMORY_BASIC_INFORMATION        {            public IntPtr BaseAddress;            public IntPtr AllocationBase;            public uint AllocationProtect;            public uint RegionSize;            public uint State;            public uint Protect;            public uint Type;        }        protected List<MEMORY_BASIC_INFORMATION> MemoryRegion { get; set; }        protected void MemInfo(IntPtr pHandle)        {            IntPtr Addy = new IntPtr();            while (true)            {                MEMORY_BASIC_INFORMATION MemInfo = new MEMORY_BASIC_INFORMATION();                int MemDump = VirtualQueryEx(pHandle, Addy, out MemInfo, Marshal.SizeOf(MemInfo));                if (MemDump == 0) break;                if ((MemInfo.State & 0x1000) != 0 && (MemInfo.Protect & 0x100) == 0)                    MemoryRegion.Add(MemInfo);                Addy = new IntPtr(MemInfo.BaseAddress.ToInt32() + (int)MemInfo.RegionSize);            }        }        protected IntPtr Scan_withOutMask(byte[] sIn, byte[] sFor)        {            int[] sBytes = new int[256]; int Pool = 0;            int End = sFor.Length - 1;            for (int i = 0; i < 256; i++)                sBytes[i] = sFor.Length;            for (int i = 0; i < End; i++)                sBytes[sFor[i]] = End - i;            while (Pool <= sIn.Length - sFor.Length)            {                for (int i = End; sIn[Pool + i] == sFor[i]; i--)                    if (i == 0) return new IntPtr(Pool);                Pool += sBytes[sIn[Pool + End]];            }            return IntPtr.Zero;        }        protected IntPtr Scan_withMask(byte[] sIn, byte[] sFor, bool[] mask)        {            int[] sBytes = new int[256]; int Pool = 0;            int End = sFor.Length - 1;            for (int i = 0; i < 256; i++)                sBytes[i] = sFor.Length;            for (int i = 0; i < End; i++)                sBytes[sFor[i]] = End - i;            while (Pool <= sIn.Length - sFor.Length)            {                for (int i = End; equal(sIn[Pool + i], sFor[i], mask, i); i--)                    if (i == 0) return new IntPtr(Pool);                Pool += sBytes[sIn[Pool + End]];            }            return IntPtr.Zero;        }        bool equal(byte sIn, byte sFor, bool[] mask, int maskNumber)        {            if (mask[maskNumber])            {                return true;            }            else if(sIn == sFor)            {                return true;            }            return false;        }        /// <summary>        /// Поиск по байтам. Если маски нету то, там где "mask" пишем null        /// </summary>        /// <param name="Pattern"></param>        /// <param name="mask">Маска или null</param>        /// <param name="handle"></param>        /// <returns></returns>        public IntPtr AobScan(byte[] Pattern, string mask, IntPtr handle)        {            MemoryRegion = new List<MEMORY_BASIC_INFORMATION>();            MemInfo(handle);//сюда записываем handle процесса            if (string.IsNullOrEmpty(mask)) // если маски нету            {                for (int i = 0; i < MemoryRegion.Count; i++)                {                    byte[] buff = new byte[MemoryRegion[i].RegionSize];                    ReadProcessMemory(handle, MemoryRegion[i].BaseAddress, buff, MemoryRegion[i].RegionSize, 0);                    IntPtr Result = Scan_withOutMask(buff, Pattern);                    if (Result != IntPtr.Zero)                        return new IntPtr(MemoryRegion[i].BaseAddress.ToInt32() + Result.ToInt32());                }                            }            else            {                bool[] maskBool = new bool[mask.Length/2];                for (int i = 0; i <= mask.Length - 2; i += 2)                {                    maskBool[i/2] = mask.Substring(i, 2) == "xx" ? true : false;                }                for (int i = 0; i < MemoryRegion.Count; i++)                {                    byte[] buff = new byte[MemoryRegion[i].RegionSize];                    ReadProcessMemory(handle, MemoryRegion[i].BaseAddress, buff, MemoryRegion[i].RegionSize, 0);                    IntPtr Result = Scan_withMask(buff, Pattern, maskBool);                    if (Result != IntPtr.Zero)                        return new IntPtr(MemoryRegion[i].BaseAddress.ToInt32() + Result.ToInt32());                }            }            return IntPtr.Zero;        }    }}

   AOBScan aobscan = new AOBScan();   int address;   int pID = 4180;   IntPtr handle = AOBScan.OpenProcess(AOBScan.ProcessAccessFlags.All, false, pID);   address = (int)aobscan.AobScan(new byte[] { 0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x8B, 0x45, 0x08, 0x85, 0xC0, 0x74, 0x0F, 0x50, 0x6A, 0x00, 0xFF, 0x35, 0x08, 0x30, 0x88, 0x76, 0xFF, 0x15, 0x2C, 0x40, 0x88, 0x76, 0x8B, 0x45, 0x0C, 0x85, 0xC0 }, "8Bxxxx8Bxx8Bxxxx85xx74xxxx6AxxFFxxxxxxxxxxFFxxxxxxxxxx8Bxxxx85xx", handle); или   address = (int)aobscan.AobScan(new byte[] { 0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x8B, 0x45, 0x08, 0x85, 0xC0, 0x74, 0x0F, 0x50, 0x6A, 0x00, 0xFF, 0x35, 0x08, 0x30, 0x88, 0x76, 0xFF, 0x15, 0x2C, 0x40, 0x88, 0x76, 0x8B, 0x45, 0x0C, 0x85, 0xC0 }, null, handle);   если нету маски

З.Ы. Мне кажется не фига не быстрый это... Хотя особо не проверял

protected int FindPatternKeng(byte[] buffer, byte[] pattern)        {            if (ProcessСonnection.handle != IntPtr.Zero)            {                var counter = 0;                if (pattern.Length <= buffer.Length)                {                    for (var i = 0; i < (buffer.Length); i++)                    {                        if (buffer[i] == pattern[0] | pattern[0] == 0xFF)                        {                            for (var j = 0; j < pattern.Length && i + j < buffer.Length; j++)                            {                                if (buffer[(i + j)] == pattern[j] | pattern[j] == 0xFF)                                {                                    counter++;                                    if (counter == pattern.Length)                                    {                                        var result = i;                                        return result;                                    }                                }                                else                                {                                    counter = 0;                                }                            }                        }                    }                  }            }            return 0;        } 
protected IntPtr Scan(byte[] sIn, byte[] sFor)        {            int[] sBytes = new int[256]; int Pool = 0;            int End = sFor.Length - 1;            for (int i = 0; i < 256; i++)                sBytes[i] = sFor.Length;            for (int i = 0; i < End; i++)                sBytes[sFor[i]] = End - i;            while (Pool <= sIn.Length - sFor.Length)            {                for (int i = End; sIn[Pool + i] == sFor[i]; i--)//                    if (i == 0) return new IntPtr(Pool);                Pool += sBytes[sIn[Pool + End]];            }            return IntPtr.Zero;        } 
Изменено пользователем EvilByte
Ссылка на комментарий
Поделиться на другие сайты

EvilByte , ну ясен пень , что с# уступает с++ по скорости   :) А сканер с алгоритмом Boyer–Moore–Horspool реально быстрый )

Изменено пользователем afro228offical
Ссылка на комментарий
Поделиться на другие сайты

Тут идея не в поиске по маске, а в том, что если байт в сигнатуре равен -1(0xFF), то это и есть "неопределенный" байт, который может меняться.

 

Согласен что 0xFFы может быт меняется, но и другие тоже может меняться. Не зря же придумали маску.

Ссылка на комментарий
Поделиться на другие сайты

Согласен что 0xFFы может быт меняется, но и другие тоже может меняться. Не зря же придумали маску.

 

Может ты немного не правильно меня понял? 

Допустим есть сигнатура  с байтами 8B 3C 00 24 10. К примеру, я точно знаю, что байт 24 "неопределенный".

Я заменяю его на FF. То есть сигнатура теперь выглядит так: 8B 3C 00 FF 10.

 

И поэтому я переделал код на вот этот:

 

Я изменил на вот это: for (int i = End; sIn[Pool + i] == sFor | sFor == 0xFF; i--)  Но такой способ не работает.

 

То есть, если есть байты в сигнатуре со значением 0xFF(-1), то цикл вычитается (не важно, совпал ли байт из буффера с байтом из сигнатуры).

 

Я просто заменил вопросик на 0xFF

 

Кстати насчет маски есть один вопрос.

 

Я правильно переделал код? Чтобы в маске было не два символа "xx", а один "x".

 

(исходный код) Для двух символов "xx":

bool[] maskBool = new bool[mask.Length / 2];                for (int i = 0; i <= mask.Length - 2; i += 2)                {                    maskBool[i / 2] = mask.Substring(i, 2) == "xx" ? true : false;                }

(переделанный код) Для одного символа "x":

bool[] maskBool = new bool[mask.Length];                for (int i = 0; i <= mask.Length - 1; i++)                {                    maskBool[i] = mask.Substring(i, 1) == "x" ? true : false;                }
  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.