1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 揭秘灰色产业链中掖着藏着的底层技术(初级篇)

揭秘灰色产业链中掖着藏着的底层技术(初级篇)

时间:2023-12-22 07:02:35

相关推荐

揭秘灰色产业链中掖着藏着的底层技术(初级篇)

独角兽企业重金招聘Python工程师标准>>>

今天就来一段现在比较流行的,也算是有人藏着掖着的,能反反调试的一种手段之一,重载内核。一共两个函数,放在驱动程序里直接调用即可。废话不多说,上代码。

////函数名称:LoadKernel//函数作用:将内核文件载入内存//参数:newKernelBasePtrPtr[OUT]:接收新内核基址的指针//oldKernelBasePtrPtr[OUT]:接收旧内核基址的指针//作者:葛世超//时间:8月14日22:37//NTSTATUS LoadKernel(OUT PUCHAR * newKernelBasePtrPtr, OUT PUCHAR * oldKernelBasePtrPtr){ULONG rtlProcessModulesSize = 0;//获取枚举系统模块所需内存尺寸NTSTATUS status = ZwQuerySystemInformation(SystemModuleInformation, NULL, 0, &rtlProcessModulesSize);//以获取的内存尺寸作为判断函数成功的依据是由于rtlProcessModulesSize为0时函数一定不能返回STATUS_SUCCESSif (!rtlProcessModulesSize){return status;}//为系统模块分配内存空间PRTL_PROCESS_MODULES rtlProcessModulesPtr = (PRTL_PROCESS_MODULES)ExAllocatePoolWithTag(PagedPool, rtlProcessModulesSize, 'NIMS');if (!rtlProcessModulesPtr){return STATUS_NO_MEMORY;}RtlZeroMemory(rtlProcessModulesPtr, rtlProcessModulesSize);//第二次调用该函数且rtlProcessModulesSize不为0时可返回有效内核模块信息status = ZwQuerySystemInformation(SystemModuleInformation, rtlProcessModulesPtr, rtlProcessModulesSize, &rtlProcessModulesSize);//因rtlProcessModulesSize足够大且rtlProcessModulesPtr有效, 则可以使用函数返回值判断函数执行结果if (!NT_SUCCESS(status)){ExFreePoolWithTag(rtlProcessModulesPtr, 'NIMS');return status;}UNICODE_STRING kernelFilePath;RtlZeroMemory(&kernelFilePath, sizeof(kernelFilePath));PUCHAR oldKernelBasePtr = NULL;for (int i = 0; i < rtlProcessModulesPtr->NumberOfModules; ++i){if (strstr(rtlProcessModulesPtr->Modules[i].FullPathName, "ntoskrnl.exe")){RtlInitUnicodeString(&kernelFilePath, L"\\SystemRoot\\System32\\ntoskrnl.exe");oldKernelBasePtr = (PUCHAR)rtlProcessModulesPtr->Modules[i].ImageBase;break;}if (strstr(rtlProcessModulesPtr->Modules[i].FullPathName, "ntkrnlpa.exe")){RtlInitUnicodeString(&kernelFilePath, L"\\SystemRoot\\System32\\ntkrnlpa.exe");oldKernelBasePtr = (PUCHAR)rtlProcessModulesPtr->Modules[i].ImageBase;break;}if (strstr(rtlProcessModulesPtr->Modules[i].FullPathName, "ntkrnlmp.exe")){RtlInitUnicodeString(&kernelFilePath, L"\\SystemRoot\\System32\\ntkrnlmp.exe");oldKernelBasePtr = (PUCHAR)rtlProcessModulesPtr->Modules[i].ImageBase;break;}if (strstr(rtlProcessModulesPtr->Modules[i].FullPathName, "ntkrpamp.exe")){RtlInitUnicodeString(&kernelFilePath, L"\\SystemRoot\\System32\\ntkrpamp.exe");oldKernelBasePtr = (PUCHAR)rtlProcessModulesPtr->Modules[i].ImageBase;break;}}ExFreePoolWithTag(rtlProcessModulesPtr, 'NIMS');//oldKernelBasePtr等于NULL时没有找到内核文件路径if (!oldKernelBasePtr){return STATUS_NOT_FOUND;}//将内核文件内容读入内存OBJECT_ATTRIBUTES objectAttributes;RtlZeroMemory(&objectAttributes, sizeof(objectAttributes));InitializeObjectAttributes(&objectAttributes,&kernelFilePath,OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,NULL,NULL);IO_STATUS_BLOCK ioStatusBlock;RtlZeroMemory(&ioStatusBlock, sizeof(ioStatusBlock));HANDLE kernelFileHandle = NULL;status = ZwOpenFile(&kernelFileHandle,GENERIC_READ,&objectAttributes,&ioStatusBlock,FILE_SHARE_READ,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);if (!NT_SUCCESS(status)){return status;}FILE_STANDARD_INFORMATION fileStandardInformation;RtlZeroMemory(&fileStandardInformation, sizeof(fileStandardInformation));status = ZwQueryInformationFile(kernelFileHandle,&ioStatusBlock,&fileStandardInformation,sizeof(fileStandardInformation),FileStandardInformation);if (!NT_SUCCESS(status)){ZwClose(kernelFileHandle);return status;}ULONG kernelFileSize = fileStandardInformation.EndOfFile.QuadPart;PUCHAR kernelFileContentPtr = (PUCHAR)ExAllocatePoolWithTag(PagedPool, kernelFileSize, 'TNTC');if (!kernelFileContentPtr){ZwClose(kernelFileHandle);return STATUS_NO_MEMORY;}RtlZeroMemory(kernelFileContentPtr, kernelFileSize);status = ZwReadFile(kernelFileHandle,NULL,NULL,NULL,&ioStatusBlock,kernelFileContentPtr,kernelFileSize,NULL,NULL);ZwClose(kernelFileHandle);if (!NT_SUCCESS(status)){ExFreePoolWithTag(kernelFileContentPtr, 'TNTC');return status;}//IMAGE_DOS_HEADERPIMAGE_DOS_HEADER imageDosHeaderPtr = (PIMAGE_DOS_HEADER)kernelFileContentPtr;if (imageDosHeaderPtr->e_magic != IMAGE_DOS_SIGNATURE){ExFreePoolWithTag(kernelFileContentPtr, 'TNTC');return STATUS_INVALID_IMAGE_FORMAT;}//IMAGE_NT_HEADERPIMAGE_NT_HEADERS imageNtHeadersPtr = (PIMAGE_NT_HEADERS)(kernelFileContentPtr + imageDosHeaderPtr->e_lfanew);if (imageNtHeadersPtr->Signature != IMAGE_NT_SIGNATURE){ExFreePoolWithTag(kernelFileContentPtr, 'TNTC');return STATUS_INVALID_IMAGE_FORMAT;}ULONG kernelMemorySize = imageNtHeadersPtr->OptionalHeader.SizeOfImage;//为新内核分配内存空间(非分页内存)PUCHAR newKernelBasePtr = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, kernelMemorySize, 'LNRK');if (!newKernelBasePtr){ExFreePoolWithTag(kernelFileContentPtr, 'TNTC');return STATUS_NO_MEMORY;}RtlZeroMemory(newKernelBasePtr, kernelFileSize);//将文件内容中PE头复制到内存区RtlCopyMemory(newKernelBasePtr, kernelFileContentPtr, imageNtHeadersPtr->OptionalHeader.SizeOfHeaders);//按顺序装载各节PIMAGE_SECTION_HEADER imageSectionHeaderPtr = (PIMAGE_SECTION_HEADER)(kernelFileContentPtr + imageDosHeaderPtr->e_lfanew + sizeof(IMAGE_NT_HEADERS));for (int i = 0; i < imageNtHeadersPtr->FileHeader.NumberOfSections; ++i){ULONG sectionVirtualAddress = imageSectionHeaderPtr[i].VirtualAddress;ULONG sectionFileOffset = imageSectionHeaderPtr[i].PointerToRawData;//只映射有效区域ULONG sectionSize = imageSectionHeaderPtr[i].SizeOfRawData <= imageSectionHeaderPtr[i].Misc.VirtualSize ? imageSectionHeaderPtr[i].SizeOfRawData : imageSectionHeaderPtr[i].Misc.VirtualSize;if (sectionSize){RtlCopyMemory(newKernelBasePtr + sectionVirtualAddress, kernelFileContentPtr + sectionFileOffset, sectionSize);}}//以旧内核基址为参考基址对新内核进行基址重定位PIMAGE_BASE_RELOCATION imageBaseRelocationPtr = (PIMAGE_BASE_RELOCATION)(newKernelBasePtr + imageNtHeadersPtr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);while (imageBaseRelocationPtr->SizeOfBlock){PUSHORT relocationDataPtr = (PUSHORT)((PUCHAR)imageBaseRelocationPtr + sizeof(IMAGE_BASE_RELOCATION));for (int i = 0; i < (imageBaseRelocationPtr->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); ++i){if (relocationDataPtr[i] >> 12 == IMAGE_REL_BASED_HIGHLOW){PULONG relocationAddressPtr = (PULONG)(newKernelBasePtr + imageBaseRelocationPtr->VirtualAddress + (relocationDataPtr[i] & 0x0fff));*relocationAddressPtr = *relocationAddressPtr - imageNtHeadersPtr->OptionalHeader.ImageBase + (ULONG)oldKernelBasePtr;}}imageBaseRelocationPtr = (PIMAGE_BASE_RELOCATION)((PUCHAR)imageBaseRelocationPtr + imageBaseRelocationPtr->SizeOfBlock);}//修复被重定位过的系统服务分发表(SSDT), 将其指回新内核对应分发函数入口PSYSTEM_SERVICE_DESCRIPTOR_TABLE systemServiceDescriptorTable = (PSYSTEM_SERVICE_DESCRIPTOR_TABLE)(newKernelBasePtr + (ULONG)KeServiceDescriptorTable - (ULONG)oldKernelBasePtr);systemServiceDescriptorTable->NTOSKRNL.NumberOfService = KeServiceDescriptorTable->NTOSKRNL.NumberOfService;if (KeServiceDescriptorTable->NTOSKRNL.CounterTableBase){systemServiceDescriptorTable->NTOSKRNL.CounterTableBase = (PULONG)(newKernelBasePtr + (ULONG)KeServiceDescriptorTable->NTOSKRNL.CounterTableBase - (ULONG)oldKernelBasePtr);}if (KeServiceDescriptorTable->NTOSKRNL.ParameterTableBase){systemServiceDescriptorTable->NTOSKRNL.ParameterTableBase = (PUCHAR)(newKernelBasePtr + (ULONG)KeServiceDescriptorTable->NTOSKRNL.ParameterTableBase - (ULONG)oldKernelBasePtr);}if (KeServiceDescriptorTable->NTOSKRNL.ServiceTableBase){systemServiceDescriptorTable->NTOSKRNL.ServiceTableBase = (PULONG)(newKernelBasePtr + (ULONG)KeServiceDescriptorTable->NTOSKRNL.ServiceTableBase - (ULONG)oldKernelBasePtr);for (int i = 0; i < systemServiceDescriptorTable->NTOSKRNL.NumberOfService; ++i){systemServiceDescriptorTable->NTOSKRNL.ServiceTableBase[i] += (ULONG)newKernelBasePtr - (ULONG)oldKernelBasePtr;}}ExFreePoolWithTag(kernelFileContentPtr, 'TNTC');*newKernelBasePtrPtr = newKernelBasePtr;*oldKernelBasePtrPtr = oldKernelBasePtr;return STATUS_SUCCESS;}////函数名称:FreeKernel//函数作用:释放加载的内核//参数:kernelBasePtr[IN]:新内核基址//VOID FreeKernel(IN PUCHAR kernelBasePtr){ExFreePoolWithTag(kernelBasePtr, 'LNRK');}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。