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[] = "\x48\x8B\x05\x00\x00\x00\x00\x48\x83\xC0\xE8";
static UCHAR signature2[] = "\x48\x8B\x0D\x00\x00\x00\x00\x48\x83\xC1\xE8";
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,
"\x48\x8B\x0D\x00\x00\x00\x00\x48\x85\xC9\x74\x00\x8B\x15",
"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,
"\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");
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] != '\0' || current[i] != '\0'; 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("%s\r\n", 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: %s\r\n", 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: %s\r\n", 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: %s\r\n", serialNumber);
}if (serialNumber)
{
if (header->Type == 1) // SystemInfo 主板bios
{
SMBIOS_TYPE1* pSystemInfoHeader = reinterpret_cast<SMBIOS_TYPE1*>(header);RandomizeSerialNumber(serialNumber, 12);
DbgPrint("write: %s\r\n", serialNumber);serialNumber = GetString((SMBIOS_HEADER*)pSystemInfoHeader, pSystemInfoHeader->SerialNumber,
header->Length);
DbgPrint("re-read BaseBoard bios: %s.Len:%d\r\n", serialNumber, header->Length);
}
else if (header->Type == 2) // BaseBoard Physical SN
{
SMBIOS_TYPE3* pBaseBoardHeader = reinterpret_cast<SMBIOS_TYPE3*>(header);RandomizeSerialNumber(serialNumber, 12);
DbgPrint("write: %s\r\n", serialNumber);serialNumber = GetString((SMBIOS_HEADER*)pBaseBoardHeader, pBaseBoardHeader->SerialNumber,
header->Length);
DbgPrint("re-read BaseBoard: %s.Len:%d\r\n", serialNumber, header->Length);
}
else if (header->Type == 4) // CPU
{
SMBIOS_TYPE4* pCpuHeader = reinterpret_cast<SMBIOS_TYPE4*>(header);RandomizeSerialNumber(serialNumber, 12);
DbgPrint("write: %s\r\n", serialNumber);serialNumber = GetString((SMBIOS_HEADER*)pCpuHeader, pCpuHeader->ProcessorId,
header->Length);
DbgPrint("re-read CPU: %s.Len:%d\r\n", 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
# 往期推荐
2、恶意木马历险记
球分享
球点赞
球在看
点击阅读原文查看更多