From 81137ab62766d676e816e6b0b8b1fee9ca9aadf0 Mon Sep 17 00:00:00 2001 From: gmh5225 <2315157@qq.com> Date: Sun, 12 Feb 2023 21:33:36 +0800 Subject: [PATCH] Update --- Driver-SoulExtraction.vcxproj | 4 + File.cpp | 248 ++++++++++++++++++ File.h | 14 + Lib-SoulExtraction/Lib.SoulExtraction.cpp | 1 + .../rewrite/Lib.SoulExtraction.rewrite.c | 1 + SoulExtraction.cpp | 60 +++++ 6 files changed, 328 insertions(+) create mode 100644 File.cpp create mode 100644 File.h diff --git a/Driver-SoulExtraction.vcxproj b/Driver-SoulExtraction.vcxproj index 425905d..790add4 100644 --- a/Driver-SoulExtraction.vcxproj +++ b/Driver-SoulExtraction.vcxproj @@ -156,8 +156,12 @@ + + + + diff --git a/File.cpp b/File.cpp new file mode 100644 index 0000000..947fd13 --- /dev/null +++ b/File.cpp @@ -0,0 +1,248 @@ +#include "File.h" +#include + +typedef struct _iobuf +{ + void *_Placeholder; +} FILE; + +#define SEEK_CUR 1 +#define SEEK_END 2 +#define SEEK_SET 0 +#define EIO 5 + +#define FILE_POOL_DEFAULT_TAG 'file' + +typedef struct _FILE_CONTROL_BLOCK +{ + HANDLE hFile; + NTSTATUS err; +} FILE_CONTROL_BLOCK; + +FILE_CONTROL_BLOCK * +fget_core(FILE *f) +{ + return (FILE_CONTROL_BLOCK *)f->_Placeholder; +} + +void +fset_core(FILE *f, FILE_CONTROL_BLOCK *fcb) +{ + f->_Placeholder = fcb; +} + +void *__cdecl fopen2(char const *_FileName, char const *_Mode) +{ + NTSTATUS st; + HANDLE hFile; + char *path = NULL; + IO_STATUS_BLOCK isb; + OBJECT_ATTRIBUTES oa; + ANSI_STRING FileNameA; + UNICODE_STRING FileNameW; + + ULONG AccessMask = 0; + ULONG ShareAccess = 0; + ULONG CreateOptions = 0; + ULONG CreateDisposition = 0; + { + char c_r[] = {'r', 0}; + char c_rb[] = {'r', 'b', 0}; + char c_w[] = {'w', 0}; + char c_wb[] = {'w', 'b', 0}; + char c_rw[] = {'r', 'w', 0}; + char c_rwb[] = {'r', 'w', 'b', 0}; + char c_ajia[] = {'a', '+', 0}; + char c_ajiab[] = {'a', '+', 'b', 0}; + char c_abjia[] = {'a', 'b', '+', 0}; + + const char *mode = _Mode; + + if (!strcmp(mode, c_r) || !strcmp(mode, c_rb)) + { + AccessMask = FILE_READ_DATA | FILE_READ_ATTRIBUTES; + CreateDisposition = FILE_OPEN; + } + else if (!strcmp(mode, c_w) || !strcmp(mode, c_wb)) + { + AccessMask = FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES; + CreateDisposition = FILE_SUPERSEDE; + } + else if (!strcmp(mode, c_rw) || !strcmp(mode, c_rwb)) + { + AccessMask = FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES; + CreateDisposition = FILE_OPEN_IF; + } + else if (!strcmp(mode, c_ajia) || !strcmp(mode, c_ajiab) || !strcmp(mode, c_abjia)) + { + AccessMask = + FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_APPEND_DATA; + CreateDisposition = FILE_OPEN_IF; + } + else + { + return NULL; + } + + AccessMask |= SYNCHRONIZE; + ShareAccess = FILE_SHARE_READ; + CreateOptions = FILE_SYNCHRONOUS_IO_NONALERT; + } + + path = (char *)ExAllocatePoolWithTag(PagedPool, 512, FILE_POOL_DEFAULT_TAG); + if (!path) + return NULL; + RtlSecureZeroMemory(path, 512); + + RtlCopyMemory(path, _FileName, min(512, strlen(_FileName))); + + RtlInitAnsiString(&FileNameA, path); + if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&FileNameW, &FileNameA, TRUE))) + { + ExFreePoolWithTag(path, FILE_POOL_DEFAULT_TAG); + return NULL; + } + + InitializeObjectAttributes(&oa, &FileNameW, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); + st = ZwCreateFile( + &hFile, + AccessMask, + &oa, + &isb, + NULL, + FILE_ATTRIBUTE_NORMAL, + ShareAccess, + CreateDisposition, + CreateOptions, + NULL, + 0); + ExFreePoolWithTag(path, FILE_POOL_DEFAULT_TAG); + path = NULL; + RtlFreeUnicodeString(&FileNameW); + + if (!NT_SUCCESS(st)) + return NULL; + + FILE *f = (FILE *)ExAllocatePoolWithTag(PagedPool, sizeof(FILE), FILE_POOL_DEFAULT_TAG); + FILE_CONTROL_BLOCK *fcb = + (FILE_CONTROL_BLOCK *)ExAllocatePoolWithTag(PagedPool, sizeof(FILE_CONTROL_BLOCK), FILE_POOL_DEFAULT_TAG); + fcb->err = 0; + fcb->hFile = hFile; + fset_core(f, fcb); + + return (void *)f; +} + +__int64 __cdecl _ftelli64_2(FILE *_Stream) +{ + IO_STATUS_BLOCK isb; + FILE_POSITION_INFORMATION fpi; + FILE_CONTROL_BLOCK *fcb = fget_core(_Stream); + + fcb->err = ZwQueryInformationFile(fcb->hFile, &isb, &fpi, sizeof(fpi), FilePositionInformation); + if (NT_SUCCESS(fcb->err)) + { + return fpi.CurrentByteOffset.QuadPart; + } + else + { + return -1; + } +} + +int __cdecl _fseeki64_2(FILE *_Stream, __int64 _Offset, int _Origin) +{ + IO_STATUS_BLOCK isb; + FILE_POSITION_INFORMATION fpi; + FILE_CONTROL_BLOCK *fcb = fget_core(_Stream); + + switch (_Origin) + { + case SEEK_CUR: { + long cur_pos = ftell2(_Stream); + + if (cur_pos >= 0) + { + fpi.CurrentByteOffset.QuadPart = cur_pos + _Offset; + fcb->err = ZwSetInformationFile(fcb->hFile, &isb, &fpi, sizeof(fpi), FilePositionInformation); + if (NT_SUCCESS(fcb->err)) + { + return 0; + } + } + } + break; + case SEEK_END: { + FILE_STANDARD_INFORMATION fsi; + + fcb->err = ZwQueryInformationFile(fcb->hFile, &isb, &fsi, sizeof(fsi), FileStandardInformation); + if (NT_SUCCESS(fcb->err)) + { + fpi.CurrentByteOffset.QuadPart = fsi.EndOfFile.QuadPart + _Offset; + + fcb->err = ZwSetInformationFile(fcb->hFile, &isb, &fpi, sizeof(fpi), FilePositionInformation); + if (NT_SUCCESS(fcb->err)) + { + return 0; + } + } + } + break; + case SEEK_SET: { + fpi.CurrentByteOffset.QuadPart = _Offset; + fcb->err = ZwSetInformationFile(fcb->hFile, &isb, &fpi, sizeof(fpi), FilePositionInformation); + if (NT_SUCCESS(fcb->err)) + { + return 0; + } + } + break; + default: + break; + } + + return EIO; +} + +int __cdecl fseek2(void *_Stream, long _Offset, int _Origin) +{ + return _fseeki64_2((FILE *)_Stream, _Offset, _Origin); +} + +long __cdecl ftell2(void *f) +{ + return (long)_ftelli64_2((FILE *)f); +} + +int __cdecl fclose2(void *f) +{ + FILE_CONTROL_BLOCK *fcb = fget_core((FILE *)f); + + ZwClose(fcb->hFile); + ExFreePoolWithTag(fcb, FILE_POOL_DEFAULT_TAG); + ExFreePoolWithTag(f, FILE_POOL_DEFAULT_TAG); + + return 0; +} + +size_t __cdecl fread2(void *Buffer, size_t ElementSize, size_t ElementCount, void *f) +{ + IO_STATUS_BLOCK isb; + FILE_CONTROL_BLOCK *fcb = fget_core((FILE *)f); + size_t rd_size = ElementSize * ElementCount; + + RtlSecureZeroMemory(&isb, sizeof(isb)); + fcb->err = ZwReadFile(fcb->hFile, NULL, NULL, NULL, &isb, Buffer, (ULONG)rd_size, NULL, NULL); + return isb.Information; +} + +size_t __cdecl fwrite2(void const *Buffer, size_t ElementSize, size_t ElementCount, void *f) +{ + IO_STATUS_BLOCK isb; + FILE_CONTROL_BLOCK *fcb = fget_core((FILE *)f); + size_t wt_size = ElementSize * ElementCount; + + RtlSecureZeroMemory(&isb, sizeof(isb)); + fcb->err = ZwWriteFile(fcb->hFile, NULL, NULL, NULL, &isb, (PVOID)Buffer, (ULONG)wt_size, NULL, NULL); + return isb.Information; +} \ No newline at end of file diff --git a/File.h b/File.h new file mode 100644 index 0000000..0fd0c72 --- /dev/null +++ b/File.h @@ -0,0 +1,14 @@ +#pragma once +#include + +void *__cdecl fopen2(char const *_FileName, char const *_Mode); + +int __cdecl fseek2(void *_Stream, long _Offset, int _Origin); + +long __cdecl ftell2(void *f); + +int __cdecl fclose2(void *f); + +size_t __cdecl fread2(void *Buffer, size_t ElementSize, size_t ElementCount, void *f); + +size_t __cdecl fwrite2(void const *Buffer, size_t ElementSize, size_t ElementCount, void *f); diff --git a/Lib-SoulExtraction/Lib.SoulExtraction.cpp b/Lib-SoulExtraction/Lib.SoulExtraction.cpp index 2bed175..60bdb5d 100644 --- a/Lib-SoulExtraction/Lib.SoulExtraction.cpp +++ b/Lib-SoulExtraction/Lib.SoulExtraction.cpp @@ -1,4 +1,5 @@ #include +#include #include "Lib.SoulExtraction.h" extern "C" { diff --git a/Lib-SoulExtraction/rewrite/Lib.SoulExtraction.rewrite.c b/Lib-SoulExtraction/rewrite/Lib.SoulExtraction.rewrite.c index 8dd419b..c4d98f6 100644 --- a/Lib-SoulExtraction/rewrite/Lib.SoulExtraction.rewrite.c +++ b/Lib-SoulExtraction/rewrite/Lib.SoulExtraction.rewrite.c @@ -1,5 +1,6 @@ #include "Lib.SoulExtraction.rewrite.h" #include +#include #define SOUL_POOL_TAG 'SOUL' diff --git a/SoulExtraction.cpp b/SoulExtraction.cpp index 2fe5eab..8b4b8fd 100644 --- a/SoulExtraction.cpp +++ b/SoulExtraction.cpp @@ -1,5 +1,9 @@ #include +#include +#include +#include +#include "File.h" #include "Lib-SoulExtraction/Lib.SoulExtraction.h" #define dprintf(...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, __VA_ARGS__) @@ -17,5 +21,61 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) dprintf("new world\n"); DriverObject->DriverUnload = DriverUnLoad; + // maplestory + void *pf = NULL_CONTEXT; + void *pbuf = NULL; + do + { + pf = fopen2("\\??\\C:\\Windows\\System32\\ntoskrnl.exe", "rb"); + if (!pf) + { + break; + } + + if (0 != fseek2(pf, 0, SEEK_END)) + { + break; + } + + auto file_size = ftell2(pf); + if (0 != fseek2(pf, 0, SEEK_SET)) + { + break; + } + + auto pbuf = ExAllocatePoolWithTag(NonPagedPool, file_size + 10, 'soul'); + if (!pbuf) + { + break; + } + + RtlSecureZeroMemory(pbuf, file_size + 10); + + fread2(pbuf, file_size, 1, pf); + + char main_cert_name[_MAX_PATH + 1]; + RtlSecureZeroMemory(main_cert_name, sizeof(main_cert_name)); + + unsigned long long ValidFromTime = 0; + unsigned long long ValidToTime = 0; + auto bret = LibSoulExtraction::GetMainCertInfo( + pbuf, file_size, main_cert_name, _MAX_PATH, &ValidFromTime, &ValidToTime); + if (bret) + { + dprintf("soul: cert=%s, ValidFromTime=%lld, ValidToTime=%lld\n", main_cert_name, ValidFromTime, ValidToTime); + } + + } while (0); + + if (pbuf) + { + ExFreePoolWithTag(pbuf, 'soul'); + } + + if (pf) + { + fclose2(pf); + } + return STATUS_SUCCESS; }