Я работаю над небольшим проектом - я пытаюсь создать программу на C#, которая будет читать HP персонажа из игры «League Of Legends».Как читать память процесса с базовым адресом и указателями
Я провел некоторое исследование и после некоторого времени возился с cheatengine, я получил смещения, которые будут указывать на адрес HP даже после перезагрузки ПК, и я могу успешно читать его каждый раз.
Теперь я хотел бы сделать программу, которая будет делать то же самое. Я нашел класс, который я мог бы прочитать поплавок из памяти, с именем 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 я получил следующее: Я давно занимаюсь этой штукой, но я до сих пор не понимаю, что я делаю неправильно?
Как получить динамический адрес с базового адреса и Pointers?
UPDATE:
Я сейчас, используя новые указатели:
И я изменил код в соответствии с замечаниями, Он использует 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 одновременно, и он получил правильный адрес и значение, но моя программа получила следующее: , а окончательное значение равно 0, оно должно быть 528.
Не помещайте код в качестве ссылок на Pastebin, ставьте его в вопрос. Людям не нужно нажимать внешнюю ссылку, чтобы полностью понять вашу проблему. –
Как вы говорите, ваша проблема заключается в том, что вы вызываете 'vam.ReadFloat', на каждом уровне вы должны только вызывать ReadFloat один раз в конце, промежуточные уровни должны использовать' vam.ReadInt32 ('чтобы получить следующий уровень вниз Каждый уровень должен выглядеть так: «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); ' –