Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/30: Рейтинг темы: голосов - 30, средняя оценка - 4.80
107 / 13 / 7
Регистрация: 06.07.2013
Сообщений: 268

Как реализовать поиск в памяти процессов подобно функционалу ArtMoney и Cheat Engine?

20.12.2014, 14:05. Показов 6395. Ответов 10

Студворк — интернет-сервис помощи студентам
Подскажите в какую сторону копать чтобы это реализовать, от сылочек на библиотеки не откажусь. Заранее спасибо.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.12.2014, 14:05
Ответы с готовыми решениями:

Написание сканера памяти наподобие Cheat Engine или ArtMoney
помогите написать сканер памяти на подобии Cheat Engine или ArtMoney. Все сорсы, что нашел не работают. нашел это:...

Программа в Delphi 7 и Cheat Engine, Artmoney
Появилась проблема. Пишу небольшую программу шифрования, но столкнулся с 1 проблемой, при правильном подходе можно узнать код шифровки...

Как осуществить поиск значения в процессе, как в Cheat Engine?
Шурстя несколько дней в поисковике, я натыкался на информацию на то как найти значение по базовому адресу. Если базового адреса нет (то...

10
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
20.12.2014, 14:23
Цитата Сообщение от ATop Посмотреть сообщение
чтобы это реализовать
Реализовать что? Поиск процессов по имени/по ID? Есть пространство имен System.Diagnostics, в нем есть класс Process(), который предоставляет достаточно много функциональности для работы с процессами.
1
107 / 13 / 7
Регистрация: 06.07.2013
Сообщений: 268
20.12.2014, 14:28  [ТС]
Поиск процессов это пару строк кода, мне нужен поиск значение в его памяти, скажем найти золото или количество патронов как умеет ArtMoney.
0
 Аватар для Metall_Version
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
20.12.2014, 16:35
ATop, натив в помощь, в частности метод ReadProcessMemory

Небезопасный код, многоуровневая адресация - каково их назначение
Карта процессов как в ArtMoney
1
 Аватар для Lynatik001
48 / 40 / 15
Регистрация: 28.09.2012
Сообщений: 818
21.12.2014, 02:48
Цитата Сообщение от Metall_Version Посмотреть сообщение
натив в помощь, в частности метод ReadProcessMemory
Для об игр может и сойдет) вот я тоже не помню как всегда находить адрес в памяти например жизней если он не постоянный. Допустим в какой то онлайн игре
1
40 / 40 / 13
Регистрация: 09.07.2014
Сообщений: 116
21.12.2014, 09:04
Цитата Сообщение от Lynatik001 Посмотреть сообщение
Для об игр может и сойдет) вот я тоже не помню как всегда находить адрес в памяти например жизней если он не постоянный. Допустим в какой то онлайн игре
На эти адреса что-то указывает, базовый адрес структуры/класса указывает на значение в нем, на адрес структуры может указывать еще что-то, на это нечто может еще много адресов указывать и так начиная с какого-либо базового статического адреса. Это еще смещением называют.

ТС-у:
Есть такой замечательный метод в ВинАпи
C#
1
public static extern int VirtualQueryEx ( IntPtr hProcess , IntPtr lpAddress , out MEMORY_BASIC_INFORMATION lpBuffer , uint dwLength );
Узнает по любому адресу, базовый адрес его региона (память делится на регионы/страницы/etc.), размер региона, протекты и еще кое какие полезные штуки.

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

Получаешь базовый адрес региона, с ним получаешь размер, копируешь в массив с помощью ReadProcessMemory весь регион памяти.

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

На пинвоке есть все методы с некоторым описанием винАпи.
0
 Аватар для Lynatik001
