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

Сканер сигнатур [C++]


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

Не работает сканер сигнатур. Писал по урокам Dmitry K. (Coder).

Операционная система: Windows 10 x64 1809
Сидел в отладчике, PID процесса правильный всегда. Укажите, на то, что мне следует изменить или проверить.

int main() - точка старта программы

Спойлер

#include <iostream>
#include "MemReader.h"

int main()
{
    MemReader* mem = new MemReader("Terraria.exe");
    mem->Open();
    printf("PID: %X\n", mem->getPID());
    MODULEENTRY32 game = { 0 };
    mem->GetModuleInfo(NULL, &game, true);
    printf("Process base = 0x%X, size = 0x%X\n", (DWORD)game.modBaseAddr, game.modBaseSize);
    DWORD sunAddr = mem->FindSignature((DWORD)game.modBaseAddr, game.modBaseSize, (PBYTE)"\xC8\x00\x00\x00\xC8\x00\x00\x00\xC8\x00\x00\x00", "xxxxxxxxxxxx");
    printf("Signature found at 0x%X\n", sunAddr);
    system("PAUSE");
}

 

Нашел такую особенность: если изменить значения в FindSignature()

(DWORD)game.modBaseAddr, game.modBaseSize

На значения  Base address, Scan Size из плагина Sig Maker к OllyDbg 1.0, то все успешно заработает

Значения:

Спойлер

1c4b03f0eb1b.jpg


FindSignature() - метод поиска сигнатуры

Спойлер

DWORD MemReader::FindSignature(DWORD base, DWORD size, byte* sign, char* mask)
{
	MEMORY_BASIC_INFORMATION mbi = { 0 };
	DWORD offset = 0;

	while (offset < size)
	{
		VirtualQueryEx(m_hProc, (LPCVOID)(base + offset), &mbi, sizeof(MEMORY_BASIC_INFORMATION));
		if (mbi.State != MEM_FREE)
		{
			byte* buffer = new byte[mbi.RegionSize];
			ReadProcessMemory(m_hProc, mbi.BaseAddress, buffer, mbi.RegionSize, NULL);
			for (size_t i = 0; i < mbi.RegionSize; i++)
			{
				if (DataCompare(buffer + i, sign, mask))
				{
					delete[] buffer;
					return (DWORD)mbi.BaseAddress + i;
				}
			}
			delete[] buffer;
		}
		offset += mbi.RegionSize;
	}
	return 0;
}

 


DataComapre() - сравнение значений

Спойлер

bool MemReader::DataCompare(byte* data, byte* sign, char* mask)
{
	for (; *mask; mask++, sign++, data++)
	{
		if (*mask == 'x' && *data != *sign)
			return false;
	}
	return true;
}

 

 

GetModuleInfo() - Получении информации о модуле

Спойлер

void MemReader::GetModuleInfo(char* moduleName, MODULEENTRY32* mInfo, bool aboutProcess)
{
	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, m_pID);
	mInfo->dwSize = sizeof(MODULEENTRY32);

	if (Module32First(snapshot, mInfo))
	{
		if (aboutProcess) { CloseHandle(snapshot); return; }
		while (Module32Next(snapshot, mInfo))
		{
			if (strcmp(moduleName, mInfo->szModule) == 0)
			{
				CloseHandle(snapshot);
				return;
			}
		}
	}
	CloseHandle(snapshot);
	memset(mInfo, 0, sizeof(MODULEENTRY32));
}

 

 

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

Возможно, код находится не в модуле, а в выделенной памяти в адресном пространстве исполняемого файла и этот диапазон адресов не подходит под диапазон, найденный с помощью getModuleInfo. Проверяй диапазон адресов, который получаешь на вход поисковика сигнатур

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

1 час назад, Lucky7 сказал:

Base address, Scan Size из плагина Sig Maker к OllyDbg 1.0, то все успешно заработает

Как сказал @Xipho у тебя вероятно сканирование происходит не в области модуля, Terraria.exe это тоже модуль. То есть есть процесс - Terraria.exe, а в нём есть модуль Terraria.exe, на равне с dll и другими. А я вижу что ты пишешь NULL при поиске модуля, попробуй укажи там Terraria.exe.

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

1 час назад, imaginary сказал:

Как сказал @Xipho у тебя вероятно сканирование происходит не в области модуля, Terraria.exe это тоже модуль. То есть есть процесс - Terraria.exe, а в нём есть модуль Terraria.exe, на равне с dll и другими. А я вижу что ты пишешь NULL при поиске модуля, попробуй укажи там Terraria.exe.

Указал название модуля Terraria.exe, модуль он находит правильно, и его Size тоже, вопрос в том, что память, которую я хочу изменить находится как я понял не в нем.
Только, что получил значение через CheatEngine "1E593078", его AllocationBase=1D5E0000, это значение отличается, от того, которое я получил GetModuleInfo.
Скриншот для наглядности:
 

Спойлер

9d2cbdc638d8.jpg

А теперь главный вопрос, где мне тогда искать мое значение, раз его нету в модуле Terraria.exe.

 

2 часа назад, Xipho сказал:

Возможно, код находится не в модуле, а в выделенной памяти в адресном пространстве исполняемого файла и этот диапазон адресов не подходит под диапазон, найденный с помощью getModuleInfo. Проверяй диапазон адресов, который получаешь на вход поисковика сигнатур

Могу предположить, что придется использовать GetProcessHeap()?
 

Благодарю всех за ответы, уже 3 день сижу решаю эту проблему.

 

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

21 час назад, Lucky7 сказал:

Могу предположить, что придется использовать GetProcessHeap()?

Память может быть выделена не в куче, тут надо думать. Для эксперимента можешь попробовать указать в качестве стартового адрес модуля, как ты до этого делал, а в качестве размера - 0x7FFFFFFF (если это 32 битная игра), и посмотреть, найдет ли в таком случае сигнатуру.

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

23 часа назад, Lucky7 сказал:

А теперь главный вопрос, где мне тогда искать мое значение

У меня эта сигнатура тоже не в модуле, находится просто поиском по страницам с использованием VirtualQueryEx.
А ещё как я вижу это записываемая память, попробуй написать простой перебор страниц, с проверкой, если записываемая память, то проверять, если иная, например исполняемая, то не трогать, проверяй всё с начального адреса до последней страницы, последнюю страницу можно определить если VirtualQueryEx вернёт ту же самую страницу после прибавления её размера, а не следующую. В CE как раз реализован умный поиск, там есть галочка Writable.

 

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

В 19.03.2020 в 17:11, imaginary сказал:

У меня эта сигнатура тоже не в модуле, находится просто поиском по страницам с использованием VirtualQueryEx.
А ещё как я вижу это записываемая память, попробуй написать простой перебор страниц, с проверкой, если записываемая память, то проверять, если иная, например исполняемая, то не трогать, проверяй всё с начального адреса до последней страницы, последнюю страницу можно определить если VirtualQueryEx вернёт ту же самую страницу после прибавления её размера, а не следующую. В CE как раз реализован умный поиск, там есть галочка Writable.

 

А можно простой пример реализации, допустим, на примере кода lucky? 

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

×
×
  • Создать...

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

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