CHBS

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

17 сообщений в этой теме

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

 

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

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

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

0

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


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

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

0

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


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

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

0

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


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

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

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

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

 

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

 

0

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


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

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

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

 

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

0

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


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

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

 

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

0

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


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

 

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

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

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

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

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

0

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


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

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

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

crOUI6tgRpKPo2gUzhdZyqtUOUnp2k.png

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

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

 

0

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


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

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

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

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;
                                }
                            }
                        }
                    }
                }
            } 

 

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

0

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


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

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

0

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


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

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

 

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

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

0

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


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

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

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

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

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

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

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

 

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

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


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

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

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

 

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

 

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

XQo4FtyHZvXTfS6uSArVM3TwV67zQE.png

 

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

 

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

dJkjdWaD33Unv6Hc67R79WiQMj7Gro.png

 

0

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


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

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

 

 

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

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

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


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

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

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

0

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


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

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

 

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

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

 

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

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

0

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


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

 

 

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

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

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

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

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

0

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


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