
NTSTATUS NTAPI NtSetSystemInformation ( __in SYSTEM_INFORMATION_CLASS SystemInformationClass, __in_bcount_opt(SystemInformationLength) PVOID SystemInformation, __in ULONG SystemInformationLength ) /*++ Routine Description: This function set information about the system. Arguments: SystemInformationClass - The system information class which is to be modified. SystemInformation - A pointer to a buffer which contains the specified information. The format and content of the buffer depend on the specified system information class. SystemInformationLength - Specifies the length in bytes of the system information buffer. Return Value: Returns one of the following status codes: STATUS_SUCCESS - Normal, successful completion. STATUS_ACCESS_VIOLATION - The specified system information buffer is not accessible. STATUS_INVALID_INFO_CLASS - The SystemInformationClass parameter did not specify a valid value. STATUS_INFO_LENGTH_MISMATCH - The value of the SystemInformationLength parameter did not match the length required for the information class requested by the SystemInformationClass parameter. STATUS_PRIVILEGE_NOT_HELD is returned if the caller does not have the privilege to set the system time. --*/ { BOOLEAN Enable; KPROCESSOR_MODE PreviousMode; NTSTATUS Status; ULONG TimeAdjustment; PSYSTEM_SET_TIME_ADJUST_INFORMATION TimeAdjustmentInformation; HANDLE EventHandle; PVOID Event; ULONG LoadFlags = MM_LOAD_IMAGE_IN_SESSION; PAGED_CODE(); // // Establish an exception handle in case the system information buffer // is not accessible. // Status = STATUS_SUCCESS; try { // // Get the previous processor mode and probe the input buffer for // read access if necessary. // PreviousMode = KeGetPreviousMode(); if (PreviousMode != KernelMode) { ProbeForRead((PVOID)SystemInformation, SystemInformationLength, sizeof(ULONG)); } // // Dispatch on the system information class. // switch (SystemInformationClass) { case SystemFlagsInformation: if (SystemInformationLength != sizeof( SYSTEM_FLAGS_INFORMATION )) { return STATUS_INFO_LENGTH_MISMATCH; } if (!SeSinglePrivilegeCheck( SeDebugPrivilege, PreviousMode )) { return STATUS_ACCESS_DENIED; } else { ULONG Flags; Flags = ((PSYSTEM_FLAGS_INFORMATION)SystemInformation)->Flags & ~(FLG_KERNELMODE_VALID_BITS | FLG_BOOTONLY_VALID_BITS); Flags |= NtGlobalFlag & (FLG_KERNELMODE_VALID_BITS | FLG_BOOTONLY_VALID_BITS); NtGlobalFlag = Flags; ((PSYSTEM_FLAGS_INFORMATION)SystemInformation)->Flags = NtGlobalFlag; } break; ...... 省略 case SystemRegisterFirmwareTableInformationHandler: Status = ExpRegisterFirmwareTableInformationHandler(SystemInformation, SystemInformationLength, PreviousMode); break;
TableHandler.ProviderSignature = 'RSMB'; // (Raw SMBIOS) TableHandler.Register = TRUE; TableHandler.FirmwareTableHandler = &WmipRawSMBiosTableHandler1; TableHandler.DriverObject = g_PnpDriverObject; ntStatus = funZwSetSystemInfomation(SystemRegisterFirmwareTableInformationHandler, (PVOID)&TableHandler, sizeof(SYSTEM_FIRMWARE_TABLE_HANDLER));
VOID WmipRegisterFirmwareProviders() { // Register the SMBIOS raw provider. TableHandler.ProviderSignature = 'RSMB'; // (Raw SMBIOS) TableHandler.Register = FALSE; TableHandler.FirmwareTableHandler = &WmipRawSMBiosTableHandler1; TableHandler.DriverObject = g_PnpDriverObject/*IoPnpDriverObject*/; ntStatus = funZwSetSystemInfomation(SystemRegisterFirmwareTableInformationHandler, (PVOID)&TableHandler, sizeof(SYSTEM_FIRMWARE_TABLE_HANDLER)); TableHandler.ProviderSignature = 'RSMB'; // (Raw SMBIOS) TableHandler.Register = TRUE; TableHandler.FirmwareTableHandler = &WmipRawSMBiosTableHandler1; TableHandler.DriverObject = g_PnpDriverObject; ntStatus = funZwSetSystemInfomation(SystemRegisterFirmwareTableInformationHandler, (PVOID)&TableHandler, sizeof(SYSTEM_FIRMWARE_TABLE_HANDLER)); }
NTSTATUS ExpRegisterFirmwareTableInformationHandler( IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, IN KPROCESSOR_MODE PreviousMode ) /*++ Description: This routine registers and unregisters firmware table providers. Parameters: SystemInformation - points to the SYSTEM_FIRMWARE_TABLE_HANDLER structure. SystemInformationLength - returns the number of bytes written on success. if the provided buffer was too small, it returns the required size. PreviousMode - Previous mode (Kernel / User). Return Value: STATUS_SUCCESS - On success. STATUS_PRIVILEGE_NOT_HELD - If caller is from User mode. STATUS_INFO_LENGTH_MISMATCH - Buffer too small. STATUS_INSUFFICIENT_RESOURCES - On failure to allocate resources. STATUS_OBJECT_NAME_EXISTS - Table already registered. STATUS_INVALID_PARAMETER - Table not found / invalid request. --*/ { BOOLEAN HandlerFound = FALSE; PSYSTEM_FIRMWARE_TABLE_HANDLER_NODE HandlerListCurrent = NULL; PSYSTEM_FIRMWARE_TABLE_HANDLER_NODE HandlerListNew = NULL; NTSTATUS Status = STATUS_SUCCESS; PSYSTEM_FIRMWARE_TABLE_HANDLER SystemTableHandler = NULL; PAGED_CODE(); if (PreviousMode != KernelMode) { Status = STATUS_PRIVILEGE_NOT_HELD; } else { if ((!SystemInformation) || (SystemInformationLength < sizeof(SYSTEM_FIRMWARE_TABLE_HANDLER))) { Status = STATUS_INFO_LENGTH_MISMATCH; } else { // // Grab the resource to prevent state change via reentry. // KeEnterCriticalRegion(); ExAcquireResourceExclusiveLite(&ExpFirmwareTableResource, TRUE); SystemTableHandler = (PSYSTEM_FIRMWARE_TABLE_HANDLER)SystemInformation; EX_FOR_EACH_IN_LIST(SYSTEM_FIRMWARE_TABLE_HANDLER_NODE, FirmwareTableProviderList, &ExpFirmwareTableProviderListHead, HandlerListCurrent) { if (HandlerListCurrent->SystemFWHandler.ProviderSignature == SystemTableHandler->ProviderSignature) { HandlerFound = TRUE; break; } } // // Handler was not found and this is a register request, so // allocate a new node and insert it into the list. // if ((!HandlerFound) && (SystemTableHandler->Register)) { // // This is a new Firmware table handler, allocate // the space and add it to the list. // HandlerListNew = ExAllocatePoolWithTag(PagedPool, sizeof(SYSTEM_FIRMWARE_TABLE_HANDLER_NODE), 'TFRA'); if (HandlerListNew) { // // Populate the new node. // HandlerListNew->SystemFWHandler.ProviderSignature = SystemTableHandler->ProviderSignature; HandlerListNew->SystemFWHandler.FirmwareTableHandler = SystemTableHandler->FirmwareTableHandler; HandlerListNew->SystemFWHandler.DriverObject = SystemTableHandler->DriverObject; InitializeListHead(&HandlerListNew->FirmwareTableProviderList); // // Grab a reference to the providers driverobject so that the // driver does not get unloaded without our knowledge. The // handler must first be unregistered before unloading. // ObReferenceObject((PVOID)HandlerListNew->SystemFWHandler.DriverObject); // // Update the LinkList. // InsertTailList(&ExpFirmwareTableProviderListHead, &HandlerListNew->FirmwareTableProviderList); } else { Status = STATUS_INSUFFICIENT_RESOURCES; } } else if ((HandlerFound) && (!(SystemTableHandler->Register))) { // // Check to make sure that a matching driver object was sent in. // if (HandlerListCurrent->SystemFWHandler.DriverObject == SystemTableHandler->DriverObject) { // // Remove the entry from the list. // RemoveEntryList(&HandlerListCurrent->FirmwareTableProviderList); // // Deref the device object. // ObDereferenceObject((PVOID)HandlerListCurrent->SystemFWHandler.DriverObject); // // Free the unregistered list element. // ExFreePoolWithTag(HandlerListCurrent, 'TFRA'); } else { Status = STATUS_INVALID_PARAMETER; } } else if ((HandlerFound) && (SystemTableHandler->Register)) { // // A handler for this table has already been registered. return // error. // Status = STATUS_OBJECT_NAME_EXISTS; } else { Status = STATUS_INVALID_PARAMETER; } ExReleaseResourceLite(&ExpFirmwareTableResource); KeLeaveCriticalRegion(); } } return Status; }
EX_FOR_EACH_IN_LIST(SYSTEM_FIRMWARE_TABLE_HANDLER_NODE, FirmwareTableProviderList, &ExpFirmwareTableProviderListHead, HandlerListCurrent) { if (HandlerListCurrent->SystemFWHandler.ProviderSignature == SystemTableHandler->ProviderSignature) { HandlerFound = TRUE; break; }
BOOL HookWmipRawSMBiosTable() { PLIST_ENTRY pExpFirmwareTableProviderListHead = NULL; PSYSMODULELIST pSysModuleList = NULL; static UCHAR signature[] = "x48x8Bx05x00x00x00x00x48x83xC0xE8"; static UCHAR signature2[] = "x48x8Bx0Dx00x00x00x00x48x83xC1xE8"; pSysModuleList = GetModuleList(); if (!pSysModuleList) return FALSE; ULONG_PTR ulNtoskrnlBase =0, ulNtoskrnlSize = 0; FindModuleByName(pSysModuleList, "ntoskrnl.exe", &ulNtoskrnlBase, &ulNtoskrnlSize); IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER*)(ulNtoskrnlBase); IMAGE_NT_HEADERS *kernelImage = (IMAGE_NT_HEADERS*)(ulNtoskrnlBase + dos->e_lfanew); //PIMAGE_SECTION_HEADER pFirstSection = (PIMAGE_SECTION_HEADER)(g_ntoskrnl + 1); // // 获取DOS头部 IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)ulNtoskrnlBase; // 检查DOS头部的标志是否符合PE格式 if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) { return FALSE; } // 计算PE头部的地址 IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)((DWORD_PTR)ulNtoskrnlBase + dosHeader->e_lfanew); // 检查PE头部的标志是否符合PE格式 if (ntHeader->Signature != IMAGE_NT_SIGNATURE) { return FALSE; } // 获取节表的地址 IMAGE_SECTION_HEADER* sectionHeader = (IMAGE_SECTION_HEADER*)((DWORD_PTR)ntHeader + sizeof(IMAGE_NT_HEADERS)); for (PIMAGE_SECTION_HEADER pSection = sectionHeader; pSection < sectionHeader + kernelImage->FileHeader.NumberOfSections; pSection++) { if (*(PULONG)pSection->Name != 'EGAP') { continue; } DWORD64 found = find_pattern(ulNtoskrnlBase + pSection->VirtualAddress, pSection->Misc.VirtualSize, (const char*)signature, "xxx????xxxx"); if (found == 0) { found = find_pattern(ulNtoskrnlBase + pSection->VirtualAddress, pSection->Misc.VirtualSize, (const char*)signature2, "xxx????xxxx"); } if (found != 0) { pExpFirmwareTableProviderListHead = (PLIST_ENTRY)found; break; } } if (pExpFirmwareTableProviderListHead != NULL) { // PAGE:00000001404A95A5 48 8B 05 >64 8C E2 FF mov rax, cs:ExpFirmwareTableProviderListHead int relativeAddr = *(int*)((char*)pExpFirmwareTableProviderListHead + 3); pExpFirmwareTableProviderListHead = (PLIST_ENTRY)((uintptr_t)(pExpFirmwareTableProviderListHead)+7 + relativeAddr); if (!IsListEmpty(pExpFirmwareTableProviderListHead)) { PLIST_ENTRY nextEntry = NULL; for (PLIST_ENTRY pListEntry = pExpFirmwareTableProviderListHead->Flink; pListEntry != pExpFirmwareTableProviderListHea d; pListEntry = nextEntry) { nextEntry = pListEntry->Flink; unsigned int val = *(unsigned int*)((uintptr_t)pListEntry - 0x18); PVOID* funcPtr = (PVOID*)((uintptr_t)pListEntry - 0x18 + 0x8); DbgPrint("ExpFirmwareTableProviderListHead entry: %u 0x%p", val, *funcPtr); if (val == 'RSMB') { g_pFuncPtr = funcPtr; pOriginalWmipRawSMBiosTableHandler = *(PFNFTH*)funcPtr; InterlockedExchangePointer((volatile PVOID*)funcPtr, (PVOID)WmipRawSMBiosTableHandlerHook); break; } } } } return TRUE; }
// WmipFindSMBiosStructure -> WmipSMBiosTablePhysicalAddress PPHYSICAL_ADDRESS physical_address = (PPHYSICAL_ADDRESS)n_util::find_pattern_image(address, "x48x8Bx0Dx00x00x00x00x48x85xC9x74x00x8Bx15", "xxx????xxxx?xx"); if (physical_address == 0) return false; physical_address = reinterpret_cast<PPHYSICAL_ADDRESS>(reinterpret_cast<char*>(physical_address) + 7 + *reinterpret_cast<int*>(reinterpret_cast<char*>(physical_address) + 3)); if (physical_address == 0) return false; n_log::printf("physical address : %llx n", physical_address); // WmipFindSMBiosStructure -> WmipSMBiosTableLength DWORD64 physical_length_address = n_util::find_pattern_image(address, "x8Bx1Dx00x00x00x00x48x8BxD0x44x8BxC3x48x8BxCDxE8x00x00x00x00x8BxD3x48x8B", "xx????xxxxxxxxxx????xxxx"); if (physical_length_address == 0) return false; unsigned long physical_length = *reinterpret_cast<unsigned long*>(static_cast<char*>((void*)physical_length_address) + 6 + *reinterpret_cast<int*>(static_cast<char*>((void*)physical_length_address) + 2)); if (physical_length == 0) return false; n_log::printf("physical length : %d n", physical_length);
typedef struct { UINT8 Type; UINT8 Length; UINT8 Handle[2]; } SMBIOS_HEADER,*PSMBIOS_HEADER; typedef UINT8 SMBIOS_STRING; typedef struct { SMBIOS_HEADER Hdr; SMBIOS_STRING Vendor; SMBIOS_STRING BiosVersion; UINT8 BiosSegment[2]; SMBIOS_STRING BiosReleaseDate; UINT8 BiosSize; UINT8 BiosCharacteristics[8]; } SMBIOS_TYPE0; typedef struct { SMBIOS_HEADER Hdr; SMBIOS_STRING Manufacturer; SMBIOS_STRING ProductName; SMBIOS_STRING Version; SMBIOS_STRING SerialNumber; // // always byte copy this data to prevent alignment faults! // GUID Uuid; // EFI_GUID == GUID? UINT8 WakeUpType; } SMBIOS_TYPE1; typedef struct { SMBIOS_HEADER Hdr; SMBIOS_STRING Manufacturer; SMBIOS_STRING ProductName; SMBIOS_STRING Version; SMBIOS_STRING SerialNumber; } SMBIOS_TYPE2; typedef struct { SMBIOS_HEADER Hdr; SMBIOS_STRING Manufacturer; UINT8 Type; SMBIOS_STRING Version; SMBIOS_STRING SerialNumber; SMBIOS_STRING AssetTag; UINT8 BootupState; UINT8 PowerSupplyState; UINT8 ThermalState; UINT8 SecurityStatus; UINT8 OemDefined[4]; } SMBIOS_TYPE3;
void process_smbios_table(SMBIOS_HEADER* header) { auto TableLength = [](PSMBIOS_HEADER pHeader) -> size_t { char* current = reinterpret_cast<char*>(pHeader) + pHeader->Length; size_t i = 1; for (i; current[i - 1] != '�' || current[i] != '�'; i++) { // Scan until we find a double zero byte } return pHeader->Length + i + 1; }; auto GetString = [](PSMBIOS_HEADER pHeader, unsigned char id, int nLen) -> char* { UNREFERENCED_PARAMETER(id); UNREFERENCED_PARAMETER(nLen); char* string = reinterpret_cast<char*>(pHeader) + pHeader->Length; char hexOutput[256] = { 0 }; stringToHex(string, hexOutput, nLen); DbgPrint("%srn", hexOutput); for (DWORD i = 1; i < id; i++) { string += strlen(string) + 1; } return string; }; { char* serialNumber = NULL; if (header->Type == 1) //主板bios { SMBIOS_TYPE1* pSystemInfoHeader = reinterpret_cast<SMBIOS_TYPE1*>(header); serialNumber = GetString((SMBIOS_HEADER*)pSystemInfoHeader, pSystemInfoHeader->SerialNumber, header->Length); DbgPrint("read SystemInfo: %srn", serialNumber); } else if (header->Type == 2) //主板物理序列号 { SMBIOS_TYPE3* pBaseBoardHeader = reinterpret_cast<SMBIOS_TYPE3*>(header); serialNumber = GetString((SMBIOS_HEADER*)pBaseBoardHeader, pBaseBoardHeader->SerialNumber, header->Length); DbgPrint("read BaseBoard: %srn", serialNumber); } else if (header->Type == 4) // CPU { SMBIOS_TYPE4* pCpuHeader = reinterpret_cast<SMBIOS_TYPE4*>(header); serialNumber = GetString((SMBIOS_HEADER*)pCpuHeader, pCpuHeader->ProcessorId, header->Length); DbgPrint("read CPU: %srn", serialNumber); } if (serialNumber) { if (header->Type == 1) // SystemInfo 主板bios { SMBIOS_TYPE1* pSystemInfoHeader = reinterpret_cast<SMBIOS_TYPE1*>(header); RandomizeSerialNumber(serialNumber, 12); DbgPrint("write: %srn", serialNumber); serialNumber = GetString((SMBIOS_HEADER*)pSystemInfoHeader, pSystemInfoHeader->SerialNumber, header->Length); DbgPrint("re-read BaseBoard bios: %s.Len:%drn", serialNumber, header->Length); } else if (header->Type == 2) // BaseBoard Physical SN { SMBIOS_TYPE3* pBaseBoardHeader = reinterpret_cast<SMBIOS_TYPE3*>(header); RandomizeSerialNumber(serialNumber, 12); DbgPrint("write: %srn", serialNumber); serialNumber = GetString((SMBIOS_HEADER*)pBaseBoardHeader, pBaseBoardHeader->SerialNumber, header->Length); DbgPrint("re-read BaseBoard: %s.Len:%drn", serialNumber, header->Length); } else if (header->Type == 4) // CPU { SMBIOS_TYPE4* pCpuHeader = reinterpret_cast<SMBIOS_TYPE4*>(header); RandomizeSerialNumber(serialNumber, 12); DbgPrint("write: %srn", serialNumber); serialNumber = GetString((SMBIOS_HEADER*)pCpuHeader, pCpuHeader->ProcessorId, header->Length); DbgPrint("re-read CPU: %s.Len:%drn", serialNumber, header->Length); } } header = (PSMBIOS_HEADER)((char*)header + TableLength(header)); } DbgPrint("[WmipRawSMBiosTableHandlerHook] Serial numbers spoofed."); }
看雪ID:yirucandy
https://bbs.kanxue.com/user-home-597552.htm
原文始发于微信公众号(看雪学苑):获得并修改硬件序列号——CPU、主板、内存、硬盘等(有源码)
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论