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

alexmarch

Пользователи
  • Постов

    23
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные alexmarch

  1. Короче парни, если кто еще читает.
    Получилось то что хотел. Накопипастел со всего инета.
    Работает на x64 сканирует 32х приложения и находит мои данные в пределах выше 4 гб.
    И что самое приятное, он пожалуй самый быстрый.(хотя по модулю может чуть быстрее)
    И очень простой и маленький код
    Спасибо кенгу за его видо уроки и Laziz за вектор поиска
    вот готовый код

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using TradingAssisetent;using System.Diagnostics;using System.Runtime.InteropServices;namespace TradingAssisetent{    public class sigScan    {        [DllImport("kernel32.dll")]        public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, uint size, int lpNumberOfBytesRead);        [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;  // Указатель на базовый адрес диапазона страниц, выделенных VirtualAlloc функции. Страница, на которую указывает BaseAddress элемента, содержащаяся в данном диапазоне распределения.            public uint AllocationProtect; // Опция Защита памяти, когда область была первоначально выделено. Этот элемент может быть одним из постоянных защиты памяти или 0, если абонент не имеет доступа.            public uint RegionSize;        // Размер области, начиная с базового адреса, в которой все страницы имеют идентичные атрибуты, в байтах.            public uint State;            public uint Protect;            public uint Type;        }        List<MEMORY_BASIC_INFORMATION> MemReg { get; set; }                                          // Структура карты памяти MemReg        public void MemInfo(IntPtr pHandle)                                                          // В место того что бы каждый раз читать ReadProcessMemory, создадим свою карту памяти.                                                                                                     // Свалим все, в одну кучу(MemReg) и будем в нем искать свою сигнатуру         {                                                                                            // Функция VirtualQueryEx возвращает информацию о диапазоне страниц, виртуального адресного пространства указанного процесса.            IntPtr Addy = new IntPtr();                                                              // hProcess: THandle;                      //дескриптор процесса            while (true)                                                                             // lpAddress: Pointer;                     //адрес начала региона памяти             {                                                                                        // var lpBuffer: TMemoryBasicInformation;  //буфер для получения информации                MEMORY_BASIC_INFORMATION MemInfo = new MEMORY_BASIC_INFORMATION();                   // dwLength: DWORD                         //размер буфера                int MemDump = VirtualQueryEx(pHandle, Addy, out  MemInfo, Marshal.SizeOf(MemInfo));  // Вызовим VirtualQueryEx, получим базовый адрес процесса и размер региона в структуру MEMORY_BASIC_INFORMATION                if (MemDump == 0) break;                                                             // Выход из цыкла                 if ((MemInfo.State & 0x1000) != 0 && (MemInfo.Protect & 0x100) == 0)                 // Если флаг региона  0x1000, 0x100 известные флаги (MEM_COMMIT, MEM_RESERVE, MEM_FREE, MEM_PRIVATE, MEM_MAPPED, or MEM_IMAGE).                    MemReg.Add(MemInfo);                                                             // Добавим в MemReg                                 Addy = new IntPtr(MemInfo.BaseAddress.ToInt32() + (int)MemInfo.RegionSize);                            }        }               public 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(string ProcessName, byte[] Pattern)        {            Process[] P = Process.GetProcessesByName(ProcessName);  // Получим в p процес;            if (P.Length == 0) return IntPtr.Zero;                  // Если процесс не найден, вернем 0;            MemReg = new List<MEMORY_BASIC_INFORMATION>();          // Создадим маcсив структуры -> MEMORY_BASIC_INFORMATION;            MemInfo(P[0].Handle);                                   // Получим  хендл;            for (int i = 0; i < MemReg.Count; i++)                  // Перечисляем пока есть страницы            {                byte[] buff = new byte[MemReg[i].RegionSize ];       // Буфер                ReadProcessMemory(P[0].Handle, MemReg[i].BaseAddress, buff, MemReg[i].RegionSize, 0);                IntPtr Result = _Scan(buff, Pattern);                if (Result != IntPtr.Zero)                    return new IntPtr(MemReg[i].BaseAddress.ToInt32() + Result.ToInt32());            }            return IntPtr.Zero;        }    } } 
     private void button3_Click(object sender, EventArgs e)        {            sigScan sigScan = new sigScan();                       textBox1.Text = "";            string hexValues = textBox2.Text;   //берем значение с поисковой строки            byte[] toFind = System.Text.Encoding.UTF8.GetBytes(hexValues);   //перводим стринг в байт            IntPtr MyAddress = sigScan.AobScan("EliteDangerous32", toFind);            textBox1.Text = textBox1.Text + MyAddress.ToString();        } 
    • Плюс 2
  2. 33ef052868ed6e9cb29902c2d64d98c3.png

    Почему данные храниться вне диапазона модуля?

    Здорово, сам нашел причину и никто даже не догадывался в теме.

    Да потому что я объясняю через Ж :))))
  3. Короче. Я тут реально много флуда нафлудил :)

    Но вдруг кому то это тоже будет полезным разобраться.

    теперь я 100% могу сказать почему я не находил свои данные

    у меня 64 bit Win 8 bg оперативка, когда память не сильно загружена игра писала данные в область user-mode, а это как известно от  от 0x0000000  до 0x7FFFFFFF

    как только память была "подзабита" игра писала "выше" и я уже не могу там нечего найти.

    Вот и весь ответ.

    Keng

    Очень хочу разобраться до конца, потому как твой способ мне видеться для этой задачи самый шустрый и компактнее.

    Еще раз

    почему в диапазон адресов   между (int)m.BaseAddress и m.ModuleMemorySize не попадают те данные которые хранит игра?

    почему данные моего модуля храниться вне этого диапазона?

    foreach (ProcessModule m in p.Modules) // Получаем модули связанные с процесом                        {                            if (m.ModuleName == nameProc + ".exe") // Имя модуля должно совпадать с именим exe-файла                            {                                startAddress = (int)m.BaseAddress; // Возвращает адрес в памяти, куда был загружен модуль.                                sizeToAllocate = m.ModuleMemorySize; // Возвращает размер модуля                                lblProgress.Text = string.Format("{0}/{1}", startAddress, sizeToAllocate);                                return 1;                                                            }                        }
    • Плюс 3
  4. Ты можешь это сам проверить  ;)

    для этого нужно свою структуру

     

      

    protected struct MEMORY_BASIC_INFORMATION_x64

     

    Да я на шарпе 2 неделе...

    Мда хакеры уже пошли нет те :-P  

     

    а что за переменный "MEM_IMAGE"?

     

    Медленный - имелся введу в широком смысле. Я конечно знаю разницу между двумя способами. Кенг показал один способ поиска и тоже корректный, но для узкого круга поиска.

    вот тут подробно http://nmdsoft.blogspot.ru/2010/10/memorybasicinformation.html

     

    1) Указывать флаг  не PAGE_READWRITE, а например PAGE_EXECUTE_READWRITE. Во всяком случае флаги нужно подбирать в соответствии с тем что и где ищем. Если это код, то ищем в памяти где права на код. Если это данные перезаписываемые, то и ищем по флагам соответствующим. Подробно флаги расписаны в MSDN

                    // если это кусок памяти доступен

     

    Так? да гораздо быстрее

    1) Указывать флаг  не PAGE_READWRITE, а например PAGE_EXECUTE_READWRITE.

    по PAGE_EXECUTE_READWRITE нечего не находит

                    if (mem_basic_info.Protect == AllocationProtectEnum.PAGE_READWRITE && mem_basic_info.State == StateEnum.MEM_COMMIT);{}
  5. С Флагами поэксперементирую

    а что за переменный "MEM_IMAGE"?

     

     

    я пока не все доделал

     

    public enum TypeEnum : uint{MEM_IMAGE = 0x1000000,MEM_MAPPED = 0x40000,MEM_PRIVATE = 0x20000}public struct MEMORY_BASIC_INFORMATION{public uint BaseAddress;public IntPtr AllocationBase;public AllocationProtectEnum AllocationProtect;public uint RegionSize;public StateEnum State;public AllocationProtectEnum Protect;public TypeEnum lType;}
  6. вот у меня как раз тот случай когда по имени модуля я не могу найти свои данные

    Если

    VirtualQueryEx(processHandle, proc_min_address, out mem_basic_info, 28);
    то мы получаем в результате всю память игры. И статическую и динамическую. 

     

    всем понятно что статическая память нужна для переменных выделяемых заранее, для хранения и (.text  и т.д.), в отличие от динамической она выделяется после того  был запущен модуль, в которой переменные  будут выделены в кучу (динамическое пространство-адрес. прим. Кенг об этом говорил). Стек динамически выделяется и будет находиться за пределами сегментов памяти модуля. 

    короче можно сделать проверку и дело пойдет быстрее

    VirtualQueryEx(processHandle, proc_min_address, out mem_basic_info, 28);if (mem_basic_info.Type == MEM_IMAGE) {}
    работает ли это с адресами x64?
  7. Прогресс на лицо. Норм.

    спасибо

    поиск медленный - потому что не С++.

    поиск медленный не потому что C#, а потому что, во втором случаи, мы сканируем всю память User-Mode. Но тогда получается сканер сигнатур Кенга не работает корректно.

    меня в частности вот эти две строки интересуют.

    startAddress = (int)m.BaseAddress; // Берем базовый адрес
    sizeToAllocate = m.ModuleMemorySize; // Размер модуля

    Кенг просто берет имя модуля по названию игры, хотя данные могут хранится в другом месте, как в моем случаи

  8. Виртуальное адресное пространство процесса или как найти свою сигнатуру.
    1. В 32-битных системах процессор может сгенерировать 32-битный адрес. Это означает, что каждому процессу выделяется диапазон виртуальных адресов от 0x00000000 до 0xFFFFFFFF
    Эти 4 Гб адресов система делит примерно пополам, и для кода и данных пользовательского режима отводятся 2 Гб в нижней части памяти. Если быть более точным, то речь идет об виртуальных адресах, начиная с 0x00010000 и конечная 0x07FFEFFFF
    vm1.png
    Источник тут >>
    2. В большинстве современных операционных систем виртуальная память организуется с помощью страничной адресации. Оперативная память делится на страницы: области памяти фиксированной длины (например, 4096 байт), которые являются минимальной единицей выделяемой памяти (то есть даже запрос на 1 байт от приложения приведёт к выделению ему страницы памяти).
    Источник тут >>
     
    3.Так же, как и в Win32, размер страницы на платформе x64 равен 4 Кб. Первые 64 Кб адресного пространства никогда не проецируются на физическую память, поэтому младший допустимый адрес - 0x10000. В отличие от Win32 системные DLL по умолчанию не загружаются по адресу в верхней части адресного пространства пользовательского режима. Вместо этого они загружаются после 4 Гб, обычно по адресам, близким к 0x7FF00000000.
    Источник тут >>
    Так как нам правильно сканировать память чужого процесса на C#?
    Windows запуская любой процесс, выделят память из кучи, стека и областей - однако Windows не будет выделять "весь блок" памяти целиком. Она пытается выделить любой свободной кусок памяти, доступной для так называемой User-Mode – таким образом выделенная память не будет непрерывной. Так же, Windows не скажет нам диапазон адресов, где мы можем найти данные программы. Таким образом, нам придется сканировать почти каждый возможный адрес ( с помощью GetSystemInfo ()) и проверять,  принадлежит ли он к нашему процессу (с VirtualQueryEx ()): если это произойдет, будем читаем значения с помощью (ReadProcessMemory () )

     

    код взял тут

    using System;using System.Diagnostics;using System.IO;using System.Runtime.InteropServices;namespace MemoryScanner{    class Program    {        // REQUIRED CONSTS        const int PROCESS_QUERY_INFORMATION = 0x0400;        const int MEM_COMMIT = 0x00001000;        const int PAGE_READWRITE = 0x04;        const int PROCESS_WM_READ = 0x0010;        // REQUIRED METHODS        [DllImport("kernel32.dll")]        public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);        [DllImport("kernel32.dll")]        public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);        [DllImport("kernel32.dll")]        static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);        [DllImport("kernel32.dll", SetLastError=true)]        static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);        // REQUIRED STRUCTS        public struct MEMORY_BASIC_INFORMATION        {            public int BaseAddress;            public int AllocationBase;            public int AllocationProtect;            public int RegionSize;            public int State;            public int Protect;            public int lType;        }        public struct SYSTEM_INFO        {            public ushort processorArchitecture;            ushort reserved;            public uint pageSize;            public IntPtr minimumApplicationAddress;            public IntPtr maximumApplicationAddress;            public IntPtr activeProcessorMask;            public uint numberOfProcessors;            public uint processorType;            public uint allocationGranularity;            public ushort processorLevel;            public ushort processorRevision;        }                // finally...        public static void Main()        {            // getting minimum & maximum address            SYSTEM_INFO sys_info = new SYSTEM_INFO();            GetSystemInfo(out sys_info);              IntPtr proc_min_address = sys_info.minimumApplicationAddress;            IntPtr proc_max_address = sys_info.maximumApplicationAddress;            // saving the values as long ints so I won't have to do a lot of casts later            long proc_min_address_l = (long)proc_min_address;            long proc_max_address_l = (long)proc_max_address;            // notepad better be runnin'            Process process = Process.GetProcessesByName("notepad")[0];            // opening the process with desired access level            IntPtr processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_WM_READ, false, process.Id);            StreamWriter sw = new StreamWriter("dump.txt");            // this will store any information we get from VirtualQueryEx()            MEMORY_BASIC_INFORMATION mem_basic_info = new MEMORY_BASIC_INFORMATION();            int bytesRead = 0;  // number of bytes read with ReadProcessMemory            while (proc_min_address_l < proc_max_address_l)            {                // 28 = sizeof(MEMORY_BASIC_INFORMATION)                VirtualQueryEx(processHandle, proc_min_address, out mem_basic_info, 28);                                // if this memory chunk is accessible                if (mem_basic_info.Protect == PAGE_READWRITE && mem_basic_info.State == MEM_COMMIT)                {                    byte[] buffer = new byte[mem_basic_info.RegionSize];                    // read everything in the buffer above                    ReadProcessMemory((int)processHandle, mem_basic_info.BaseAddress, buffer, mem_basic_info.RegionSize, ref bytesRead);                    // then output this in the file                    for (int i = 0; i < mem_basic_info.RegionSize; i++)                        sw.WriteLine("0x{0} : {1}", (mem_basic_info.BaseAddress+i).ToString("X"), (char)buffer[i]);                }                // move to the next memory chunk                proc_min_address_l += mem_basic_info.RegionSize;                proc_min_address = new IntPtr(proc_min_address_l);            }            sw.Close();            Console.ReadLine();        }    }}
  9. Да нашел!!!!

    УРА действительно в конце пробел был.  o_0

    По модулям поиск не находит!

    Но поиск очень медленный

    В любом случаи спасибо, это хоть какое то решение.

    Но почему  тогда в поиске по модулям в буфере оказывается не то!

    Зачем его тогда вообще использовать, если в нем нет нужных значений!

  10. Тип: массив байт

    По поводу сигнатуры: пробелы просто убери, и вставь в программу.

    3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D227574662D38223F3E0A3C646174613E3C696E76656E746F72793E 

    Ругается благим матом, говорит непонятный символ 

  11. Может просто CE ищет сигнатуру в модуле, а ты в исполняемом файле или наоборот? :)

    может быть, я уже не знаю куда посмотреть все по 100 перепроверил.

    вот код как я ищу

     

     

    попробуйте этим поискать, потом скажете. находит ли вообше.

    http://forum.gamehacklab.ru/topic/3567-videourok-kenga-poisk-signatury-signaturu/?p=26679

    ща попробую

    Тип поиска массив байт? мне в int перевести надо?

    у меня HEX или стринг!

    3C 3F 78 6D 6C 20 76 65 72 73 69 6F 6E 3D 22 31 2E 30 22 20 65 6E 63 6F 64 69 6E 67 3D 22 75 74 66 2D 38 22 3F 3E 0A 3C 64 61 74 61 3E 3C 69 6E 76 65 6E 74 6F 72 79 3E <?xml version="1.0" encoding="utf-8"?><data><inventory>
     public int GetProcessID(string nameProc) //Поиск Id процесса        {            foreach (Process proc in Process.GetProcessesByName(nameProc))            {                pID = proc.Id; // запомним ID процесса                return proc.Id;            }            return -1;        }        public int FindModulesAddress(string nameProc) // Поиск по модулям         {            if (pID !=0) // если ID процесса найден            {                foreach (var p in Process.GetProcesses())                {                     if (p.Id == pID ) // Ищем процеес с нашим ID                    {                        foreach (ProcessModule m in p.Modules) // Находим базовый модуль                        {                            if (m.ModuleName == nameProc + ".exe") // Имя модуля должно совпадать с именим exe-файла                            {                                string srtA = m.BaseAddress.ToString();//Удалить экперемент                                UInt32 Base = (UInt32)m.BaseAddress.ToInt32(); //Удалить экперемент                                startAddress = (int)m.BaseAddress; // Берем базовый адрес                                sizeToAllocate = m.ModuleMemorySize; // Размер модуля                                return 1;                                                            }                        }                    }                }                            }            return -1;        }
  12. Ты хочеш сказат что на ЧитЭнжине находит последвательност байтов(сигнатуру), код каторый на С# не находит так?.

    Просто суть вопроса не могу понять.

    Абсолютно точно. Именно это я и говорю.

  13. Отвечая на твой вопрос: в буфере ее нет.

    Я ищу в памяти набор байт определенной последовательности. Когда нахожу записываю и храню переменной

    Вот твой почти не переделанный код.

    Я все понимаю о чем ты говоришь, что он ищет начало сигнатуры меня это все устраивает, я никак не могу обьяснить что по какой то блин ФАНТАСТИЧЕСКОЙ, ЗАГАДОЧНОЙ, причине в Буффере НЕТ этой сигнатуре, когда как я ее явно, отчетливо, в упор вижу через отладчик! ЧУДО, которое я не могу никак объяснить.

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

            public int FindSignature(string hexValues)        {            hexValues = hexValues.Replace(" ", string.Empty); //Удалим пробелы            //Преобразуем из HEX в DEC16            int[] signature = Enumerable.Range(0, hexValues.Length / 2).Select(x => Convert.ToInt32(hexValues.Substring(x * 2, 2), 16)).ToArray();            //Посик сигнатуры            File.WriteAllBytes(@"C:\buffer.txt", buffer);                      var counter = 0; // обьявляем переменную счетчик             if (signature.Length <= buffer.Length) //Проверим что бы сигнатура была меньше буфера            {                for (var i = 0; i < buffer.Length; i++) //Цыкл гонит по всему массиву                {                    if (buffer[i] == signature[0] | signature[0] == -1) //Если первый символ сигнатуры равен или равен -1, тогда ...                     {                        for (var j = 0; j < signature.Length; j++) //вхождение в сигнатуру                        {                            if (buffer[i + j] == signature[j] | signature[j] == -1) //Если свопадает с сигнатурой или равен -1, тогда ...                            {                                counter++; // Считаем совпадения                                                              if (counter == signature.Length) // Если  сигнатура найдена                                {                                                                      return xmlStart = i + startAddress; //Вернем найденый адрес                                }                            }                            else                            {                                counter = 0;                            }                        }                    }                }            }            return -1;        } 
  14. У меня не стоит задача записи на диск всей памяти. Делал я это от безысходности так как хотел увидеть что хранит в себе buffer.

    buffer если я все правильно вижу хранить массив байт, с который можно  проводить int сравнение в пределах 0 до 255

    Я думал что я неправильно конверчу  свою сигнатуру все проверил там все ОК. потом я понял что что то не так с buffer-ом и поэтому начал его сохранять на диск что бы посмотреть Cheat Engine-ом


    сейчас я так данные сохраняю

    File.WriteAllBytes(@"C:\buffer.txt", buffer);

    Но это не решило проблемы


    могу видео записать 

  15. ты пытаешься скормить массив байт методу, который ждет string?

    Покажи где я пытаюсь это сделать?

     

    то проблема не в моем коде

    Спасибо за твой код все чудесно

    Единственно я его сделал несколько удобнее

     string hexValues = "3C 63 6F 6D 6D 6F 64 69 74 69 65 73 3E 3C 69 74 65 6D 3E 3C 69 64 3E";            hexValues = hexValues.Replace(" ", string.Empty); //Удалим пробелы  //Преобразуем из HEX в DEC16   int[] signature = Enumerable.Range(0, hexValues.Length / 2).Select(x => Convert.ToInt32(hexValues.Substring(x * 2, 2), 16)).ToArray();   //Посик сигнатуры
  16. Keng твой вариант приводит к такому результату

    4D-5A-90-00-03-00-00-00-04-00-00-00-FF-FF

    а должно быть  приблизительно так:

    MZ !This program cannot be run in DOS mode.

    Я прекрасно отдаю себе отчет разницу между string и byte

    Этот наверно подходит File.WriteAllBytes(@"C:\buffer.txt", buffer);

    Если честно я уже все перепробовал и не понимаю на какой стадии ошибка

    Это все твой же код я мучаю по поиску сигнатур

    вот пример

     

    ReadProcessMemory(handle, (IntPtr)startAddress, buffer, sizeToAllocate, out bytesread); //Читаем, с начала адресса, в буфер, весь файл, и заглушка

    тут переменные 

    int startAddress = 0; // Начало файла
    int sizeToAllocate = 0; // Размер файла
    byte[] buffer; // Буфер для записи всей игры из памяти
    и вот когда я ищу свою сигнатуру я не могу ее там найти вот я и решил ее слить на диск и посмотреть в Cheat Engine, вдруг думаю я что то упустил
    так вот в сохраненном buffer тоже нет моей сигнатуры. Если быть точнее есть ее куски но не целиком.
    Я непониманию где БАГ помогите 
  17. Всем привет. 
    читаю из памяти 


    все прекрасно работает. lpBuffer пополняться от 0 до 255
    Хочу все это сохранить в файл на диск 
    сохраняю так:

     


    Теперь в чем вопрос когда смотрю в память процесса через Cheat Engine я нахожу свою сигнатуру "3C 2F 69 74 65 6D 3E 3C 2F 63 6F 6D 6D 6F 64 69 74 69 65 73 3E 3C 2F 64 61 74 61 3E"
    но когда просматриваю в сохранённом файле на диске ее там нет.
    В чем может быть причина?


    как сделать дамп памяти запущенного процесса правильно?

    static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,[Out] byte[]lpBuffer,int dwSize,        out int lpNumberOfBytesRead);
     protected bool SaveData(byte[] Data)        {            BinaryWriter Writer = null;            string Name = @"C:\buffer.txt";            try            {                // Create a new stream to write to the file                Writer = new BinaryWriter(File.OpenWrite(Name));                // Writer raw data                                Writer.Write(Data);                Writer.Flush();                Writer.Close();            }            catch            {                //...                return false;            }            return true;        }
  18. Код рабочий но почему то не находит сигнатуру. Находит из 73 только 30 байт

    хотя в читэнжине вижу все

    34006fb6ef62ea644043d2b291549243.jpg

    может неверный адрес вхождения?

    NullAlex: если-бы мне платили за каждый тег кода и спойлера хотя-бы по рублю...
    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Diagnostics;using System.Runtime.InteropServices;namespace TradingAssisetent{    class MemoryRead    {        const int PROCESS_WM_READ = 0x0010; // флаг на чтение        //ReadProcessMemory        [DllImport("kernel32.dll", SetLastError = true)]        static extern bool ReadProcessMemory(          IntPtr hProcess,          IntPtr lpBaseAddress,          [Out] byte[] lpBuffer,          int dwSize,          out int lpNumberOfBytesRead         );        //OpenProcess // Flag = All = 0x001F0FFF        [DllImport("kernel32.dll")]        public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);        // CloseHandle        [DllImport("kernel32.dll", SetLastError = true)]        [return: MarshalAs(UnmanagedType.Bool)]        static extern bool CloseHandle(IntPtr hObject);        [StructLayout(LayoutKind.Sequential)]        public struct MEMORY_BASIC_INFORMATION        {            public IntPtr BaseAddress;            public IntPtr AllocationBase;            public uint AllocationProtect;            public IntPtr RegionSize;            public uint State;            public uint Protect;            public uint Type;        }                       // Глобальные переменные        public int pID; // PID процесса        int startAddress = 0; // Начало файла        int sizeToAllocate = 0; // Размер файла        byte[] buffer; // Объявление ссылки на массив                public int GetProcessID(string nameProc) //Поиск Id процесса        {            foreach (Process proc in Process.GetProcessesByName(nameProc))            {                pID = proc.Id; // запомним ID процесса                return proc.Id;            }            return -1;        }        public int FindModulesAddress(string nameProc) // Поиск по модулям        {            if (pID !=0) // если ID процесса найден            {                foreach (var p in Process.GetProcesses())                {                     if (p.Id == pID ) // Ищем процеес с нашим ID                    {                        foreach (ProcessModule m in p.Modules)                         {                            if (m.ModuleName == nameProc + ".exe")                             {                                startAddress = (int)m.BaseAddress; // Берем базовый адрес                                sizeToAllocate = m.ModuleMemorySize; // Размер модуля                                return 1;                                                            }                        }                    }                }                            }            return -1;        }        public int FindSignature() // Поиск по сигнатуре        {                                int[] signature = {0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E,                               0x30, 0x22, 0x20, 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x75, 0x74, 0x66, 0x2D,                              0x38, 0x22, 0x3F, 0x3E, 0x0A, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x3E, 0x3C, 0x69, 0x6E, 0x76, 0x65, 0x6E,                               0x74, 0x6F, 0x72, 0x79, 0x3E, 0x3C, 0x69, 0x74, 0x65, 0x6D, 0x3E, 0x3C, 0x63, 0x6F, 0x6D, 0x6D, 0x6F,                               0x64, 0x69, 0x74, 0x79, 0x3E};                var handle = OpenProcess(PROCESS_WM_READ, false, pID); // ID процесса                if (handle != IntPtr.Zero) // Если хендл не 0, тогда                {                    buffer = new byte[sizeToAllocate]; // Объявляем буфер размером во весь модуль                    int bytesread; // переменная заглушка                    ReadProcessMemory(handle, (IntPtr)startAddress, buffer, sizeToAllocate, out bytesread); //Читаем, с начала адресса, в буфер, весь файл, и заглушка                    CloseHandle(handle); // закрыли хендл                                    var counter = 0; // обьявляем переменную счетчик                     if (signature.Length <= buffer.Length)                    {                        for (var i = 0; i < buffer.Length; i++)                        {                            if (buffer[i] == signature[0] | signature [0] == -1 )                            {                                for ( var j =0;  j < signature.Length; j++)                                {                                    var text = buffer[i + j];                                    if (buffer[i+j]== signature[j] | signature[j] == -1)                                    {                                        counter++;                                        if (counter >=29)                                        { \\максимум было 30 каунтов                                        }                                                                                if (counter == signature.Length)                                        {                                            var result = i + startAddress;                                            return result;                                        }                                    }                                    else                                    {                                        counter = 0;                                    }                                }                            }                        }                    }                }                return -1;             }
  19. Спасибо за ответы. Если следовать логике Keng-a то действия примерно такие. Ставим хук на любой клики мышки и потом выполняем нужные действия.

    Я по наивности своего представления хочу приблизительно следующие Найти адрес в памяти что то типа Button_mouse_Click = False и каждую допустим секунду смотреть сменилось на True или нет?

    Вообще у этой проблемы есть только одно решение? 

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

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

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