Перейти к содержанию
Авторизация  
Lucky7

Сканер сигнатур [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? 

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


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

Для публикации сообщений создайте учётную запись или авторизуйтесь

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

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация  

×

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

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