2017-01-01 4 views
1

Я работаю над небольшим проектом - я пытаюсь создать программу на C#, которая будет читать HP персонажа из игры «League Of Legends».Как читать память процесса с базовым адресом и указателями

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

CE

Теперь я хотел бы сделать программу, которая будет делать то же самое. Я нашел класс, который я мог бы прочитать поплавок из памяти, с именем VAMemory. Я копировал статический адрес из Cheatengine в свою программу и получил значение HP, как я и хотел.

VAMemory vam = new VAMemory("League Of Legends"); 
vam.ReadFloat((IntPtr)adress); 

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

Я нашел подобный question и ответ сказал:

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

В этом вопросе у asker было 2 смещений, но у меня есть 5?

Используется это, чтобы получить базовый адрес:

Process GameProcess = Process.GetProcessesByName("League Of Legends").FirstOrDefault(); 
IntPtr BaseAddress = GameProcess.MainModule.BaseAddress; 

Итак, я создал это уродство:

try 
     { 


      Process GameProcess = Process.GetProcessesByName("League Of Legends").FirstOrDefault(); 
      VAMemory vam = new VAMemory("League Of Legends"); 

      IntPtr BaseAddress = GameProcess.MainModule.BaseAddress; 
      float Basevalue = vam.ReadFloat((IntPtr)BaseAddress); 
      abase.Text = BaseAddress.ToString(); 
      vbase.Text = Basevalue.ToString(); 

      IntPtr Basefirst = IntPtr.Add(BaseAddress, 0x658); 
      float Basefirstvalue = vam.ReadFloat((IntPtr)Basefirst); 
      a1.Text = Basefirst.ToString(); 
      v1.Text = Basefirstvalue.ToString(); 

      IntPtr Basesecond = IntPtr.Add(IntPtrFromFloat(Basefirstvalue), 0x150); 
      float Basesecondvalue = vam.ReadFloat((IntPtr)Basefirstvalue); 
      a2.Text = Basesecond.ToString(); 
      v2.Text = Basesecondvalue.ToString(); 

      IntPtr Basethird = IntPtr.Add(IntPtrFromFloat(Basesecondvalue), 0x0); 
      float Basethirdvalue = vam.ReadFloat((IntPtr)Basethird); 
      a3.Text = Basethird.ToString(); 
      v3.Text = Basethirdvalue.ToString(); 

      IntPtr Basefourth = IntPtr.Add(IntPtrFromFloat(Basethirdvalue), 0x44); 
      float Basefourthvalue = vam.ReadFloat((IntPtr)Basefourth); 
      a4.Text = Basefourth.ToString(); 
      v4.Text = Basefourthvalue.ToString(); 

      IntPtr Basefifth = IntPtr.Add(IntPtrFromFloat(Basefourthvalue), 0x36c); 
      float Basefifthvalue = vam.ReadFloat((IntPtr)Basefirst); 
      a5.Text = Basefifth.ToString(); 
      v5.Text = Basefifthvalue.ToString(); 


     } 
     catch (Exception ex) 
     { MessageBox.Show(ex.ToString()); } 
    } 
    static IntPtr IntPtrFromFloat(float f) 
    { 
     unsafe 
     { 
      return (*(IntPtr*)&f); 
     } 
    } 
  • Он принимает базовый адрес, добавляет первое смещение, [считывает значение , добавляет следующий] x5 и затем считывает последний адрес, но, к сожалению, его значение равно 0.

Вместо красивых номеров в Cheatengine я получил следующее: numbers Я давно занимаюсь этой штукой, но я до сих пор не понимаю, что я делаю неправильно?

Как получить динамический адрес с базового адреса и Pointers?

UPDATE:

Я сейчас, используя новые указатели: new pointers

И я изменил код в соответствии с замечаниями, Он использует Readint32() вместо readfloat() и выглядит гораздо чище:

Process GameProcess = Process.GetProcessesByName("League Of Legends").FirstOrDefault(); 
      VAMemory vam = new VAMemory("League Of Legends"); 

      IntPtr BaseAddress = GameProcess.MainModule.BaseAddress; 

      IntPtr Base1 = IntPtr.Add((IntPtr)vam.ReadInt32(BaseAddress), 0x58); 

      IntPtr Base2 = IntPtr.Add((IntPtr)vam.ReadInt32(Base1), 0xC0); 

      IntPtr Base3 = IntPtr.Add((IntPtr)vam.ReadInt32(Base2), 0x118); 

      IntPtr Base4 = IntPtr.Add((IntPtr)vam.ReadInt32(Base3), 0x39C); 

      IntPtr Base5 = IntPtr.Add((IntPtr)vam.ReadInt32(Base4), 0xBC); 

      float value = vam.ReadFloat(Base4); 

      Lvalue.Text = value.ToString(); 

НО, он все еще не работает. Я запускал Cheatengine одновременно, и он получил правильный адрес и значение, но моя программа получила следующее: debug , а окончательное значение равно 0, оно должно быть 528.

+0

Не помещайте код в качестве ссылок на Pastebin, ставьте его в вопрос. Людям не нужно нажимать внешнюю ссылку, чтобы полностью понять вашу проблему. –

+0

Как вы говорите, ваша проблема заключается в том, что вы вызываете 'vam.ReadFloat', на каждом уровне вы должны только вызывать ReadFloat один раз в конце, промежуточные уровни должны использовать' vam.ReadInt32 ('чтобы получить следующий уровень вниз Каждый уровень должен выглядеть так: «IntPtr Basesecond = IntPtr.Add ((IntPtr) vam.ReadInt32 (Basefirst), 0x150);' –

+0

'IntPtr Basethird = IntPtr.Add ((IntPtr) vam.ReadInt32 (Basesecond), 0x0); ',' IntPtr Basefourth = IntPtr.Add ((IntPtr) vam.ReadInt32 (Basethird), 0x44); ',' IntPtr Basefifth = IntPtr.Add ((IntPtr) vam.ReadInt32 (Basefourth), 0x36c); ',' float Basefifthvalue = vam.ReadFloat (Basefifth); ' –

ответ

1

Мой оригинал комментарий в ответ:

Ваша проблема, которую вы называете vam.ReadFloat, на каждом уровне, вы должны называть только ReadFloat один раз в конце концов, между уровнями нужно использовать vam.ReadInt32(, чтобы получить следующий слой вниз.

Process GameProcess = Process.GetProcessesByName("League Of Legends").FirstOrDefault(); 

VAMemory vam = new VAMemory("League Of Legends"); 

IntPtr Base = GameProcess.MainModule.BaseAddress; 
IntPtr BaseFirst = IntPtr.Add((IntPtr)vam.ReadInt32(Base), 0x658); 
IntPtr Basesecond = IntPtr.Add((IntPtr)vam.ReadInt32(Basefirst), 0x150); 
IntPtr Basethird = IntPtr.Add((IntPtr)vam.ReadInt32(Basesecond), 0x0); 
IntPtr Basefourth = IntPtr.Add((IntPtr)vam.ReadInt32(Basethird), 0x44); 
IntPtr Basefifth = IntPtr.Add((IntPtr)vam.ReadInt32(Basefourth), 0x36c); 
float Basefifthvalue = vam.ReadFloat(Basefifth); 

Lvalue.Text = Basefifthvalue.ToString(); 

Проблема с обновленным ответом является у вас есть опечатка.

float value = vam.ReadFloat(Base4); 

должен быть

float value = vam.ReadFloat(Base5); 

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