[Video Tutorial] Internal Signature Scanning

11/26/2019 17:39 Black_and_White#1
Hello everyone :)

I recently made a video on Internal Signature (aob) scanning. Hope you enjoy.

[Only registered and activated users can see links. Click Here To Register...]

If you are only interested in the code here u go:

Code:
DWORD GetAddressFromSignature(std::vector<int> signature, DWORD startaddress=0, DWORD endaddress=0) {
	SYSTEM_INFO si;
	GetSystemInfo(&si);
	if (startaddress == 0) {
		startaddress = (DWORD)(si.lpMinimumApplicationAddress);
	}
	if (endaddress == 0) {
		endaddress = (DWORD)(si.lpMaximumApplicationAddress);
	}

	MEMORY_BASIC_INFORMATION mbi{ 0 };
	DWORD protectflags = (PAGE_GUARD | PAGE_NOCACHE | PAGE_NOACCESS);

	for (DWORD i = startaddress; i < endaddress -signature.size(); i++) {
		//std::cout << "scanning: " << std::hex << i << std::endl;
		if (VirtualQuery((LPCVOID)i, &mbi, sizeof(mbi))) {
			if (mbi.Protect & protectflags || !(mbi.State & MEM_COMMIT)) {
				std::cout << "Bad Region! Region Base Address: " << mbi.BaseAddress << " | Region end address: " << std::hex << (int)((DWORD)mbi.BaseAddress + mbi.RegionSize) << std::endl;
				i += mbi.RegionSize;
				continue; // if bad adress then dont read from it
			}
			std::cout << "Good Region! Region Base Address: " << mbi.BaseAddress << " | Region end address: " << std::hex << (int)((DWORD)mbi.BaseAddress + mbi.RegionSize) << std::endl;
			for (DWORD k = (DWORD)mbi.BaseAddress; k < (DWORD)mbi.BaseAddress + mbi.RegionSize - signature.size(); k++) {
				for (DWORD j = 0; j < signature.size(); j++) {
					if (signature.at(j) != -1 && signature.at(j) != *(byte*)(k + j))
						break;
					if (j + 1 == signature.size())
						return k;
				}
			}
			i = (DWORD)mbi.BaseAddress + mbi.RegionSize;
		}
	}
	return NULL;
}
PS: Yes I did sub elitepvpers channel and I will link back to this thread ;)
05/28/2020 02:23 Crossfire2000#2
you're the best !
05/28/2020 19:57 elmarcia#3
Quote:
Originally Posted by Black_and_White View Post
Hello everyone :)

I recently made a video on Internal Signature (aob) scanning. Hope you enjoy.

[Only registered and activated users can see links. Click Here To Register...]

If you are only interested in the code here u go:

Code:
DWORD GetAddressFromSignature(std::vector<int> signature, DWORD startaddress=0, DWORD endaddress=0) {
	SYSTEM_INFO si;
	GetSystemInfo(&si);
	if (startaddress == 0) {
		startaddress = (DWORD)(si.lpMinimumApplicationAddress);
	}
	if (endaddress == 0) {
		endaddress = (DWORD)(si.lpMaximumApplicationAddress);
	}

	MEMORY_BASIC_INFORMATION mbi{ 0 };
	DWORD protectflags = (PAGE_GUARD | PAGE_NOCACHE | PAGE_NOACCESS);

	for (DWORD i = startaddress; i < endaddress -signature.size(); i++) {
		//std::cout << "scanning: " << std::hex << i << std::endl;
		if (VirtualQuery((LPCVOID)i, &mbi, sizeof(mbi))) {
			if (mbi.Protect & protectflags || !(mbi.State & MEM_COMMIT)) {
				std::cout << "Bad Region! Region Base Address: " << mbi.BaseAddress << " | Region end address: " << std::hex << (int)((DWORD)mbi.BaseAddress + mbi.RegionSize) << std::endl;
				i += mbi.RegionSize;
				continue; // if bad adress then dont read from it
			}
			std::cout << "Good Region! Region Base Address: " << mbi.BaseAddress << " | Region end address: " << std::hex << (int)((DWORD)mbi.BaseAddress + mbi.RegionSize) << std::endl;
			for (DWORD k = (DWORD)mbi.BaseAddress; k < (DWORD)mbi.BaseAddress + mbi.RegionSize - signature.size(); k++) {
				for (DWORD j = 0; j < signature.size(); j++) {
					if (signature.at(j) != -1 && signature.at(j) != *(byte*)(k + j))
						break;
					if (j + 1 == signature.size())
						return k;
				}
			}
			i = (DWORD)mbi.BaseAddress + mbi.RegionSize;
		}
	}
	return NULL;
}
PS: Yes I did sub elitepvpers channel and I will link back to this thread ;)
You can even speed up the process if your pattern can be contained in an ASM register:
For 32bit processors: register size = 4bytes
For 64bit processors: register size = 8bytes

This code is fast for aligned memory, meaning your pattern is aligned between 16bytes (4 bytes aligned for 32 bits processors, 8 bytes aligned for 64bits)

If non aligned memory in pattern, then offset step should be 1, meaning it will be more slow.

Aligned pattern

Aligned 32bits pattern
64bits step size is 8bytes meaning it will skip those bytes, but 32bit will work fine.

Code

The way this code works is supper simple:

You have a pattern lets say: 0x01 ?? 0x03 ?? 0x05 ?? 0x7 0x8
You build a mask for that pattern that replaces ?? for 0x00 and anything else for 0xFF

So mask: 0xFF 0x00 0xFF 0x00 0xFF 0x00 0xFF 0xFF

You go save your first value in a register -> EAX
You perform an and operation to EAX with mask, to filter ?? values
then you apply a xor between eax and your pattern, to check if they are equal. if cero means they are equal, then you have a match. Repeat until end

Edit:
Didn't saw that bump lol my bad