48 / 40 / 15
Регистрация: 28.09.2012
Сообщений: 818
21.12.2014, 17:11
Цитата Сообщение от Tirenta Посмотреть сообщение
Узнает по любому адресу, базовый адрес его региона (память делится на регионы/страницы/etc.), размер региона, протекты и еще кое какие полезные штуки.
Самый простой поиск выглядит так:
Используешь этот метод на нужном адресе, например начиная с 0x0, (что особо не имеет смысла, но будем брать в учет, что в коде реализован фильтр по участкам памяти в которых ничего нет).
Получаешь базовый адрес региона, с ним получаешь размер, копируешь в массив с помощью ReadProcessMemory весь регион памяти.
Ищешь по массиву нужные байты, значения/опкоды и т.д., потом продолжаешь со следующим регионом который начинается с суммы базового адреса и размера прошлого региона, повторяешь копирование и так до самого конца памяти, например, уже не помню где там конец) Все это в несколько потоков очень быстро можно делать, главное продумать все.
На пинвоке есть все методы с некоторым описанием винАпи.
С памятю почти что не работал дак что смутно представляю как ето бы в коде выглядело. Да и думаю автор тоже не понял
1
40 / 40 / 13
Регистрация: 09.07.2014
Сообщений: 116
21.12.2014, 20:34
Лучший ответ Сообщение было отмечено ATop как решение

Решение

ну смотрите, во первых нужно добавить методы из винАпи, например в отдельный класс, самый минимум это вот
(предварительно нужно добавить using System.Runtime.InteropServices)

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/// <summary>
    /// Набор методов из винАпи
    /// </summary>
    public static class WindowsApi
    {
        /// <summary>
        /// Прочитать массив байт процесса.
        /// </summary>
        /// <param name="hProcess">Handle процесса.</param>
        /// <param name="lpBaseAddress">Базовый адрес, от куда начинать чтение.</param>
        /// <param name="buffer">Выходной буфер куда будет читаться массив байт.</param>
        /// <param name="size">Размер количества читаемых байт.</param>
        /// <param name="lpNumberOfBytesRead">Количество успешно прочитанных байт.</param>
        /// <returns></returns>
        [DllImport ( "kernel32.dll" , SetLastError = true )]
        public static extern Int32 ReadProcessMemory (
            IntPtr hProcess ,
            IntPtr lpBaseAddress ,
            [Out] byte [ ] buffer ,
            UInt32 size ,
            out IntPtr lpNumberOfBytesRead );
 
        /// <summary>
        /// Получить базовую информацию
        /// участка памяти.
        /// </summary>
        /// <param name="hProcess">Handle процесса.</param>
        /// <param name="lpAddress">Адрес в памяти, по которому нужно получить информацию.</param>
        /// <param name="lpBuffer">Выходной буфер, структура базовой информации.</param>
        /// <param name="dwLength">Нипанятна =).</param>
        /// <returns></returns>
        [DllImport ( "kernel32.dll" )]
        public static extern int VirtualQueryEx ( IntPtr hProcess , IntPtr lpAddress , out MEMORY_BASIC_INFORMATION lpBuffer , uint dwLength );
    }
 
    /// <summary>
    /// Базовая информация
    /// нужного участка памяти.
    /// </summary>
    [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;
    }
Теперь нужно просто использовать эти методы, получив Handle окна.
Handle можно получить только с правами администратора, то есть либо запустить студию от админа, либо программу.
Вот небольшой набросок:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
static void Main(string[] args)
        {
            Process [ ] prc = Process.GetProcessesByName ( "chrome" ); //получаем массив процессов с этим именем
            IntPtr handle = Process.GetProcessById ( prc [ 0 ].Id ).Handle; //получаем Handle окна из первого элемента массива
 
            MEMORY_BASIC_INFORMATION mbi; //объявляем структуру для использования
            IntPtr baseAddress = IntPtr.Zero; //адрес в памяти по которому нужно получить размер региона, у меня это ноль для теста.
 
            //Юзаем метод, получаем информацию по региону
            WindowsApi.VirtualQueryEx (
                handle ,
                baseAddress ,
                out mbi , //наша структура
                ( uint ) Marshal.SizeOf ( typeof ( MEMORY_BASIC_INFORMATION ) ) ); // я не понимаю, что это значит :D, но так нужно)
 
            //Тут уже почти все готово, у нас уже есть нужная информация, что бы скопировать регион памяти в массив!
 
            //объявляем массив размером равным размеру региона
            byte [ ] buffer = new byte [ ( int ) mbi.RegionSize ];
            //еще одна переменная, для количества прочитанных байт
            IntPtr countOfReadBytes;
 
            //читаем регион памяти в массив
            WindowsApi.ReadProcessMemory (
                handle ,
                mbi.BaseAddress ,
                buffer ,
                ( uint ) buffer.Length ,
                out countOfReadBytes );
        }
