mutante icon indicating copy to clipboard operation
mutante copied to clipboard

SMBIOs not spoofing in VM - Windows 10 22H2.

Open WHots opened this issue 2 years ago • 2 comments

Windows 10, 22H2

Build: Debug, x64 Character Set: User Multi-Byte Character Set

Checking SMBIOs data before and after loading with OSR is use: https://github.com/KunYi/DumpSMBIOS/tree/main

DriverEntry

`extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { DriverObject->DriverUnload = Unload; DbgPrint("[*]\tDriver ini...");

DbgPrint ("[*]\tRunning SpoofSMBIOSCleaner");
SpoofSMBIOSCleaner();
DbgPrint("[*]\tFinished running SpoofSMBIOSCleaner");
return STATUS_SUCCESS;

}`

RandomText/GetString/RandomizeString

`void RandomText(char* text, const int length) {

if (!text)
{
	DbgPrint ("[!] RandomText: text is null\n");
	return;
}
	

static const char alphanum[] =
	"0123456789"
	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	"abcdefghijklmnopqrstuvwxyz";

auto seed = KeQueryTimeIncrement();

for (auto n = 0; n <= length; n++)
{
	auto key = RtlRandomEx(&seed) % static_cast<int>(sizeof(alphanum) - 1);
	text[n] = alphanum[key];
}

}

char* GetString(SMBIOS_HEADER* header, SMBIOS_STRING string) { const auto* start = reinterpret_cast<const char*>(header) + header->Length;

if (!string || *start == 0)
{
	DbgPrint ("[!] GetString: string is null\n");
	return nullptr;
}

while (--string)
{
	start += strlen(start) + 1;
}

return const_cast<char*>(start);

}

void RandomizeString(char* string) {

if (!string) { DbgPrint ("[!] RandomizeString: string is null\n"); return; }

const auto length = static_cast<int>(strlen(string));

auto* buffer = static_cast<char*>(ExAllocatePoolWithTag(NonPagedPool, length, 'ref0'));

if (sizeof(buffer) == 0)
{
	DbgPrint ("[!] RandomizeString: buffer is null\n");
	return;
}

RandomText(buffer, length);
buffer[length] = '\0';

if (sizeof(buffer) == 0)
{
	DbgPrint("[!] RandomizeString: buffer is null after termination\n");
	return;
}

memcpy(string, buffer, length);

ExFreePool(buffer);

}`

ProcessTable/LoopTables/SpoofSMBIOSCleaner

` void ProcessTable(SMBIOS_HEADER* header) {

if (header->Type == 0)
{
	auto* type0 = reinterpret_cast<SMBIOS_TYPE0*>(header);

	auto* vendor = GetString(header, type0->Vendor);
	RandomizeString(vendor);
}

if (header->Type == 1)
{
	auto* type1 = reinterpret_cast<SMBIOS_TYPE1*>(header);

	auto* manufacturer = GetString(header, type1->Manufacturer);
	RandomizeString(manufacturer);

	auto* productName = GetString(header, type1->ProductName);
	RandomizeString(productName);

	auto* serialNumber = GetString(header, type1->SerialNumber);
	RandomizeString(serialNumber);
	
}

if (header->Type == 2)
{
	auto* type2 = reinterpret_cast<SMBIOS_TYPE2*>(header);

	auto* manufacturer = GetString(header, type2->Manufacturer);
	RandomizeString(manufacturer);

	auto* productName = GetString(header, type2->ProductName);
	RandomizeString(productName);

	auto* serialNumber = GetString(header, type2->SerialNumber);
	RandomizeString(serialNumber);
}

if (header->Type == 3)
{
	auto* type3 = reinterpret_cast<SMBIOS_TYPE3*>(header);

	auto* manufacturer = GetString(header, type3->Manufacturer);
	RandomizeString(manufacturer);

	auto* serialNumber = GetString(header, type3->SerialNumber);
	RandomizeString(serialNumber);
}

}

void LoopTables(void* mapped, ULONG size) {

auto* endAddress = static_cast<char*>(mapped) + size;

if (endAddress == nullptr) 
{
	DbgPrint ("Failed to get end address");
}	

while (true)
{
	auto* header = static_cast<SMBIOS_HEADER*>(mapped);
	if (header->Type == 127 && header->Length == 4)
		break;

	ProcessTable(header);

	auto* end = static_cast<char*>(mapped) + header->Length;
	while (0 != (*end | *(end + 1))) end++;
	end += 2;
	if (end >= endAddress)
		break;

	mapped = end;
}

}

void SpoofSMBIOSCleaner() {

auto* base = GetModuleBase("ntoskrnl.exe");
if (!base)
{
	DbgPrint("Failed to get ntoskrnl.exe base address");
}

auto* physicalAddress = static_cast<PPHYSICAL_ADDRESS>(FindPatternImage(base, "\x48\x8B\x0D\x00\x00\x00\x00\x48\x85\xC9\x74\x00\x8B\x15", "xxx????xxxx?xx")); // WmipFindSMBiosStructure -> WmipSMBiosTablePhysicalAddress
if (!physicalAddress)
{
	DbgPrint("Failed to find WmipSMBiosTablePhysicalAddress");
}

physicalAddress = reinterpret_cast<PPHYSICAL_ADDRESS>(reinterpret_cast<char*>(physicalAddress) + 7 + *reinterpret_cast<int*>(reinterpret_cast<char*>(physicalAddress) + 3));
if (!physicalAddress)
{
	DbgPrint("Failed to get physical address");
}

auto* sizeScan = FindPatternImage(base, "\x8B\x1D\x00\x00\x00\x00\x48\x8B\xD0\x44\x8B\xC3\x48\x8B\xCD\xE8\x00\x00\x00\x00\x8B\xD3\x48\x8B", "xx????xxxxxxxxxx????xxxx");  // WmipFindSMBiosStructure -> WmipSMBiosTableLength
if (!sizeScan)
{
	DbgPrint("Failed to find WmipSMBiosTableLength");
}

const auto size = *reinterpret_cast<ULONG*>(static_cast<char*>(sizeScan) + 6 + *reinterpret_cast<int*>(static_cast<char*>(sizeScan) + 2));
if (!size)
{
	DbgPrint("Failed to get size");
}

auto* mapped = MmMapIoSpace(*physicalAddress, size, MmNonCached);
if (!mapped)
{
	DbgPrint("Failed to map physical address");
}

LoopTables(mapped, size);

MmUnmapIoSpace(mapped, size);

} `

In my kernel debug log I'm getting error for ..

[!] GetString: string is null [!] RandomizeString: string is null

And that's it, just once for each.. no other errors are raised... any solution for this, or does this method not work for 22h2 ?

WHots avatar Jun 14 '23 04:06 WHots

UPDATE: So if you remove the parts grabbing the SerialNumbers, It will run with no errors displayed.. and i have a of check lol..

so the only thing it's grabbing is Manufacturer and ProductName.. BUUUUUT it still does not change anything... so yeah kinda lost, it runs with no errors but doesn't work lmao.

WHots avatar Jun 14 '23 04:06 WHots

This project is old and the parsing is not well written. Just recreate the tables from scratch and replace them completely.

SamuelTulach avatar Jan 22 '24 20:01 SamuelTulach