SamuelTulach / mutante

Kernel-mode Windows HWID spoofer
520 stars 142 forks source link

SMBIOs not spoofing in VM - Windows 10 22H2. #21

Open WHots opened 1 year ago

WHots commented 1 year ago

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 commented 1 year ago

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.

SamuelTulach commented 5 months ago

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