#include "precomp.h" #include "ntstrsafe.h" #include #define NT_PROCNAMELEN 16 #define SYSNAME "System" #define PAGE_SIZE 0x1000 typedef NTSTATUS(*ZwQueryInformationProcessT)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); ZwQueryInformationProcessT ZwQueryInformationProcess = NULL; #define MEDIA_POOL_TAG 'cdsa' PVOID UAlloc(SIZE_T size) { PUCHAR buffer = NULL; buffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, size, MEDIA_POOL_TAG); if (!buffer) return NULL; RtlZeroMemory(buffer, size); return (PVOID)buffer; } VOID UFree(PVOID* buf) { if (*buf) { ExFreePoolWithTag(*buf, MEDIA_POOL_TAG); *buf = NULL; } return; } NTSTATUS UStrNew(PUNICODE_STRING ustr, USHORT bytes) { ustr->Buffer = UAlloc(bytes + sizeof(wchar_t)); if (!ustr->Buffer) return STATUS_INSUFFICIENT_RESOURCES; ustr->MaximumLength = (USHORT)bytes; ustr->Length = 0; RtlZeroMemory(ustr->Buffer, bytes + sizeof(wchar_t)); return STATUS_SUCCESS; } NTSTATUS UStrFree(PUNICODE_STRING ustr) { if (!ustr->Buffer) return STATUS_INVALID_PARAMETER; ustr->Length = 0; ustr->MaximumLength = 0; UFree(&ustr->Buffer); return STATUS_SUCCESS; } NTSTATUS UStrCopy(PUNICODE_STRING dst, PUNICODE_STRING src) { if (dst->MaximumLength <= src->Length + sizeof(wchar_t)) { return STATUS_INSUFFICIENT_RESOURCES; } RtlUnicodeStringCopy(dst, src); return STATUS_SUCCESS; } NTSTATUS UStrCatC(PUNICODE_STRING ustr, LPCSTR str) { UNREFERENCED_PARAMETER(ustr); UNREFERENCED_PARAMETER(str); return STATUS_UNSUCCESSFUL; } NTSTATUS UStrCatW(PUNICODE_STRING ustr, LPWSTR str) { UNICODE_STRING tmp; RtlInitUnicodeString(&tmp, str); return UStrCat(ustr, &tmp); } NTSTATUS UStrCatA(PUNICODE_STRING ustr, PANSI_STRING str) { UNREFERENCED_PARAMETER(ustr); UNREFERENCED_PARAMETER(str); return STATUS_UNSUCCESSFUL; } NTSTATUS UStrCat(PUNICODE_STRING ustr, PUNICODE_STRING str) { USHORT r; r = ustr->MaximumLength - ustr->Length; if (r < str->Length) return STATUS_UNSUCCESSFUL; RtlCopyMemory(GetPtr(ustr->Buffer, ustr->Length), str->Buffer, str->Length + sizeof(wchar_t)); ustr->Length += str->Length; return STATUS_SUCCESS; } BOOLEAN ISWcstok(WCHAR* pwszSrc, WCHAR* pwszDest, ULONG ulSrcLen, const WCHAR pwszToken, BOOLEAN bNetFlag) { //BOOLEAN bRet = TRUE; ULONG ulCnt = 0; ULONG i = 0; if (pwszSrc == NULL || ulSrcLen == 0) { return FALSE; } while (ulCnt < ulSrcLen) { if (pwszSrc[ulCnt] == pwszToken) break; pwszDest[ulCnt] = pwszSrc[ulCnt]; ulCnt++; } ulCnt++; if (ulCnt >= ulSrcLen) return FALSE; if (!bNetFlag) return TRUE; ulSrcLen -= ulCnt; memset(pwszDest, 0, sizeof(WCHAR) * 260); while (i < ulSrcLen) { if (pwszSrc[ulCnt] == pwszToken) break; pwszDest[i] = pwszSrc[ulCnt]; i++; ulCnt++; } return TRUE; } NTSTATUS UGetCurrentStackProcessImageName(ULONG processId, PUNICODE_STRING ProcessImageName) { NTSTATUS status = STATUS_SUCCESS; ULONG returnedLength = 0; ULONG bufferLength = 0; //HANDLE hProcess = NULL; PVOID buffer = NULL; //PEPROCESS eProcess = NULL; //PUNICODE_STRING imageName; PAGED_CODE(); if (processId == 0 || processId == 4 || processId == 8) { return STATUS_UNSUCCESSFUL; } if (ZwQueryInformationProcess == NULL) { UNICODE_STRING routineName; RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess"); ZwQueryInformationProcess = (ZwQueryInformationProcessT)MmGetSystemRoutineAddress(&routineName); if (ZwQueryInformationProcess == NULL) { return STATUS_UNSUCCESSFUL; } } // status = PsLookupProcessByProcessId((HANDLE)processId, &eProcess); // // if(NT_SUCCESS(status)) // { // status = ObOpenObjectByPointer(eProcess,0, NULL, 0,*PsProcessType,KernelMode,&hProcess); // ObDereferenceObject(eProcess); // if(!NT_SUCCESS(status)) // { // // sskim - 171117 Added. // hProcessID = NULL; // return STATUS_UNSUCCESSFUL; // } // // KLogEx(DEBUG_TRACE_INFO,"hProcess(%p)\n", hProcess); // // } // else // { // // sskim - 171117 Added. // hProcessID = NULL; // return status; // } status = ZwQueryInformationProcess(NtCurrentProcess(), ProcessImageFileName, NULL, 0, &returnedLength); if (status != STATUS_INFO_LENGTH_MISMATCH) { status = STATUS_UNSUCCESSFUL; goto $cleanup; } bufferLength = returnedLength + sizeof(UNICODE_STRING) + sizeof(WCHAR); buffer = UAlloc(bufferLength); if (!buffer) { status = STATUS_UNSUCCESSFUL; goto $cleanup; } if (!NT_SUCCESS(UStrNew(ProcessImageName, (USHORT)bufferLength))) { status = STATUS_UNSUCCESSFUL; goto $cleanup; } status = ZwQueryInformationProcess(NtCurrentProcess(), ProcessImageFileName, (PVOID)buffer, returnedLength, &returnedLength); if (NT_SUCCESS(status)) { RtlCopyUnicodeString(ProcessImageName, (PUNICODE_STRING)buffer); } else { UStrFree(ProcessImageName); } $cleanup: /// 2014-04-03 ÇÁ·Î¼¼½º ÇÚµé Áõ°¡ ¹®Á¦°¡ º¸°í µÇ¼­ Ãß°¡ // if(hProcess != NULL) // ZwClose(hProcess); UFree(&buffer); return status; } ULONG UGetKernelVersion() { ULONG mj = 0; ULONG mi = 0; RTL_OSVERSIONINFOW os; //PsGetVersion(&mj, &mi, NULL, NULL); RtlGetVersion(&os); mj = os.dwMajorVersion; mi = os.dwMinorVersion; KLogEx(DEBUG_TRACE_INFO, "%d %d\n", mj, mi); if (mj == 10) { if (mi > 22000) return (ULONG)Win11; return (ULONG)Win10; } else if (mj == 6 && mi == 2) { return (ULONG)Win8; } else if (mj == 6 && mi == 1) { return (ULONG)Win7; } else if (mj == 6 && mi == 0) { // vista, server 2008 return (ULONG)WinVista; } else if ((mj == 5 && mi == 1)) { // XP return (ULONG)WinXP; } else if (mj == 5 && mi == 2) { // 2003, 2003 R2 return (ULONG)Win2k3; } else if (mj == 5 && mi == 0) { // 2000 , NT return (ULONG)Win2k; } return (ULONG)WinUndefined; } PLIST_ENTRY WalkList(PLIST_ENTRY head, WalkCallbackFuncT fn, PVOID p, ULONG d) { PLIST_ENTRY current, tail, tmp; tail = head; current = tail->Flink; while (tail != current) { tmp = current; current = current->Flink; __try { if (!fn(tmp, p, d)) return tmp; } __except (EXCEPTION_EXECUTE_HANDLER) { return NULL; } } return NULL; } PLIST_ENTRY WalkListPoint(PLIST_ENTRY head, WalkCallbackFuncPointT fn, PVOID p1, PVOID p2) { PLIST_ENTRY current, tail, tmp; tail = head; current = tail->Flink; while (tail != current) { tmp = current; current = current->Flink; __try { if (!fn(tmp, p1, p2)) return tmp; } __except (EXCEPTION_EXECUTE_HANDLER) { return NULL; } } return NULL; } NTSTATUS UGetProcessFullPathFromPid( _In_ HANDLE pid, _Out_writes_bytes_opt_(PathBufferSize) PWCHAR PathBuffer, _In_ ULONG PathBufferSize, _Out_writes_bytes_opt_(NameBufferSize) PWCHAR NameBuffer, _In_ ULONG NameBufferSize ) { NTSTATUS status; PEPROCESS Process = NULL; PUNICODE_STRING pImageName = NULL; // PID·Î EPROCESS °´Ã¼ ÂüÁ¶ status = PsLookupProcessByProcessId(pid, &Process); if (!NT_SUCCESS(status)) { return status; } // Àüü °æ·Î(Image Name) °¡Á®¿À±â status = SeLocateProcessImageName(Process, &pImageName); if (NT_SUCCESS(status) && pImageName != NULL) { // Àüü °æ·Î º¹»ç (¿äû ½Ã) if (PathBuffer != NULL && PathBufferSize > 0) { RtlStringCbCopyW(PathBuffer, PathBufferSize, pImageName->Buffer); } // ÆÄÀϸí ÃßÃâ ¹× º¹»ç (¿äû ½Ã) if (NameBuffer != NULL && NameBufferSize > 0) { // µÚ¿¡¼­ºÎÅÍ '\' ¹®ÀÚ¸¦ ãÀ½ WCHAR* pFileName = wcsrchr(pImageName->Buffer, L'\\'); if (pFileName) { pFileName++; // '\' ´ÙÀ½ ±ÛÀÚ°¡ ÆÄÀÏ À̸§ ½ÃÀÛ } else { pFileName = pImageName->Buffer; // '\'°¡ ¾øÀ¸¸é Àüü°¡ À̸§ } RtlStringCbCopyW(NameBuffer, NameBufferSize, pFileName); } // ¸Þ¸ð¸® ÇØÁ¦ ExFreePool(pImageName); } else { // ½ÇÆÐ ½Ã ºó ¹®ÀÚ¿­ ó¸® if (PathBuffer && PathBufferSize > 0) PathBuffer[0] = L'\0'; if (NameBuffer && NameBufferSize > 0) NameBuffer[0] = L'\0'; } // ÇÁ·Î¼¼½º °´Ã¼ ÂüÁ¶ ÇØÁ¦ ObDereferenceObject(Process); return status; } static ULONG s_ProcessNameOffset = 0; ULONG USetProcessNameOffset(void) { PEPROCESS curproc = NULL; DWORD i = 0; curproc = PsGetCurrentProcess(); if (curproc != NULL) { for (i = 0; i < 3 * PAGE_SIZE; i++) { if (!memcmp(SYSNAME, (PCHAR)curproc + i, 6)) { break; } } } s_ProcessNameOffset = i; KLogEx(DEBUG_TRACE_INFO, "offset(%x)\n", s_ProcessNameOffset); return i; } BOOLEAN UGetProcessName(PCHAR theName) { PEPROCESS curproc = NULL; char* nameptr = NULL; if (s_ProcessNameOffset) { // if ( g_uiProcessNameOffset > 0x450) // { // // bug da~ // g_uiProcessNameOffset = 0x174; // XPÀϰæ¿ì // // KdPrint(("bug da~2, %x\n", gProcessNameOffset)); // } curproc = PsGetCurrentProcess(); nameptr = (PCHAR)curproc + s_ProcessNameOffset; memcpy(theName, nameptr, NT_PROCNAMELEN); theName[NT_PROCNAMELEN] = 0; /* NULL at end */ return TRUE; } return FALSE; } extern UCHAR* PsGetProcessImageFileName(IN PEPROCESS Process); NTSTATUS UGetProcessNameFromPid( _In_ HANDLE pid, _Out_writes_bytes_(BufferSize) PCHAR Buffer, _In_ ULONG BufferSize ) { PEPROCESS Process = NULL; NTSTATUS status; status = PsLookupProcessByProcessId(pid, &Process); if (!NT_SUCCESS(status)) { if (BufferSize > 0) { RtlStringCbCopyA(Buffer, BufferSize, "Unknown0"); } return status; } PCHAR pName = (PCHAR)PsGetProcessImageFileName(Process); if (pName) { status = RtlStringCbCopyA(Buffer, BufferSize, pName); } else { status = STATUS_NOT_FOUND; if (BufferSize > 0) RtlStringCbCopyA(Buffer, BufferSize, "Unknown1"); //Buffer[0] = '\0'; } ObDereferenceObject(Process); return status; } //BOOLEAN UGetProcessNameFormPid(PCHAR theName, HANDLE pid) //{ // PEPROCESS curproc = NULL; // char* nameptr = NULL; // // if (KeGetCurrentIrql() > PASSIVE_LEVEL) // return FALSE; // // if (PsLookupProcessByProcessId(pid, &curproc) == STATUS_INVALID_PARAMETER) // { // return "??"; // } // nameptr = PsGetProcessImageFileName(curproc); // ObDereferenceObject(curproc); // return (CHAR*) // // //if (!s_ProcessNameOffset) // // return FALSE; // // //// if ( g_uiProcessNameOffset > 0x450) // //// { // //// // bug da~ // //// g_uiProcessNameOffset = 0x174; // XPÀϰæ¿ì // //// // KdPrint(("bug da~2, %x\n", gProcessNameOffset)); // //// } // //if (PsLookupProcessByProcessId(pid, &curproc) == STATUS_SUCCESS) // //{ // // //curproc = PsGetCurrentProcess(); // // // nameptr = (PCHAR)curproc + s_ProcessNameOffset; // // memcpy(theName, nameptr, NT_PROCNAMELEN); // // theName[NT_PROCNAMELEN] = 0; /* NULL at end */ // // ObDereferenceObject(curproc); // // return TRUE; // //} // // return FALSE; //} NTSTATUS UDeleteFile(wchar_t* path) { OBJECT_ATTRIBUTES oa; UNICODE_STRING FileNameUnicode; // WCHAR szTemp[300] = L"\\??\\"; //HANDLE Directory = NULL; NTSTATUS ntStatus = STATUS_SUCCESS; // wcscat( szTemp , path ); RtlInitUnicodeString(&FileNameUnicode, path); InitializeObjectAttributes(&oa, &FileNameUnicode, OBJ_CASE_INSENSITIVE, NULL, NULL); ntStatus = ZwDeleteFile(&oa); return ntStatus; } NTSTATUS UTerminateProcess(ULONG pid) { HANDLE ProcessHandle = NULL; OBJECT_ATTRIBUTES ObjectAttributes = { 0, }; CLIENT_ID ClientId = { 0, }; NTSTATUS NtStatus = STATUS_SUCCESS; ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); ObjectAttributes.RootDirectory = NULL; ObjectAttributes.ObjectName = NULL; ObjectAttributes.Attributes = OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE; ObjectAttributes.SecurityDescriptor = NULL; ObjectAttributes.SecurityQualityOfService = NULL; ClientId.UniqueThread = 0; ClientId.UniqueProcess = (HANDLE)pid; NtStatus = ZwOpenProcess( &ProcessHandle, PROCESS_ALL_ACCESS, &ObjectAttributes, &ClientId); if (!NT_SUCCESS(NtStatus)) { return NtStatus; } NtStatus = ZwTerminateProcess(ProcessHandle, STATUS_SUCCESS); if (ProcessHandle) ZwClose(ProcessHandle); return NtStatus; } BOOLEAN UGetDosFilePath(PFLT_VOLUME pVolume, UNICODE_STRING FilePath, PUNICODE_STRING OUT pDosFilePath) { NTSTATUS status = 0; BOOLEAN bResult = FALSE; PDEVICE_OBJECT devObj = NULL; UNICODE_STRING VolumeName = { 0, }; UNICODE_STRING DosVolumeName = { 0, }; ULONG ulBufferNeeded = 0; ULONG ulVolumeNameLength = 0; if (pVolume == NULL) { return FALSE; } status = FltGetDiskDeviceObject(pVolume, &devObj); if (NT_SUCCESS(status)) { status = FltGetVolumeName(pVolume, NULL, &ulBufferNeeded); if (status == STATUS_BUFFER_TOO_SMALL) { status = UStrNew(&VolumeName, (USHORT)(ulBufferNeeded + 1)); if (NT_SUCCESS(status)) { status = FltGetVolumeName(pVolume, &VolumeName, &ulBufferNeeded); if (NT_SUCCESS(status)) { status = RtlVolumeDeviceToDosName(devObj, &DosVolumeName); if (NT_SUCCESS(status) && VolumeName.Buffer != NULL) { ulVolumeNameLength = (ULONG)wcslen(VolumeName.Buffer); status = UStrNew(pDosFilePath, DosVolumeName.MaximumLength + FilePath.MaximumLength); if (NT_SUCCESS(status)) { UStrCopy(pDosFilePath, &DosVolumeName); wcscat(pDosFilePath->Buffer, FilePath.Buffer + ulVolumeNameLength); bResult = TRUE; } } else { KLogEx(DEBUG_TRACE_INFO, "RtlVolumeDeviceToDosName Return Fail %x \n", status); } } else { KLogEx(DEBUG_TRACE_ERROR, "FltGetVolumeName(2) Return Fail %x \n", status); } } else { KLogEx(DEBUG_TRACE_ERROR, "IStrNew Return Fail %x \n", status); } UStrFree(&VolumeName); } else { KLogEx(DEBUG_TRACE_ERROR, "FltGetVolumeName(1) Return Fail %x \n", status); } } else { KLogEx(DEBUG_TRACE_ERROR, "FltGetDiskDeviceObject Return Fail %x \n", status); } return bResult; } PFN_IoOpenDriverRegistryKey UGetIoOpenDriverRegistryKey( VOID ) { static PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey = NULL; UNICODE_STRING FunctionName = { 0 }; if (pIoOpenDriverRegistryKey == NULL) { RtlInitUnicodeString(&FunctionName, L"IoOpenDriverRegistryKey"); pIoOpenDriverRegistryKey = (PFN_IoOpenDriverRegistryKey)MmGetSystemRoutineAddress(&FunctionName); } return pIoOpenDriverRegistryKey; } NTSTATUS UOpenServiceParametersKey( _In_ PUNICODE_STRING RegistryPath, _Out_ PHANDLE ServiceParametersKey ) { NTSTATUS Status; HANDLE ServiceKey = NULL; HANDLE ParametersKey = NULL; OBJECT_ATTRIBUTES Attributes; UNICODE_STRING SubKeyName; // 1. ¼­ºñ½º ·çÆ® Ű ¿­±â (\Registry\...\bs1flt) InitializeObjectAttributes(&Attributes, RegistryPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenKey(&ServiceKey, KEY_READ, &Attributes); if (!NT_SUCCESS(Status)) { return Status; } // 2. "Parameters" ¼­ºê Ű ¿­±â RtlInitUnicodeString(&SubKeyName, L"Parameters"); InitializeObjectAttributes(&Attributes, &SubKeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, ServiceKey, NULL); Status = ZwOpenKey(&ParametersKey, KEY_READ, &Attributes); // 3. ¼­ºñ½º ·çÆ® Ű´Â ÀÌÁ¦ ÇÊ¿ä ¾øÀ¸¹Ç·Î ´ÝÀ½ ZwClose(ServiceKey); if (NT_SUCCESS(Status)) { *ServiceParametersKey = ParametersKey; } return Status; } ///NTSTATUS USetConfiguration(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath); NTSTATUS USetConfiguration( _In_ PUNICODE_STRING RegistryPath // DriverObject´Â ÇÊ¿ä ¾øÀ½ ) { NTSTATUS status; HANDLE settingsKey = NULL; UNICODE_STRING valueName; // ¹öÆÛ Å©±â¸¦ ³Ë³ËÇÏ°Ô ÀâÀ½ (µ¥ÀÌÅͰ¡ ULONGÀÌ ¾Æ´Ò ¼öµµ ÀÖÀ¸¹Ç·Î) UCHAR buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)]; PKEY_VALUE_PARTIAL_INFORMATION value = (PKEY_VALUE_PARTIAL_INFORMATION)buffer; ULONG resultLength; // 1. Parameters Ű ¿­±â status = UOpenServiceParametersKey(RegistryPath, &settingsKey); if (!NT_SUCCESS(status)) { return STATUS_SUCCESS; } // 2. DebugLevel °ª Àбâ RtlInitUnicodeString(&valueName, L"DebugLevel"); status = ZwQueryValueKey(settingsKey, &valueName, KeyValuePartialInformation, value, sizeof(buffer), &resultLength); if (NT_SUCCESS(status) && value->Type == REG_DWORD) { // Àü¿ª º¯¼ö ¼³Á¤ (extern ¼±¾ð ÇÊ¿ä) g_DebugLevel = *(PULONG)value->Data; } // 3. ProcessCreate °ª Àбâ RtlInitUnicodeString(&valueName, L"ProcessCreate"); status = ZwQueryValueKey(settingsKey, &valueName, KeyValuePartialInformation, value, sizeof(buffer), &resultLength); if (NT_SUCCESS(status) && value->Type == REG_DWORD) { g_bs1Flt.IsProcessCreate = *(PULONG)value->Data; } // 4. ÇÚµé ´Ý±â (Çʼö) ZwClose(settingsKey); return STATUS_SUCCESS; } //NTSTATUS //ObOpenObjectByName( // IN POBJECT_ATTRIBUTES ObjectAttributes, // IN ULONG_PTR OPTIONAL, // IN ULONG AccessMode, // IN ULONG OPTIONAL2, // IN ULONG DesiredAccess OPTIONAL, // IN OUT PVOID ParseContext OPTIONAL, // OUT PHANDLE Handle //); NTSYSAPI NTSTATUS NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectPath, IN ULONG Attributes, IN PACCESS_STATE PassedAccessState OPTIONAL, IN ACCESS_MASK DesiredAccess OPTIONAL, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, OUT PVOID* ObjectPtr ); extern POBJECT_TYPE* IoDriverObjectType; PDRIVER_OBJECT SearchDriverObject(WCHAR* name) { NTSTATUS st; //HANDLE Handle; //OBJECT_ATTRIBUTES ObjectAttributes; PDRIVER_OBJECT Object; UNICODE_STRING Uni; RtlInitUnicodeString(&Uni, name); st = ObReferenceObjectByName(&Uni, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, KernelMode, NULL, &Object); if (st != STATUS_SUCCESS) { // SHOW_DEBUG(("ObReferenceObjectByName fail(0x%X)", ntStatus)); return (PDRIVER_OBJECT)0; } ObDereferenceObject(Object); /* RtlInitUnicodeString(&Uni, name); InitializeObjectAttributes(&ObjectAttributes, &Uni, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); st = ObOpenObjectByName(&ObjectAttributes, (ULONG_PTR)*IoDriverObjectType, KernelMode, 0L, 0L, 0L, &Handle); if (st != STATUS_SUCCESS) { KLogEx(DEBUG_TRACE_INFO, "ObOpenObjectByName status(%08x)\n", st); return (PDRIVER_OBJECT)0; } st = ObReferenceObjectByHandle(Handle, 0x80000000, NULL, KernelMode, &Object, NULL); if (st != STATUS_SUCCESS) { ZwClose(Handle); KLogEx(DEBUG_TRACE_INFO, "ObReferenceObjectByHandle status(%08x)\n", st); return (PDRIVER_OBJECT)0; } ZwClose(Handle); ObDereferenceObject(Object); */ return Object; } DWORD IsExceptionProcess(PPROCESS_MANAGER proccess_manager, ULONG cnt, WCHAR* processname) { //ULONG type = 0; ULONG i = 0; for (i = 0; i < cnt; ++i) { if (_wcsnicmp(processname, proccess_manager[i].path, proccess_manager[i].size) == 0) return proccess_manager[i].type; } return PG_PID_UNDEFINED; } int ISWtoi(const WCHAR* pwszStr) { int dwRet = 0; int dwTemp = 1; int nCnt = (int)wcslen(pwszStr) - (int)1; while (nCnt >= 0) { if (pwszStr[nCnt] >= L'0' && pwszStr[nCnt] <= L'9') { dwRet += ((pwszStr[nCnt] - 48) * dwTemp); dwTemp *= 10; } nCnt--; } return dwRet; } VOID ISIPAddressToInt(PWCHAR ip_address, const ULONG ulLen, ULONG* pulIP) { WCHAR wszTemp[4][4] = { 0, }; ULONG ulTempIP = 0; ULONG nlCnt = 0; int nShift = 24; int i = 0; int j = 0; for (nlCnt = 0; nlCnt < ulLen; nlCnt++) { if (ip_address[nlCnt] == L'.') { i++; j = 0; continue; } wszTemp[i][j] = ip_address[nlCnt]; j++; } for (nlCnt = 0; nlCnt < 4; nlCnt++) { ulTempIP = ISWtoi(wszTemp[nlCnt]); if (nlCnt == 3) { *pulIP |= ulTempIP; } else { *pulIP |= ulTempIP << nShift; } nShift -= 8; } } BOOLEAN ISIPAddress(PWCHAR pwszPath, const ULONG ulLen) { BOOLEAN bReturn = TRUE; ULONG ulPeriod = 0; ULONG ulCnt = 0; if (ulLen < 7 || ulLen > 15) { return FALSE; } for (ulCnt = 0; ulCnt < ulLen; ulCnt++) { if (pwszPath[ulCnt] == L'.') { ulPeriod++; continue; } if (!(pwszPath[ulCnt] >= L'0' && pwszPath[ulCnt] <= L'9')) { bReturn = FALSE; break; } } if (ulPeriod != 3) { bReturn = FALSE; } return bReturn; } void PrintHexData(unsigned char* data, int datalength) { char szBuffer[128] = { 0, }; size_t cbDest = sizeof(szBuffer); size_t cbCurrentLen = 0; int i = 0; if (data == NULL || datalength <= 0) return; for (i = 0; i < datalength; i++) { // ¹öÆÛ ³¡¿¡ ÀÌ¾î ºÙÀ̱â RtlStringCbPrintfA(szBuffer + cbCurrentLen, cbDest - cbCurrentLen, "%02X ", data[i]); cbCurrentLen += 3; // "XX " 3¹ÙÀÌÆ® Áõ°¡ // 32¹ÙÀÌÆ® ´ÜÀ§ ȤÀº ¸¶Áö¸· µ¥ÀÌÅÍÀÏ ¶§ Ãâ·Â if (((i + 1) % 32 == 0) || (i == datalength - 1)) { KLogEx(DEBUG_TRACE_INFO, "%s", szBuffer); // ÃʱâÈ­ szBuffer[0] = '\0'; cbCurrentLen = 0; } } } // ----------------------------------------------------------------------------- // [ÅëÇÕ API] ¸ðµç º¼·ý Á¤º¸¸¦ ÇÑ ¹ø¿¡ ¼öÁýÇÏ´Â ÇÔ¼ö // ----------------------------------------------------------------------------- NTSTATUS GetAllVolumeDetails( _In_ PFLT_INSTANCE Instance, _Out_ PVOLUME_DETAILS pOutDetails ) { NTSTATUS status; IO_STATUS_BLOCK iosb; // °¡º¯ ±æÀÌ µ¥ÀÌÅ͸¦ ¹Þ±â À§ÇÑ Àӽà ¹öÆÛ (½ºÅà 1KB) UCHAR buffer[1024]; if (!pOutDetails) return STATUS_INVALID_PARAMETER; // ±¸Á¶Ã¼ ÃʱâÈ­ RtlZeroMemory(pOutDetails, sizeof(VOLUME_DETAILS)); RtlZeroMemory(buffer, sizeof(buffer)); // ========================================================================= // 1. ¿ë·® Á¤º¸ (FileFsSizeInformation) - °¡Àå Áß¿ä // ========================================================================= { FILE_FS_SIZE_INFORMATION info; status = FltQueryVolumeInformation(Instance, &iosb, &info, sizeof(info), FileFsSizeInformation); if (NT_SUCCESS(status)) { pOutDetails->TotalBytes = info.TotalAllocationUnits.QuadPart * info.SectorsPerAllocationUnit * info.BytesPerSector; pOutDetails->FreeBytes = info.AvailableAllocationUnits.QuadPart * info.SectorsPerAllocationUnit * info.BytesPerSector; } } // ========================================================================= // 2. º¼·ý ±âº» Á¤º¸ (FileFsVolumeInformation) - ¶óº§, ½Ã¸®¾ó // ========================================================================= { PFILE_FS_VOLUME_INFORMATION info = (PFILE_FS_VOLUME_INFORMATION)buffer; RtlZeroMemory(buffer, sizeof(buffer)); status = FltQueryVolumeInformation(Instance, &iosb, info, sizeof(buffer), FileFsVolumeInformation); if (NT_SUCCESS(status)) { pOutDetails->VolumeSerialNumber = info->VolumeSerialNumber; // ¶óº§ º¹»ç (Buffer Overflow ¹æÁö) if (info->VolumeLabelLength > 0) { ULONG copyLen = min(info->VolumeLabelLength, sizeof(pOutDetails->VolumeLabel) - sizeof(WCHAR)); RtlCopyMemory(pOutDetails->VolumeLabel, info->VolumeLabel, copyLen); pOutDetails->VolumeLabel[copyLen / sizeof(WCHAR)] = L'\0'; // Null Termination } } } // ========================================================================= // 3. ÆÄÀÏ ½Ã½ºÅÛ ¼Ó¼º (FileFsAttributeInformation) - FSÀ̸§, Flag // ========================================================================= { PFILE_FS_ATTRIBUTE_INFORMATION info = (PFILE_FS_ATTRIBUTE_INFORMATION)buffer; RtlZeroMemory(buffer, sizeof(buffer)); status = FltQueryVolumeInformation(Instance, &iosb, info, sizeof(buffer), FileFsAttributeInformation); if (NT_SUCCESS(status)) { pOutDetails->FileSystemAttributes = info->FileSystemAttributes; // FS À̸§ º¹»ç (¿¹: NTFS) if (info->FileSystemNameLength > 0) { ULONG copyLen = min(info->FileSystemNameLength, sizeof(pOutDetails->FileSystemName) - sizeof(WCHAR)); RtlCopyMemory(pOutDetails->FileSystemName, info->FileSystemName, copyLen); pOutDetails->FileSystemName[copyLen / sizeof(WCHAR)] = L'\0'; } } } // ========================================================================= // 4. µð¹ÙÀ̽º Á¤º¸ (FileFsDeviceInformation) // ========================================================================= { FILE_FS_DEVICE_INFORMATION info; status = FltQueryVolumeInformation(Instance, &iosb, &info, sizeof(info), FileFsDeviceInformation); if (NT_SUCCESS(status)) { pOutDetails->DeviceType = info.DeviceType; pOutDetails->DeviceCharacteristics = info.Characteristics; } } // ========================================================================= // 5. ¼½ÅÍ »ó¼¼ Á¤º¸ (FileFsSectorSizeInformation) - Win7 ÀÌ»ó // ========================================================================= { FILE_FS_SECTOR_SIZE_INFORMATION info; status = FltQueryVolumeInformation(Instance, &iosb, &info, sizeof(info), FileFsSectorSizeInformation); if (NT_SUCCESS(status)) { pOutDetails->PhysicalBytesPerSector = info.PhysicalBytesPerSectorForPerformance; pOutDetails->LogicalBytesPerSector = info.LogicalBytesPerSector; } else { // Áö¿øÇÏÁö ¾Ê´Â OS¸é 0À¸·Î ¼³Á¤ pOutDetails->PhysicalBytesPerSector = 0; pOutDetails->LogicalBytesPerSector = 0; } } // ========================================================================= // 6. º¼·ý GUID (FileFsGuidInformation) - Win10 ÀÌ»ó (Optional) // ========================================================================= { // ±¸Á¶Ã¼ ·ÎÄà Á¤ÀÇ (±¸Çü WDK ȣȯ¼º) typedef struct _LOC_FILE_FS_GUID_INFORMATION { GUID FsGuid; } LOC_FILE_FS_GUID_INFORMATION; LOC_FILE_FS_GUID_INFORMATION info; status = FltQueryVolumeInformation(Instance, &iosb, &info, sizeof(info), FileFsGuidInformation); if (NT_SUCCESS(status)) { pOutDetails->VolumeGuid = info.FsGuid; } } // ÇÙ½É Á¤º¸(Size µî)¸¦ ¸ø ±¸Çß´õ¶óµµ ÇÔ¼ö ÀÚü´Â ¼º°øÀ¸·Î ¹ÝȯÇÏ¿© // ºÎºÐ Á¤º¸¶óµµ ¾µ ¼ö ÀÖ°Ô ÇÔ. return STATUS_SUCCESS; } // JSON¿¡ µé¾î°¥ ¼ö ÀÖµµ·Ï ¹é½½·¡½Ã(\)¿Í Å«µû¿ÈÇ¥(")¸¦ À̽ºÄÉÀÌÇÁ ó¸®ÇÏ´Â ÇÔ¼ö NTSTATUS EscapeJsonStringW( _In_ PWCHAR Src, _Out_writes_z_(DestSizeInChars) PWCHAR Dest, _In_ size_t DestSizeInChars ) { size_t i = 0, j = 0; if (!Src || !Dest || DestSizeInChars == 0) return STATUS_INVALID_PARAMETER; while (Src[i] != L'\0') { // 1. ¿ª½½·¡½Ã³ª Å«µû¿ÈÇ¥¸¦ ¸¸³ª¸é ¾Õ¿¡ ¿ª½½·¡½Ã Çϳª ´õ Ãß°¡ if (Src[i] == L'\\' || Src[i] == L'"') { if (j + 2 >= DestSizeInChars) return STATUS_BUFFER_TOO_SMALL; // ¹öÆÛ Ãʰú ¹æÁö Dest[j++] = L'\\'; Dest[j++] = Src[i]; } // 2. ÀÏ¹Ý ¹®ÀÚ else { if (j + 1 >= DestSizeInChars) return STATUS_BUFFER_TOO_SMALL; Dest[j++] = Src[i]; } i++; } Dest[j] = L'\0'; // ³Î Á¾·á ¹®ÀÚ Ãß°¡ return STATUS_SUCCESS; }