├── .gitignore ├── EntryPoint.cpp └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /EntryPoint.cpp: -------------------------------------------------------------------------------- 1 | struct memcpy_structure 2 | { 3 | void* destination; 4 | unsigned int max_size; 5 | unsigned int offset; 6 | unsigned char pad[0xF]; 7 | unsigned char error_flag; 8 | }; 9 | 10 | typedef NTSTATUS(* safe_memcpy)(memcpy_structure* dst, void* src, unsigned __int32 size); 11 | safe_memcpy PiDqSerializationWrite; 12 | 13 | #define NT_HEADER(ModBase) (PIMAGE_NT_HEADERS)((ULONG64)(ModBase) + ((PIMAGE_DOS_HEADER)(ModBase))->e_lfanew) 14 | #define IMAGE_FIRST_SECTION(NtHeader) (PIMAGE_SECTION_HEADER)(NtHeader + 1) 15 | #define SizeAlign(Size) ((Size + 0xFFF) & 0xFFFFFFFFFFFFF000) 16 | #define InRange(x, a, b) (x >= a && x <= b) 17 | #define GetBits(x) (InRange(x, '0', '9') ? (x - '0') : ((x - 'A') + 0xA)) 18 | #define GetByte(x) ((UCHAR)(GetBits(x[0]) << 4 | GetBits(x[1]))) 19 | 20 | PVOID FindSection(PVOID ModBase, const char* Name, PULONG SectSize) 21 | { 22 | PIMAGE_NT_HEADERS NT_Header = NT_HEADER(ModBase); 23 | PIMAGE_SECTION_HEADER Sect = IMAGE_FIRST_SECTION(NT_Header); 24 | for (PIMAGE_SECTION_HEADER pSect = Sect; pSect < Sect + NT_Header->FileHeader.NumberOfSections; pSect++) 25 | { 26 | char SectName[9]; SectName[8] = 0; 27 | *(ULONG64*)&SectName[0] = *(ULONG64*)&pSect->Name[0]; 28 | 29 | if (StrICmp(Name, SectName, true)) 30 | { 31 | if (SectSize) 32 | { 33 | ULONG SSize = SizeAlign(max(pSect->Misc.VirtualSize, pSect->SizeOfRawData)); 34 | *SectSize = SSize; 35 | } 36 | 37 | return (PVOID)((ULONG64)ModBase + pSect->VirtualAddress); 38 | } 39 | } 40 | 41 | return nullptr; 42 | } 43 | 44 | PUCHAR FindPatternSect(PVOID ModBase, const char* SectName, const char* Pattern) 45 | { 46 | ULONG SectSize; 47 | PUCHAR ModuleStart = (PUCHAR)FindSection(ModBase, SectName, &SectSize); 48 | PUCHAR ModuleEnd = ModuleStart + SectSize; 49 | 50 | PUCHAR FirstMatch = nullptr; 51 | const char* CurPatt = Pattern; 52 | for (; ModuleStart < ModuleEnd; ++ModuleStart) 53 | { 54 | bool SkipByte = (*CurPatt == '\?'); 55 | if (SkipByte || *ModuleStart == GetByte(CurPatt)) 56 | { 57 | if (!FirstMatch) FirstMatch = ModuleStart; 58 | SkipByte ? CurPatt += 2 : CurPatt += 3; 59 | if (CurPatt[-1] == 0) return FirstMatch; 60 | } 61 | 62 | else if (FirstMatch) 63 | { 64 | ModuleStart = FirstMatch; 65 | FirstMatch = nullptr; 66 | CurPatt = Pattern; 67 | } 68 | } 69 | 70 | return nullptr; 71 | } 72 | 73 | NTSTATUS read_memory(PEPROCESS target_process, void* source, void* target, size_t size) 74 | { 75 | KAPC_STATE ApcState; 76 | KeStackAttachProcess(target_process, &ApcState); 77 | 78 | memcpy_structure _; 79 | _.destination = target; 80 | _.max_size = 0xFFFFFFFF; 81 | _.offset = 0; 82 | memset(_.pad, 0, sizeof(_.pad)); 83 | _.error_flag = 0; 84 | 85 | PiDqSerializationWrite(&_, source, size); 86 | 87 | if (_.error_flag) 88 | { 89 | KeUnstackDetachProcess(&ApcState); 90 | return STATUS_UNSUCCESSFUL; 91 | } 92 | 93 | KeUnstackDetachProcess(&ApcState); 94 | return STATUS_SUCCESS; 95 | } 96 | 97 | EXTERN_C 98 | NTSTATUS DriverEntry( 99 | IN PDRIVER_OBJECT DriverObject, 100 | IN PUNICODE_STRING RegistryPath 101 | ) { 102 | PiDqSerializationWrite = (safe_memcpy)FindPatternSect(GetKernelBase(), "PAGE", "48 89 5C 24 ? 48 89 4C 24 ? 57 48 83 EC 20 41"); 103 | 104 | PEPROCESS target_process = NULL; 105 | if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)2948, &target_process))) 106 | { 107 | unsigned int buf = 0; 108 | read_memory(target_process, (void*)0, (void*)&buf, 4); 109 | } 110 | 111 | return STATUS_UNSUCCESSFUL; 112 | } 113 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PiDqSerializationWrite-Example 2 | Thank you busybox10 for sharing knowledge of util functions and "PiDqSerializationWrite" functions with the community. 3 | 4 | - https://www.unknowncheats.me/forum/3742948-post13.html 5 | 6 | ## CPP 7 | ```cpp 8 | struct memcpy_structure 9 | { 10 | void* destination; 11 | unsigned int max_size; 12 | unsigned int offset; 13 | unsigned char pad[0xF]; 14 | unsigned char error_flag; 15 | }; 16 | 17 | typedef NTSTATUS(* safe_memcpy)(memcpy_structure* dst, void* src, unsigned __int32 size); 18 | safe_memcpy PiDqSerializationWrite; 19 | ``` 20 | ```cpp 21 | #define NT_HEADER(ModBase) (PIMAGE_NT_HEADERS)((ULONG64)(ModBase) + ((PIMAGE_DOS_HEADER)(ModBase))->e_lfanew) 22 | #define IMAGE_FIRST_SECTION(NtHeader) (PIMAGE_SECTION_HEADER)(NtHeader + 1) 23 | #define SizeAlign(Size) ((Size + 0xFFF) & 0xFFFFFFFFFFFFF000) 24 | #define InRange(x, a, b) (x >= a && x <= b) 25 | #define GetBits(x) (InRange(x, '0', '9') ? (x - '0') : ((x - 'A') + 0xA)) 26 | #define GetByte(x) ((UCHAR)(GetBits(x[0]) << 4 | GetBits(x[1]))) 27 | 28 | PVOID FindSection(PVOID ModBase, const char* Name, PULONG SectSize) 29 | { 30 | PIMAGE_NT_HEADERS NT_Header = NT_HEADER(ModBase); 31 | PIMAGE_SECTION_HEADER Sect = IMAGE_FIRST_SECTION(NT_Header); 32 | for (PIMAGE_SECTION_HEADER pSect = Sect; pSect < Sect + NT_Header->FileHeader.NumberOfSections; pSect++) 33 | { 34 | char SectName[9]; SectName[8] = 0; 35 | *(ULONG64*)&SectName[0] = *(ULONG64*)&pSect->Name[0]; 36 | 37 | if (StrICmp(Name, SectName, true)) 38 | { 39 | if (SectSize) 40 | { 41 | ULONG SSize = SizeAlign(max(pSect->Misc.VirtualSize, pSect->SizeOfRawData)); 42 | *SectSize = SSize; 43 | } 44 | 45 | return (PVOID)((ULONG64)ModBase + pSect->VirtualAddress); 46 | } 47 | } 48 | 49 | return nullptr; 50 | } 51 | 52 | PUCHAR FindPatternSect(PVOID ModBase, const char* SectName, const char* Pattern) 53 | { 54 | ULONG SectSize; 55 | PUCHAR ModuleStart = (PUCHAR)FindSection(ModBase, SectName, &SectSize); 56 | PUCHAR ModuleEnd = ModuleStart + SectSize; 57 | 58 | PUCHAR FirstMatch = nullptr; 59 | const char* CurPatt = Pattern; 60 | for (; ModuleStart < ModuleEnd; ++ModuleStart) 61 | { 62 | bool SkipByte = (*CurPatt == '\?'); 63 | if (SkipByte || *ModuleStart == GetByte(CurPatt)) 64 | { 65 | if (!FirstMatch) FirstMatch = ModuleStart; 66 | SkipByte ? CurPatt += 2 : CurPatt += 3; 67 | if (CurPatt[-1] == 0) return FirstMatch; 68 | } 69 | 70 | else if (FirstMatch) 71 | { 72 | ModuleStart = FirstMatch; 73 | FirstMatch = nullptr; 74 | CurPatt = Pattern; 75 | } 76 | } 77 | 78 | return nullptr; 79 | } 80 | ``` 81 | ```cpp 82 | NTSTATUS read_memory(PEPROCESS target_process, void* source, void* target, size_t size) 83 | { 84 | KAPC_STATE ApcState; 85 | KeStackAttachProcess(target_process, &ApcState); 86 | 87 | memcpy_structure _; 88 | _.destination = target; 89 | _.max_size = 0xFFFFFFFF; 90 | _.offset = 0; 91 | memset(_.pad, 0, sizeof(_.pad)); 92 | _.error_flag = 0; 93 | 94 | PiDqSerializationWrite(&_, source, size); 95 | 96 | if (_.error_flag) 97 | { 98 | KeUnstackDetachProcess(&ApcState); 99 | return STATUS_UNSUCCESSFUL; 100 | } 101 | 102 | KeUnstackDetachProcess(&ApcState); 103 | return STATUS_SUCCESS; 104 | } 105 | ``` 106 | ```cpp 107 | EXTERN_C 108 | NTSTATUS DriverEntry( 109 | IN PDRIVER_OBJECT DriverObject, 110 | IN PUNICODE_STRING RegistryPath 111 | ) { 112 | PiDqSerializationWrite = (safe_memcpy)FindPatternSect(GetKernelBase(), "PAGE", "48 89 5C 24 ? 48 89 4C 24 ? 57 48 83 EC 20 41"); 113 | 114 | PEPROCESS target_process = NULL; 115 | if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)2948, &target_process))) 116 | { 117 | unsigned int buf = 0; 118 | read_memory(target_process, (void*)0, (void*)&buf, 4); 119 | } 120 | 121 | return STATUS_UNSUCCESSFUL; 122 | } 123 | ``` 124 | 125 | --------------------------------------------------------------------------------