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

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


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

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

 

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

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

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 выходят видео

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

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

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

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-ом случае, переменная была закеширована в файле, и загрузилась при загрузке интерфейса игры.

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

  • Xipho закрыл тема
Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...

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

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