驱动中使用资源

来源:互联网 发布:人工智能瓶颈 编辑:程序博客网 时间:2024/05/01 22:28
#include <ntddk.h>#include <ntimage.h>#include "resource.h"typedef unsigned long DWORD;PVOID GetFileData(PUNICODE_STRING pFilePath, PULONG puSize);//查找资源ULONG_PTR FindDriverResource(PVOID ImageBase, unsigned int ResID, PULONG_PTR pResSize);//写入文件NTSTATUS WriteResFile(PUNICODE_STRING NewFilePathName, ULONG_PTR pDataOffset, ULONG_PTR uOffsetSize);//加载资源NTSTATUS LoadDriverResource(PVOID ImageBase, unsigned int ResID, PUNICODE_STRING pstrNewPathName);VOID DriverUnload(IN PDRIVER_OBJECT DriverObject){return;}NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath){DriverObject->DriverUnload = DriverUnload;NTSTATUS status;UNICODE_STRING strFilePath;ULONG_PTR uDataSize;PVOID pData = NULL;UNICODE_STRING strNewPathName;DbgBreakPoint();RtlInitUnicodeString(&strFilePath, L"\\??\\c:\\helloworld.sys");pData=GetFileData(&strFilePath, &uDataSize);if (pData && uDataSize>0){RtlInitUnicodeString(&strNewPathName, L"\\??\\c:\\123.exe");status=LoadDriverResource(pData, IDR_IDATA2, &strNewPathName);RtlInitUnicodeString(&strNewPathName, L"\\??\\c:\\456.exe");status = LoadDriverResource(pData, IDR_IDATA1, &strNewPathName);ExFreePool(pData);}return STATUS_SUCCESS;}//加载资源NTSTATUS LoadDriverResource(PVOID ImageBase, unsigned int ResID,PUNICODE_STRING pstrNewPathName){ULONG_PTR uOffsetSize;ULONG_PTR FileOffset;NTSTATUS status;//参数效验if (ImageBase <= 0 || ResID <= 0 ||pstrNewPathName ==NULL)return STATUS_UNSUCCESSFUL;FileOffset = FindDriverResource(ImageBase, ResID, &uOffsetSize);if (FileOffset > 0 && uOffsetSize > 0){status = WriteResFile(pstrNewPathName, (ULONG_PTR)(FileOffset + (ULONG_PTR)ImageBase), uOffsetSize);if (NT_SUCCESS(status)){KdPrint(("写入文件成功\n"));return STATUS_SUCCESS;}else{KdPrint(("写入文件失败\n"));}}return STATUS_UNSUCCESSFUL;}NTSTATUS WriteResFile(PUNICODE_STRING NewFilePathName,ULONG_PTR pDataOffset, ULONG_PTR uOffsetSize){//定义变量OBJECT_ATTRIBUTESOb = { 0 };HANDLEhFile = NULL;IO_STATUS_BLOCKiosb = { 0 };NTSTATUS status= STATUS_UNSUCCESSFUL;PVOID pBuff=NULL;LARGE_INTEGER   ByteOffset = {0};//参数效验if (NewFilePathName == NULL || pDataOffset <= 0 || uOffsetSize <= 0)return status;do {//设置变量pBuff = ExAllocatePool(NonPagedPool, uOffsetSize);if (pBuff == NULL)break;RtlZeroMemory(pBuff, uOffsetSize);RtlCopyMemory(pBuff, pDataOffset, uOffsetSize);InitializeObjectAttributes(&Ob, NewFilePathName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);status = ZwCreateFile(&hFile, FILE_ALL_ACCESS, &Ob, &iosb, 0, FILE_ATTRIBUTE_NORMAL, 0, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);if (!NT_SUCCESS(status))break;status=ZwWriteFile(hFile, NULL, NULL, NULL, &iosb, pBuff, uOffsetSize, &ByteOffset, NULL);if (!NT_SUCCESS(status))break;if (iosb.Information != uOffsetSize)break;status = STATUS_SUCCESS;} while (FALSE);if (pBuff)ExFreePool(pBuff);if (hFile)ZwClose(hFile);return status;}PVOID GetFileData(PUNICODE_STRING pFilePath, PULONG puSize){NTSTATUS status = STATUS_UNSUCCESSFUL;PVOID pData = NULL;OBJECT_ATTRIBUTESOb = { 0 };HANDLEhFile = NULL;IO_STATUS_BLOCKiosb = { 0 };FILE_STANDARD_INFORMATION FileInfo = { 0 };do{InitializeObjectAttributes(&Ob, pFilePath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);status = ZwCreateFile(&hFile, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &Ob, &iosb, 0, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);if (!NT_SUCCESS(status)){break;}status = ZwQueryInformationFile(hFile, &iosb, &FileInfo, sizeof(FileInfo), FileStandardInformation);if (!NT_SUCCESS(status)){break;}pData = (PVOID)ExAllocatePool(NonPagedPool, FileInfo.EndOfFile.QuadPart);if (pData == NULL){break;}RtlZeroMemory(pData, FileInfo.EndOfFile.QuadPart);LARGE_INTEGER ByteOffset = { 0 };status = ZwReadFile(hFile, NULL, NULL, NULL, &iosb, pData, FileInfo.EndOfFile.QuadPart, &ByteOffset, NULL);if (!NT_SUCCESS(status)){break;}*puSize = FileInfo.EndOfFile.QuadPart;status = STATUS_SUCCESS;} while (FALSE);if (!NT_SUCCESS(status)){if (pData != NULL){ExFreePool(pData);pData = NULL;}}if (hFile != NULL){ZwClose(hFile);}return pData;}DWORD RVA2Offset(DWORD dwRva, PIMAGE_NT_HEADERS pNt){//定义变量DWORD dwOffset = 0;PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNt);//参数效验if (dwRva <= 0 || pNt <= 0)return 0;for (DWORD i = 0; i < pNt->FileHeader.NumberOfSections; i++){//判断在哪个区段 并且进行转换if (dwRva >= pSection[i].VirtualAddress &&dwRva < (pSection[i].Misc.VirtualSize + pSection[i].VirtualAddress)){dwOffset = dwRva - pSection[i].VirtualAddress + pSection[i].PointerToRawData;return dwOffset;}}return NULL;}PIMAGE_SECTION_HEADER RtlSectionTableFromVirtualAddress(PIMAGE_NT_HEADERS NtHeaders, PVOID Base, ULONG Address){//定义变量ULONG i;PIMAGE_SECTION_HEADER NtSection;//参数效验if (NtHeaders <= 0 || Base <= 0 || Address <= 0)return NULL;NtSection = IMAGE_FIRST_SECTION(NtHeaders);for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)//块(section)数目{if ((ULONG)Address >= NtSection->VirtualAddress && (ULONG)Address < NtSection->VirtualAddress + NtSection->SizeOfRawData){return NtSection;}++NtSection;}return NULL;}ULONG_PTR RVAFileOffset(PIMAGE_SECTION_HEADER section, ULONG_PTR dwRVA){ULONG_PTR  Fileoffset;//参数效验if (section <= 0 || dwRVA <= 0)return NULL;Fileoffset = dwRVA + section->PointerToRawData - section->VirtualAddress;return Fileoffset;//50A0+1C00-5000}//查找资源ULONG_PTR FindDriverResource(PVOID ImageBase, unsigned int ResID, PULONG_PTR pResSize){//定义变量  DWORD dwResSize = 0;PIMAGE_DATA_DIRECTORY   pImageDataDirtry;//资源目录表DWORD dwResDirtryOffset;//资源目录表的偏移ULONG ResourceRVA;ULONG_PTR Fileoffset = 0;PIMAGE_SECTION_HEADER NtSection;NTSTATUS Status;#ifdef _WIN64  PIMAGE_NT_HEADERS64 NtHdr;#elsePIMAGE_NT_HEADERS32 NtHdr;#endif//参数效验if (ImageBase <= 0 || ResID <= 0 || pResSize <= 0)return NULL;try{do{//获取DOS头PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)ImageBase;if (IMAGE_DOS_SIGNATURE != dosheader->e_magic)break;#ifdef _WIN64  //NT头  NtHdr = (PIMAGE_NT_HEADERS64)((CHAR*)ImageBase + dosheader->e_lfanew);#else  //NT头  NtHdr = (PIMAGE_NT_HEADERS32)((CHAR*)ImageBase + dosheader->e_lfanew);#endif //效验是否PE头  if (NtHdr->Signature != IMAGE_NT_SIGNATURE)break;pImageDataDirtry = NtHdr->OptionalHeader.DataDirectory;if (pImageDataDirtry == NULL)break;pImageDataDirtry = &(pImageDataDirtry[IMAGE_DIRECTORY_ENTRY_RESOURCE]);if (pImageDataDirtry->VirtualAddress <= 0 || pImageDataDirtry->Size <= 0)break;dwResDirtryOffset = RVA2Offset(pImageDataDirtry->VirtualAddress, NtHdr);if (dwResDirtryOffset <= 0)break;PIMAGE_RESOURCE_DIRECTORY  pRes = (PIMAGE_RESOURCE_DIRECTORY)((ULONG_PTR)ImageBase + dwResDirtryOffset);if (pRes <= 0)break;//获取紧跟着的IMAGE_RESOURCE_DIRECTORY_ENTRY的个数dwResSize = pRes->NumberOfNamedEntries + pRes->NumberOfIdEntries;if (dwResSize <= 0)break;//获取到PIMAGE_RESOURCE_DIRECTORY_ENTRY PIMAGE_RESOURCE_DIRECTORY_ENTRY  pResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes + 1);if (pResEntry <= 0)break;if (NtHdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC){ResourceRVA = ((PIMAGE_NT_HEADERS32)NtHdr)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;}else if (NtHdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC){ResourceRVA = ((PIMAGE_NT_HEADERS64)NtHdr)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;}else{break;}NtSection = RtlSectionTableFromVirtualAddress(NtHdr, ImageBase, ResourceRVA);if (NtSection <= 0)break;for (DWORD i = 0; i < dwResSize; i++){// 获取第二层目录的偏移if (pResEntry[i].DataIsDirectory <= 0)continue;PIMAGE_RESOURCE_DIRECTORY pRes2 = (PIMAGE_RESOURCE_DIRECTORY)((ULONG_PTR)pRes + pResEntry[i].OffsetToDirectory);DWORD dwCount = pRes2->NumberOfIdEntries + pRes2->NumberOfNamedEntries;if (dwCount <= 0)continue;PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes2 + 1);for (DWORD i = 0; i < dwCount; i++){if (pResEntry2[i].Id == ResID){// 解析第三层目录PIMAGE_RESOURCE_DIRECTORY pRes3 = (PIMAGE_RESOURCE_DIRECTORY)((ULONG_PTR)pRes + pResEntry2[i].OffsetToDirectory);PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry3 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes3 + 1);if (!pResEntry3[i].DataIsDirectory){// 取数据偏移,显示数据PIMAGE_RESOURCE_DATA_ENTRY pResData = (PIMAGE_RESOURCE_DATA_ENTRY)((ULONG_PTR)pRes + pResEntry3->OffsetToData);//设置变量*pResSize = pResData->Size;Fileoffset = RVAFileOffset(NtSection, pResData->OffsetToData);KdPrint(("->->->数据RVA:%p  FileOffset%p 数据大小:%p\n", pResData->OffsetToData, Fileoffset, pResData->Size));return Fileoffset;}}}}} while (FALSE);}except(EXCEPTION_EXECUTE_HANDLER){Status = GetExceptionCode();}return NULL;}

0 0