Надеюсь не надо объяснять, как искать по массиву нужные байты, как конвертировать значения в байты и т.д.
1
Эксперт С++
 Аватар для _lunar_
3701 / 2836 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 21
22.12.2014, 00:33
Цитата Сообщение от Tirenta Посмотреть сообщение
Handle можно получить только с правами администратора, то есть либо запустить студию от админа, либо программу.
или воспользоваться функцией OpenProcess с флагом PROCESS_ALL_ACCESS (0x001F0FFF)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static uint pID;
 
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
 
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
 
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
 
void Something()
{
    IntPtr hWnd = FindWindow(null, "window name");
    uint threadID = GetWindowThreadProcessId(hWnd, out pID);
    IntPtr handle = OpenProcess(0x001F0FFF, false, (int)pID);
}
ну или так
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static int pID;
 
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
 
public static void GetProcess(string Name)
{
    Process[] proc = Process.GetProcesses();
    foreach (Process process in proc)
        if (process.ProcessName == Name)
        {
            pID = process.Id;
            return;
        }
    return;
}
 
void Something()
{
    GetProcess("process");
    IntPtr handle = OpenProcess(0x001F0FFF, false, pID);
}
1
22.12.2014, 02:59

Не по теме:

Цитата Сообщение от _lunar_ Посмотреть сообщение
или воспользоваться функцией OpenProcess с флагом PROCESS_ALL_ACCESS
Process.Handle тоже самое, и это не позволит открыть процесс без соответствующих привилегий.

0
Эксперт С++
 Аватар для _lunar_
3701 / 2836 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 21
22.12.2014, 18:51

Не по теме:

Цитата Сообщение от NickoTin Посмотреть сообщение
Process.Handle тоже самое
я знаю, но всё же использовать PInvoke в шарпе мне как то удобнее



Цитата Сообщение от NickoTin Посмотреть сообщение
и это не позволит открыть процесс без соответствующих привилегий
не соглашусь. Работал с памятью программы, использовав флаг PROCESS_ALL_ACCESS, которая требовала привилегии админа. Причём другие флаги давали нужный результат, лишь в том случае, если я запускаю свою программу от имени администратора.
хотя не исключаю, что это были какие-нибудь особенности в купе (ОС, программа и т.п.), которые давали спокойно работать без соответствующих привилегий.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.12.2014, 18:51
Помогаю со студенческими работами здесь

Карта процессов как в ArtMoney
Наверное много людей пользовались подобным обманщиком игр ... Инетересно какими методами можно &quot;выудить&quot; такую инфу для...

Cheat Engine
Есть игра в игре есть текстовое значение, проще говоря я нажимаю на моба выделяется моб и соответственно отображается его имя, ищу текст в...

Delphi Cheat Engine Pointer Offset
Pointer Offset помогите собрать пож) BF3.EXE+B1FD21 5C &lt;offset1 0 &lt;offset2 74 &lt;offset3 22 &lt;offset4

Pointer Scan no results in Cheat Engine
Добрый вечер! Я не нашёл подходящую тему в разделе, поэтому задам вопрос здесь. Я нашёл указатель на нужное мне значение вручную, но...

Что может означать в cheat engine строчка mov [rbx - 000b744], eax
ФедосеевПавел, немного не по теме, но можете помочь с этой строчкой кода в cheat engaine там есть ассемблер, вот что может означать эта...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
Установка Emscripten SDK (emsdk) и CMake на Windows для сборки C и C++ приложений в WebAssembly (Wasm)
8Observer8 30.01.2026
Чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. Система контроля версиями Git. . .
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru