CHBS

Прошу помощи с поиском сигнатур\значений через RPM C#

Recommended Posts

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

 

Имеется код - > 

Скрытый текст

int Counter;
int CapBytes;
int ProcessModuleSize;
int ProcessBaseAddress;	
int[] SearchValueByPattern;
byte[] SearchValueByLinear;
byte[] MemoryBuffer;

       
Process ProcessData  = Process.GetProcessesByName("myprocess")[0]; // Поиск процесса
ProcessBaseAddress   = (int)ProcessData.MainModule.BaseAddress;    // Базовый адресс процесса
ProcessModuleSize    = ProcessData.MainModule.ModuleMemorySize;    // Размер модуля процесса
MemoryBuffer         = new byte[ProcessModuleSize];                // Инициализириую массив байтов размером модуля процесса 
SearchValueByPattern = new int[] {-1, -1, 0x89, 0xC9, 0x32};       // Сигнатура для поиска адресса
SearchValueByLinear  = BitConverter.GetBytes(967110984321231);     // Значение для поиска адресса


ReadProcessMemory((int)ProcessData.Handle, ProcessBaseAddress, MemoryBuffer, MemoryBuffer.Length, ref CapBytes);

if (MemoryBuffer.Length > SearchValueByLinear.Length)
{
  for (int i = 0; i < MemoryBuffer.Length - SearchValueByLinear.Length; i++)
  {
    if (MemoryBuffer[i] == SearchValueByLinear[0])
    {
      if(MemoryBuffer[i+1] == SearchValueByLinear[1])
      {
        if (MemoryBuffer[i + 2] == SearchValueByLinear[2])
        {
          // Своими словами, тут я пытаюсь перебирать каждый байт из сохраненной
          // Да я знаю что можно использовать циклы, я делал это что бы понять где прерывается цепочка 
		  // Что бы понять в чем проблемма, в итоге я не понял в чем проблема, потому что уже на value[2] происходит обрыв
          // Т.е дает нам понять что SearchValueByLinear[2](цифра 7), не была найдена в такой последовательности.
        }
      }
    }
  }
}

 

Так же есть код с двумя циклами на перебор, по сигнатуре, но я не особо хочу его рассматривать, так как искоемое значение задается в игре т.е там есть интепретируемый язык LUA, я пытаюсь найти значения собственной переменной в игре, но ВАЖНАЯ ДЕТАЛЬ в игре переменная обусловим ее как Variable = 967110984321231, она является в игре number, но в Cheat Engine ищется исключетльно по double, я научил программу читать значение с конкретного адресса, т.е я нахожу адресс, кормлю его софту, а софт выдает мне double значение, с которым я далее манипулирую, и поставил себе задачу это дело автоматизиорвать, и пытаюсь найти в памяти региона, это значение [967110984321231] путем перебора каждого байта.
  
Прошу не гнать меня ссаными тряпками, не кидаться тапками, так как я очень давно не программировал на C# где то год, и в целом забил на кодинг на пол года из-за обстоятельств.
  
Прошу помочь мне, объяснить что в моем коде не так как с технической стороны, так и (теоретической?), что бы вы изменили, и для чего нужен оператор ref в ReadProcessMemory я тоже не могу понять.
  
Очень надеюсь на вашу помощь, GameHackLab'овцы

 

//Не по теме

Я давно не посещал этот форум, а где такие люди как Keng?

Канал засох, Keng не объявляется нигде, видео не выходят, только на GameHackLab на youtube выходят видео

Поделиться сообщением


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

Думаю, стоит переменную представлять не как переменную, а как массив байтов. В таком случае будет видно, как именно сравниваются байты. Есть подозрение, что у тебя порядок байт неправильный, ведь в памяти значения хранятся в перевернутом виде, надо это помнить.

Поделиться сообщением


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

Если переменная  "Variable = 967110984321231"  не является статической, то почему ты ее ищешь в главном модуле процесса?)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
17 час назад, Xipho сказал:

Думаю, стоит переменную представлять не как переменную, а как массив байтов. В таком случае будет видно, как именно сравниваются байты. Есть подозрение, что у тебя порядок байт неправильный, ведь в памяти значения хранятся в перевернутом виде, надо это помнить.

Немного не понял первую часть ответа, ведь   BitConverter.GetBytes(967110984321231) - возвращает массив байтов, и переменная представляется собственно как массив байтов.

А со вторым я сделал через System.Text.Encoding.UTF8.GetBytes("967110984321231"), проверил выдачу на decimal выдается теперь нормально то что нужно, но байты через 0 идут, т.е 57 00 54 00 и так далее.

 

Лучше подскажите мне как сделать поиск значения как в CE, так как значение в игре у меня уникальное, и выдает всегда только 1 адресс

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
11 час назад, Dino сказал:

Если переменная  "Variable = 967110984321231"  не является статической, то почему ты ее ищешь в главном модуле процесса?)

Это я вообще не понял, а где мне ее тогда искать, можно ответы какие то более развертнутые и конкретные?

 

Я ищу данное значение в главном модуле игры, т.к как это значение всегда хранится в главном модуле игры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
11 минуту назад, CHBS сказал:

Лучше подскажите мне как сделать поиск значения как в CE

 

Разве исходники CE закрыты стали и нельзя посмотреть как там реализован поиск?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Только что, partoftheworlD сказал:

 

Разве исходники CE закрыты стали и нельзя посмотреть как там реализован поиск?

Разве я сказал что они закрыты?

CE написан отчасти на Delphi, но у меня даже на пк валяется проект на Delphi, который ищет double значение в памяти, мне нужно найти значение в памяти через C#, что уже является лично для меня проблеммой потому что я не знаю как искать значение в C# по его типу, сказывается заброс кодинга, я сейчас пытаюсь найти значение через System.Text.Encoding.UTF8.GetBytes("967110984321231");

Принцип поиска понятен изначально, непонятна реализация на том или инном языке.

В Delphi мне будет проще реализовать поиск точного значения с помощью готовых наработок, но тут C# и я не знаю каким методом сейчас ищу я и я могу только предпологать что если я ищу через UTF8.GetBytes, то вероятно я ищу строковое значение в памяти, а не double в котором у меня лежит переменная в игре

Поделиться сообщением


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

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

Скрытый текст

crOUI6tgRpKPo2gUzhdZyqtUOUnp2k.png

Посмотрите на базовые адреса в моей программе(они верны, цикл на Process.Modules, и посмотрите на базовый адрес в Cheat Engine, еще такая же лабуда с размером модулей, в моей программе все отличается, брал так же из Process.MemoryModuleSize

Т.е C.E. Показывает базовый адрес 0x3F7E3000 а в софте минимальный базовый адрес 0x5D2B0000

 

Поделиться сообщением


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

Я в отчаянии, я уже иду по всем модулям и их базовым адресам

Скрытый текст

int Counter = 0;
int CapBytes = 0;
int ProcessModuleSize;
int ProcessBaseAddress;
byte[] SearchValueByPattern;
byte[] SearchValueByLinear;
byte[] MemoryBuffer;


Process ProcessData = Process.GetProcessesByName("prc")[0]; // Поиск процесса
ProcessBaseAddress = (int)ProcessData.MainModule.BaseAddress;         // Базовый адресс процесса
ProcessModuleSize = ProcessData.MainModule.ModuleMemorySize;    // Размер модуля процесса
var x = ProcessData.Modules[0].ModuleMemorySize;
MemoryBuffer = new byte[ProcessModuleSize];                // Инициализириую массив байтов размером модуля процесса 
SearchValueByPattern = new byte[] { 0x41, 0x0A, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00 };       // Сигнатура для поиска адресса
SearchValueByLinear = System.Text.Encoding.UTF8.GetBytes("967110984321231");     // Значение для поиска адресса


for (int g = 0; g < ProcessData.Modules.Count; g++)
            {
                ProcessBaseAddress = (int)ProcessData.Modules[g].BaseAddress;
                MemoryBuffer = new byte[ProcessData.Modules[g].ModuleMemorySize];
                ReadProcessMemory((int)ProcessData.Handle, ProcessBaseAddress, MemoryBuffer, MemoryBuffer.Length, ref CapBytes);
                if (MemoryBuffer.Length >= SearchValueByPattern.Length)
                {
                    for (int i = 0; i < MemoryBuffer.Length - SearchValueByPattern.Length; i++)
                    {
                        if (MemoryBuffer == SearchValueByPattern[0])
                        {
                            for (int j = 0; j < SearchValueByPattern.Length; j++)
                            {
                                if (MemoryBuffer[i + j] == SearchValueByPattern[j])
                                {
                                    Counter++;
                                    if (Counter == SearchValueByPattern.Length)
                                    {
                                        MessageBox.Show("0x" + Convert.ToString(ProcessBaseAddress + i, 16).ToUpper());
                                        //return ProcessBaseAddress + i;
                                    }
                                }
                                else
                                {
                                    Counter = 0;
                                }
                            }
                        }
                    }
                }
            } 

 

И все равно ничего...

Поделиться сообщением


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

Если надо получать информацию о всех модулях, то стоит использовать NtQueryInformationProcess, если только 32 битных то CreateToolhelp32Snapshot, если же модули правильно определяет, то скорее всего Text.Encoding.UTF8.GetBytes не правильно переводит значение. И мне кажется стоило бы использовать VirtualQueryEx, чтобы читать байты из памяти.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
10 час назад, CHBS сказал:

Это я вообще не понял, а где мне ее тогда искать, можно ответы какие то более развертнутые и конкретные?

 

Я ищу данное значение в главном модуле игры, т.к как это значение всегда хранится в главном модуле игры.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
4 часа назад, partoftheworlD сказал:

Если надо получать информацию о всех модулях, то стоит использовать NtQueryInformationProcess, если только 32 битных то CreateToolhelp32Snapshot, если же модули правильно определяет, то скорее всего Text.Encoding.UTF8.GetBytes не правильно переводит значение. И мне кажется стоило бы использовать VirtualQueryEx, чтобы читать байты из памяти.

Уважаемый, вы в ту ветку пишете?

Мы тут на C# пишем, а не плюсах, какие снапшоты?

А какая разница между VirtualQueryEx и ReadProcessMemory, если я дамп модуля снимаю?

И посмотрите мой последний пост, там уже алгоритм поиска другой, я пытаюсь перейти на него исключив Text.GetBytes

А перейти на чистое байтовое сравнение.

 

Изменено пользователем CHBS

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
3 часа назад, Dino сказал:

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

Интепретируемый язык LUA в игре, да, переменная собственно создается динамически и грузится в память.

 

3F65C840 вот адресс в памяти, в котором хранится мое значение в double

 

Скрытый текст

XQo4FtyHZvXTfS6uSArVM3TwV67zQE.png

 

И вот вам в Double представлении 

 

Скрытый текст

dJkjdWaD33Unv6Hc67R79WiQMj7Gro.png

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
56 минут назад, CHBS сказал:

да, переменная собственно создается динамически

 

 

ну вот, сам ответил на свой вопрос, почему тогда в г модуле ищешь?)

Изменено пользователем Dino

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
9 часов назад, Dino сказал:

ну вот, сам ответил на свой вопрос, почему тогда в г модуле ищешь?)

Потому что переменная находится в главном модуле как-бы, а во вторых, если бы ты посмотрел последний код, то я уже ищу ее во всех модулях, и не нахожу, вот в чем дело.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
13 часа назад, CHBS сказал:

Потому что переменная находится в главном модуле как-бы

 

13 часа назад, CHBS сказал:

я уже ищу ее во всех модулях, и не нахожу, вот в чем дело.

 

:D учи матчасть, чтобы в дальнейшем динамически созданные переменные в памяти модулей не искать 

https://ru.wikipedia.org/wiki/Куча_(память)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
17 час назад, Dino сказал:

 

 

:D учи матчасть, чтобы в дальнейшем динамически созданные переменные в памяти модулей не искать 

https://ru.wikipedia.org/wiki/Куча_(память)

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

Ну да ладно, проблему я решил использовав VirtualQueryEx.

Тему можно закрывать.
И да, моя переменная найдена была в 2-ух модулях, просто в 2-ом случае, переменная была закеширована в файле, и загрузилась при загрузке интерфейса игры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Гость
Эта тема закрыта для публикации сообщений.