Кто-нибудь объяснит почему многие адреса в мемхаке делятся\умножаются на 4?
Чем отличается ReadRealMemory от ReadUnrealMemory?
Насколько я знаю они просто должны разыменовывать указатель читая значение по его адресу...
К примеру я на С++ воссоздаю функцию которая читает из памяти jass строки по стринг хендлу, но логика вроде "byteOffset = addr / 4 * 4" вводит меня в ступор

DracoL1ch:
офсет 2589 *4 , я ж только что сказал
Всё, немного поковырявшись у меня получилось, нужно было еще (id * 4) еще раз умножить на 4. Теперь строки извлекает идеально.
Если кому-то интересно, выглядит это вот так:
	DWORD ReadPointer(DWORD addr)
	{
		return *(DWORD*)(addr);
	}

	DWORD GetJassContext(int id)
	{
		DWORD pJassEnvAddress = DWORD(GetModuleHandle(TEXT("Game.dll"))) + 0xADA848;
		return ReadPointer(ReadPointer(ReadPointer(ReadPointer(pJassEnvAddress) + 0x14) + 0x90) + id * 4);
	}

	DWORD GetStringTable()
	{
		DWORD pJassContext = GetJassContext(1);
		return ReadPointer(ReadPointer(pJassContext + 0x2874) + 0x8);
	}

	std::string from_jString(jString jstrHandle)
	{
		DWORD pStringTable = GetStringTable();
		const char* sptr = (const char*)ReadPointer(ReadPointer(pStringTable + ((jstrHandle * 4)*4) + 0x8) + 0x1C);
		return sptr;
	}
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
15
а что пишешь на с++. решил весь код карты перевести на dll?
Не, у меня для других целей.
Я решил пока так: Передаю в либу результат выражения ReadUnrealMemory( ReadUnrealMemory( GetJassContext( 1 ) / 4 + 2589 ) / 4 + 2 )
Назовём его условно ptr.
Потом читаю ptr = *(ptr + stringHandle * 4 + 2), потом читаю ptr = *(ptr + 7)
И на моменте чтения адреса где прибавляется 7 уже Access violation.
По идее деление делает адрес "нереальным", а умножение реальным, раз string handle умножается в функции мемхака GetStringAddress на 4, то его и в С++ надо умножить на 4
Но почему-то на чтении ptr + 7 ошибка..
16
Unreal подразумевает чтение с адреса, уже деленного на 4, у тебя ptr нужно сразу на 4 умножать
Memory[Memory[Memory[Memory[GetJassContext(1)/4+2589]/4+2]/4+SH2I(s)*4+2]/4+7]
вот в едином стиле, все результаты делятся на 4, восстанови и получишь формулу
15
DracoL1ch:
Unreal подразумевает чтение с адреса, уже деленного на 4, у тебя ptr нужно сразу на 4 умножать
Memory[Memory[Memory[Memory[GetJassContext(1)/4+2589]/4+2]/4+SH2I(s)*4+2]/4+7]
вот в едином стиле, все результаты делятся на 4, восстанови и получишь формулу
Так-то оно так, но я заметил очень странную вещь, выводил в варике значения которые читаются по адресу и сами адреса, и проверял их в cheat engine (как и в программе C++ соответственно), эти значения кардинально различаются. Такое ощущение что у него какая-то своя вселенная откуда он читает.
К примеру вывожу вариком значение GetJassContext(1) и значение памяти по адресуGetJassContext(1)/4 + 2589 , перепечатываю адрес, перевожу в hex, смотрю значение в cheat engine с соответствующим оффсетом (2589 оно же 0xA1D) и читаю.
То что читает варик и то что читает другой софт по тем же адресам вообще отличается радикально.
28
То что читает варик и то что читает другой софт по тем же адресам вообще отличается радикально.
Ну так и них разные сегменты, варик читает то, что ось отвела для варика, а твоя прога читает то, что ось отвела для неё, вот и всё.
15
DracoL1ch:
офсет 2589 *4 , я ж только что сказал
Всё, немного поковырявшись у меня получилось, нужно было еще (id * 4) еще раз умножить на 4. Теперь строки извлекает идеально.
Если кому-то интересно, выглядит это вот так:
	DWORD ReadPointer(DWORD addr)
	{
		return *(DWORD*)(addr);
	}

	DWORD GetJassContext(int id)
	{
		DWORD pJassEnvAddress = DWORD(GetModuleHandle(TEXT("Game.dll"))) + 0xADA848;
		return ReadPointer(ReadPointer(ReadPointer(ReadPointer(pJassEnvAddress) + 0x14) + 0x90) + id * 4);
	}

	DWORD GetStringTable()
	{
		DWORD pJassContext = GetJassContext(1);
		return ReadPointer(ReadPointer(pJassContext + 0x2874) + 0x8);
	}

	std::string from_jString(jString jstrHandle)
	{
		DWORD pStringTable = GetStringTable();
		const char* sptr = (const char*)ReadPointer(ReadPointer(pStringTable + ((jstrHandle * 4)*4) + 0x8) + 0x1C);
		return sptr;
	}
Принятый ответ
32
Drulia_san, Интересен готовый продукт, что такое и что делает.
15
quq_CCCP:
Drulia_san, Интересен готовый продукт, что такое и что делает.
Делаю расширенный мемхак для себя и, собираюсь добавлять туда различный функционал который мне будет необходим по мере продвижения в работе, который можно встраивать в карту. Еще параллельно делаю небольшое sdk к варику, Некоторые вещи взял из RenderEdge, работать с графикой мне не надо, потому исключил всё что было с ней связано как и связи с d3d, сделал sdk (.lib файл с небольшим колвом инклудов) с набором необходимого, которое можно включить в проект (в данном случае моя dll) не пересобирая по 100 раз одно и то же и чтобы работало прямо из карты без заранее скачанного софта.
Может на гитхаб однажды выложу.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.