added experimental feature: protect processes

git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1287 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
wj32
2009-05-17 02:59:06 +00:00
parent 9f709a1308
commit 91d061b663
28 changed files with 1705 additions and 326 deletions
+1
View File
@@ -5,6 +5,7 @@ Process Hacker
* KProcessHacker can now perform process memory reading/writing
by itself and does not require MmCopyVirtualMemory
* KProcessHacker can now bypass all handle-opening protections
* Experimental process protection feature
* Ability to set handle flags such as protect-from-close and inherit
* Better highlighting
* Terminator test: TD1 (debugs a process and closes the debug object)
+177
View File
@@ -0,0 +1,177 @@
/*
* Process Hacker Driver -
* hooks
*
* Copyright (C) 2009 wj32
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "include/hook.h"
typedef struct _MAPPED_MDL
{
PMDL Mdl;
PVOID Address;
} MAPPED_MDL, *PMAPPED_MDL;
NTSTATUS KphpCreateMappedMdl(
PVOID Address,
ULONG Length,
PMAPPED_MDL MappedMdl
);
VOID KphpFreeMappedMdl(
PMAPPED_MDL MappedMdl
);
/* KphHook
*
* Hooks a kernel-mode function.
* WARNING: DO NOT HOOK A FUNCTION THAT IS CALLABLE ABOVE PASSIVE_LEVEL.
*/
NTSTATUS KphHook(
PKPH_HOOK Hook
)
{
NTSTATUS status = STATUS_SUCCESS;
KIRQL oldIrql;
MAPPED_MDL mappedMdl;
PCHAR function;
status = KphpCreateMappedMdl(
Hook->Function,
5,
&mappedMdl
);
if (!NT_SUCCESS(status))
return status;
function = (PCHAR)mappedMdl.Address;
/* Raise to APC_LEVEL to prevent drivers calling the function while we're patching it. */
/* If they do, it's their problem because the function we're patching should only be
called at PASSIVE_LEVEL anyway (see hook.h for definition of KPH_HOOK). */
KeRaiseIrql(APC_LEVEL, &oldIrql);
memcpy(Hook->Bytes, function, 5);
Hook->Hooked = TRUE;
/* jmp Target */
*function = 0xe9;
*(PULONG_PTR)(function + 1) = (ULONG_PTR)Hook->Target - (ULONG_PTR)Hook->Function - 5;
/* Lower the IRQL back. */
KeLowerIrql(oldIrql);
KphpFreeMappedMdl(&mappedMdl);
return status;
}
/* KphUnhook
*
* Unhooks a kernel-mode function.
* WARNING: DO NOT UNHOOK A FUNCTION THAT IS CALLABLE ABOVE PASSIVE_LEVEL.
*/
NTSTATUS KphUnhook(
PKPH_HOOK Hook
)
{
NTSTATUS status = STATUS_SUCCESS;
KIRQL oldIrql;
MAPPED_MDL mappedMdl;
if (!Hook->Hooked)
return STATUS_UNSUCCESSFUL;
status = KphpCreateMappedMdl(
Hook->Function,
5,
&mappedMdl
);
if (!NT_SUCCESS(status))
return status;
KeRaiseIrql(APC_LEVEL, &oldIrql);
memcpy(mappedMdl.Address, Hook->Bytes, 5);
Hook->Hooked = FALSE;
KeLowerIrql(oldIrql);
KphpFreeMappedMdl(&mappedMdl);
return status;
}
/* KphpCreateMappedMdl
*
* Creates and maps a MDL.
*/
NTSTATUS KphpCreateMappedMdl(
PVOID Address,
ULONG Length,
PMAPPED_MDL MappedMdl
)
{
PMDL mdl;
MappedMdl->Mdl = NULL;
MappedMdl->Address = NULL;
mdl = IoAllocateMdl(Address, Length, FALSE, FALSE, NULL);
if (mdl == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
MmBuildMdlForNonPagedPool(mdl);
mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
MappedMdl->Address = MmMapLockedPagesSpecifyCache(
mdl,
KernelMode,
MmNonCached,
NULL,
FALSE,
HighPagePriority
);
MappedMdl->Mdl = mdl;
if (!MappedMdl->Address)
{
KphpFreeMappedMdl(MappedMdl);
return STATUS_INSUFFICIENT_RESOURCES;
}
return STATUS_SUCCESS;
}
/* KphpFreeMappedMdl
*
* Unmaps and frees a MDL.
*/
VOID KphpFreeMappedMdl(
PMAPPED_MDL MappedMdl
)
{
if (MappedMdl->Mdl != NULL)
{
if (MappedMdl->Address != NULL)
{
MmUnmapLockedPages(MappedMdl->Address, MappedMdl->Mdl);
MappedMdl->Address = NULL;
}
IoFreeMdl(MappedMdl->Mdl);
MappedMdl->Mdl = NULL;
}
}
Binary file not shown.
+60
View File
@@ -0,0 +1,60 @@
/*
* Process Hacker Driver -
* hooks
*
* Copyright (C) 2009 wj32
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _HOOK_H
#define _HOOK_H
#include "kph.h"
#define KPH_DEFINE_HOOK_CALL(Name, Arguments, Hook) \
__declspec(naked) Name(Arguments) \
{ \
__asm lea eax, Hook \
__asm mov eax, [eax+KPH_HOOK.Function] \
__asm add eax, 5 \
__asm push ebp \
__asm mov ebp, esp \
__asm jmp eax \
} \
typedef struct _KPH_HOOK
{
/* The address of the hooked function.
Should NOT be a function that is callable above PASSIVE_LEVEL. */
PVOID Function;
/* The address of the new function. */
PVOID Target;
/* Whether the function is hooked. */
BOOLEAN Hooked;
/* The original first 5 bytes. */
CHAR Bytes[5];
} KPH_HOOK, *PKPH_HOOK;
NTSTATUS KphHook(
PKPH_HOOK Hook
);
NTSTATUS KphUnhook(
PKPH_HOOK Hook
);
#endif
@@ -70,11 +70,17 @@
#define KPH_GETFEATURES KPH_CTL_CODE(26)
#define KPH_SETHANDLEGRANTEDACCESS KPH_CTL_CODE(27)
#define KPH_ASSIGNIMPERSONATIONTOKEN KPH_CTL_CODE(28)
#define KPH_PROTECTADD KPH_CTL_CODE(29)
#define KPH_PROTECTREMOVE KPH_CTL_CODE(30)
#define KPH_PROTECTQUERY KPH_CTL_CODE(31)
#define GET_BIT(integer, bit) (((integer) >> (bit)) & 0x1)
#define SET_BIT(integer, bit) ((integer) |= 1 << (bit))
#define CLEAR_BIT(integer, bit) ((integer) &= ~(1 << (bit)))
#define KPH_TIMEOUT_TO_SEC ((LONGLONG) 1 * 10 * 1000 * 1000)
#define KPH_REL_TIMEOUT_IN_SEC(Time) (Time * -1 * KPH_TIMEOUT_TO_SEC)
NTSTATUS KphDispatchCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS KphDispatchClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS KphDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+77
View File
@@ -0,0 +1,77 @@
/*
* Process Hacker Driver -
* process protection
*
* Copyright (C) 2009 wj32
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _PROTECT_H
#define _PROTECT_H
#include "hook.h"
#define OBOPENOBJECTBYPOINTER_ARGS \
PVOID Object, \
ULONG HandleAttributes, \
PACCESS_STATE PassedAccessState, \
ACCESS_MASK DesiredAccess, \
POBJECT_TYPE ObjectType, \
KPROCESSOR_MODE AccessMode, \
PHANDLE Handle
typedef struct _KPH_PROCESS_ENTRY
{
LIST_ENTRY ListEntry;
PEPROCESS Process;
HANDLE Tag;
ACCESS_MASK ProcessAllowMask;
ACCESS_MASK ThreadAllowMask;
} KPH_PROCESS_ENTRY, *PKPH_PROCESS_ENTRY;
NTSTATUS NTAPI KphNewObOpenObjectByPointer(OBOPENOBJECTBYPOINTER_ARGS);
NTSTATUS NTAPI KphOldObOpenObjectByPointer(OBOPENOBJECTBYPOINTER_ARGS);
NTSTATUS KphProtectInit();
NTSTATUS KphProtectDeinit();
PKPH_PROCESS_ENTRY KphProtectAddEntry(
PEPROCESS Process,
HANDLE Tag,
ACCESS_MASK ProcessAllowMask,
ACCESS_MASK ThreadAllowMask
);
BOOLEAN KphProtectCopyEntry(
PEPROCESS Process,
PKPH_PROCESS_ENTRY ProcessEntry
);
PKPH_PROCESS_ENTRY KphProtectFindEntry(
PEPROCESS Process,
HANDLE Tag
);
BOOLEAN KphProtectRemoveByProcess(
PEPROCESS Process
);
ULONG KphProtectRemoveByTag(
HANDLE Tag
);
#endif
+38
View File
@@ -29,6 +29,44 @@
#include "ob.h"
#include "se.h"
#define PROCESS_TERMINATE (0x0001)
#define PROCESS_CREATE_THREAD (0x0002)
#define PROCESS_SET_SESSIONID (0x0004)
#define PROCESS_VM_OPERATION (0x0008)
#define PROCESS_VM_READ (0x0010)
#define PROCESS_VM_WRITE (0x0020)
#define PROCESS_DUP_HANDLE (0x0040)
#define PROCESS_CREATE_PROCESS (0x0080)
#define PROCESS_SET_QUOTA (0x0100)
#define PROCESS_SET_INFORMATION (0x0200)
#define PROCESS_QUERY_INFORMATION (0x0400)
#define PROCESS_SUSPEND_RESUME (0x0800)
#define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)
#ifndef PROCESS_ALL_ACCESS
#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff)
#endif
#define THREAD_TERMINATE (0x0001)
#define THREAD_SUSPEND_RESUME (0x0002)
#define THREAD_ALERT (0x0004)
#define THREAD_GET_CONTEXT (0x0008)
#define THREAD_SET_CONTEXT (0x0010)
#define THREAD_SET_INFORMATION (0x0020)
#define THREAD_QUERY_INFORMATION (0x0040)
#define THREAD_SET_THREAD_TOKEN (0x0080)
#define THREAD_IMPERSONATE (0x0100)
#define THREAD_DIRECT_IMPERSONATION (0x0200)
#ifndef THREAD_ALL_ACCESS
#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff)
#endif
#define JOB_OBJECT_ASSIGN_PROCESS (0x0001)
#define JOB_OBJECT_SET_ATTRIBUTES (0x0002)
#define JOB_OBJECT_QUERY (0x0004)
#define JOB_OBJECT_TERMINATE (0x0008)
#define JOB_OBJECT_SET_SECURITY_ATTRIBUTES (0x0010)
#define JOB_OBJECT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1f)
extern POBJECT_TYPE *PsJobType;
/* FUNCTION DEFS */
+3 -1
View File
@@ -57,7 +57,7 @@ typedef struct _KV_SCANPROC
NTSTATUS KvInit();
PVOID KvVerifyPrologue(
ULONG_PTR Offset
PVOID Address
);
PVOID KvScanProc(
@@ -85,6 +85,7 @@ EXT ACCESS_MASK ThreadAllAccess;
/* Structures
* Et: ETHREAD
* Ep: EPROCESS
* Kt: KTHREAD
* Ot: OBJECT_TYPE
* Oti: OBJECT_TYPE_INITIALIZER, offset measured from an OBJECT_TYPE
*/
@@ -96,6 +97,7 @@ EXT ULONG OffEpObjectTable;
EXT ULONG OffEpProtectedProcessOff;
EXT ULONG OffEpProtectedProcessBit;
EXT ULONG OffEpRundownProtect;
EXT ULONG OffKtProcess;
EXT ULONG OffOhBody;
EXT ULONG OffOtiGenericMapping;
-29
View File
@@ -25,35 +25,6 @@
#include "types.h"
#define PROCESS_TERMINATE (0x0001)
#define PROCESS_CREATE_THREAD (0x0002)
#define PROCESS_SET_SESSIONID (0x0004)
#define PROCESS_VM_OPERATION (0x0008)
#define PROCESS_VM_READ (0x0010)
#define PROCESS_VM_WRITE (0x0020)
#define PROCESS_DUP_HANDLE (0x0040)
#define PROCESS_CREATE_PROCESS (0x0080)
#define PROCESS_SET_QUOTA (0x0100)
#define PROCESS_SET_INFORMATION (0x0200)
#define PROCESS_QUERY_INFORMATION (0x0400)
#define PROCESS_SUSPEND_RESUME (0x0800)
#define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
0xFFFF)
#else
#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
0xFFF)
#endif
#define JOB_OBJECT_ASSIGN_PROCESS (0x0001)
#define JOB_OBJECT_SET_ATTRIBUTES (0x0002)
#define JOB_OBJECT_QUERY (0x0004)
#define JOB_OBJECT_TERMINATE (0x0008)
#define JOB_OBJECT_SET_SECURITY_ATTRIBUTES (0x0010)
#define JOB_OBJECT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
0x1F)
typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG Reserved[2];
+189
View File
@@ -22,7 +22,9 @@
#include "include/kprocesshacker.h"
#include "include/debug.h"
#include "include/kph.h"
#include "include/protect.h"
#include "include/ps.h"
#include "include/version.h"
@@ -33,6 +35,8 @@
#pragma alloc_text(PAGE, KphUnsupported)
#pragma pack(1)
static BOOLEAN ProtectionInitialized = FALSE;
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING dosDeviceName;
@@ -41,6 +45,18 @@ VOID DriverUnload(PDRIVER_OBJECT DriverObject)
IoDeleteSymbolicLink(&dosDeviceName);
IoDeleteDevice(DriverObject->DeviceObject);
if (ProtectionInitialized)
{
LARGE_INTEGER waitLi;
KphProtectDeinit();
ProtectionInitialized = FALSE;
/* Wait for a bit before unloading to prevent BSODs. */
waitLi.QuadPart = KPH_REL_TIMEOUT_IN_SEC(5);
KeDelayExecutionThread(KernelMode, FALSE, &waitLi);
}
dprintf("Driver unloaded\n");
}
@@ -119,11 +135,26 @@ NTSTATUS KphDispatchClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
if (ProtectionInitialized)
{
ULONG count = KphProtectRemoveByTag(PsGetCurrentProcessId());
dprintf("Removed %d protection entries\n", count);
}
dprintf("Client (PID %d) disconnected\n", PsGetCurrentProcessId());
return status;
}
VOID InitProtection()
{
if (!ProtectionInitialized)
{
KphProtectInit();
ProtectionInitialized = TRUE;
}
}
/* from YAPM */
NTSTATUS GetObjectName(PFILE_OBJECT FileObject, PVOID Buffer, ULONG BufferLength, PULONG ReturnLength)
{
@@ -239,6 +270,12 @@ PCHAR GetIoControlName(ULONG ControlCode)
return "KphSetHandleGrantedAccess";
else if (ControlCode == KPH_ASSIGNIMPERSONATIONTOKEN)
return "KphAssignImpersonationToken";
else if (ControlCode == KPH_PROTECTADD)
return "Add Process Protection";
else if (ControlCode == KPH_PROTECTREMOVE)
return "Remove Process Protection";
else if (ControlCode == KPH_PROTECTQUERY)
return "Query Process Protection";
else
return "Unknown";
}
@@ -1239,6 +1276,158 @@ NTSTATUS KphDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
break;
/* Add Process Protection */
case KPH_PROTECTADD:
{
struct
{
HANDLE ProcessHandle;
ACCESS_MASK ProcessAllowMask;
ACCESS_MASK ThreadAllowMask;
} *args = dataBuffer;
PEPROCESS processObject;
if (inLength < sizeof(*args))
{
status = STATUS_BUFFER_TOO_SMALL;
goto IoControlEnd;
}
status = ObReferenceObjectByHandle(
args->ProcessHandle,
0,
*PsProcessType,
KernelMode,
&processObject,
NULL
);
ObDereferenceObject(processObject);
if (!NT_SUCCESS(status))
goto IoControlEnd;
InitProtection();
/* Don't protect the same process twice. */
if (KphProtectFindEntry(processObject, NULL))
{
status = STATUS_NOT_SUPPORTED;
goto IoControlEnd;
}
if (!KphProtectAddEntry(
processObject,
PsGetCurrentProcessId(),
args->ProcessAllowMask,
args->ThreadAllowMask
))
{
status = STATUS_UNSUCCESSFUL;
goto IoControlEnd;
}
}
break;
/* Remove Process Protection */
case KPH_PROTECTREMOVE:
{
struct
{
HANDLE ProcessHandle;
} *args = dataBuffer;
PEPROCESS processObject;
if (inLength < sizeof(*args))
{
status = STATUS_BUFFER_TOO_SMALL;
goto IoControlEnd;
}
status = ObReferenceObjectByHandle(
args->ProcessHandle,
0,
*PsProcessType,
KernelMode,
&processObject,
NULL
);
ObDereferenceObject(processObject);
if (!NT_SUCCESS(status))
goto IoControlEnd;
InitProtection();
if (!KphProtectRemoveByProcess(processObject))
{
status = STATUS_UNSUCCESSFUL;
goto IoControlEnd;
}
}
break;
/* Query Process Protection */
case KPH_PROTECTQUERY:
{
struct
{
HANDLE ProcessHandle;
PACCESS_MASK ProcessAllowMask;
PACCESS_MASK ThreadAllowMask;
} *args = dataBuffer;
PEPROCESS processObject;
KPH_PROCESS_ENTRY processEntry;
if (inLength < sizeof(*args))
{
status = STATUS_BUFFER_TOO_SMALL;
goto IoControlEnd;
}
__try
{
ProbeForWrite(args->ProcessAllowMask, sizeof(ACCESS_MASK), 1);
ProbeForWrite(args->ThreadAllowMask, sizeof(ACCESS_MASK), 1);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
status = GetExceptionCode();
goto IoControlEnd;
}
status = ObReferenceObjectByHandle(
args->ProcessHandle,
0,
*PsProcessType,
KernelMode,
&processObject,
NULL
);
ObDereferenceObject(processObject);
if (!NT_SUCCESS(status))
goto IoControlEnd;
InitProtection();
if (!KphProtectCopyEntry(processObject, &processEntry))
{
status = STATUS_UNSUCCESSFUL;
goto IoControlEnd;
}
__try
{
*(args->ProcessAllowMask) = processEntry.ProcessAllowMask;
*(args->ThreadAllowMask) = processEntry.ThreadAllowMask;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
status = GetExceptionCode();
}
}
break;
default:
{
dprintf("Unrecognized IOCTL code 0x%08x\n", controlCode);
+337
View File
@@ -0,0 +1,337 @@
/*
* Process Hacker Driver -
* process protection
*
* Copyright (C) 2009 wj32
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "include/protect.h"
LIST_ENTRY ProtectedProcessListHead;
KSPIN_LOCK ProtectedProcessListLock;
NPAGED_LOOKASIDE_LIST ProtectedProcessLookasideList;
KPH_HOOK ObOpenObjectByPointerHook = { 0 };
BOOLEAN KphpIsCurrentProcessProtected();
VOID KphpProtectRemoveEntry(
PKPH_PROCESS_ENTRY Entry
);
KPH_DEFINE_HOOK_CALL(
NTSTATUS NTAPI KphOldObOpenObjectByPointer,
OBOPENOBJECTBYPOINTER_ARGS,
ObOpenObjectByPointerHook
);
/* KphProtectInit
*
* Initializes process protection.
*/
NTSTATUS KphProtectInit()
{
NTSTATUS status;
/* Initialize list structures. */
InitializeListHead(&ProtectedProcessListHead);
KeInitializeSpinLock(&ProtectedProcessListLock);
ExInitializeNPagedLookasideList(
&ProtectedProcessLookasideList,
NULL,
NULL,
0,
sizeof(KPH_PROCESS_ENTRY),
KPH_TAG,
0
);
/* Hook various functions. */
ObOpenObjectByPointerHook.Function = ObOpenObjectByPointer;
ObOpenObjectByPointerHook.Target = KphNewObOpenObjectByPointer;
if (!NT_SUCCESS(status = KphHook(&ObOpenObjectByPointerHook)))
return status;
return STATUS_SUCCESS;
}
/* KphProtectDeinit
*
* Removes process protection and frees associated structures.
*/
NTSTATUS KphProtectDeinit()
{
KIRQL oldIrql;
/* Unhook. */
KphUnhook(&ObOpenObjectByPointerHook);
KeAcquireSpinLock(&ProtectedProcessListLock, &oldIrql);
/* Free and remove all process entries from the list. */
while (!IsListEmpty(&ProtectedProcessListHead))
{
PKPH_PROCESS_ENTRY entry =
CONTAINING_RECORD(
RemoveHeadList(&ProtectedProcessListHead),
KPH_PROCESS_ENTRY,
ListEntry
);
dprintf("KphProtectDeinit: removing entry 0x%08x\n", entry);
ExFreeToNPagedLookasideList(
&ProtectedProcessLookasideList,
entry
);
}
KeReleaseSpinLock(&ProtectedProcessListLock, oldIrql);
return STATUS_SUCCESS;
}
/* KphNewObOpenObjectByPointer
*
* New ObOpenObjectByPointer function.
*/
NTSTATUS NTAPI KphNewObOpenObjectByPointer(
OBOPENOBJECTBYPOINTER_ARGS
)
{
if (
AccessMode != KernelMode && /* let kernel-mode callers through */
!KphpIsCurrentProcessProtected() /* let protected process callers through */
)
{
PEPROCESS processObject = (PEPROCESS)Object;
BOOLEAN isThread = ObjectType == *PsThreadType;
ACCESS_MASK access;
KPH_PROCESS_ENTRY processEntry;
*Handle = NULL;
access = DesiredAccess;
/* If we have an access state, get the desired access from it. */
if (PassedAccessState != NULL)
access = PassedAccessState->OriginalDesiredAccess;
/* If this is a thread, get its parent process. */
if (isThread)
processObject = *(PEPROCESS *)KVOFF(Object, OffKtProcess);
if (KphProtectCopyEntry(processObject, &processEntry))
{
ACCESS_MASK mask =
isThread ? processEntry.ThreadAllowMask : processEntry.ProcessAllowMask;
/* The process/thread is protected. Check if the requested access is allowed. */
if ((access & mask) != access)
{
dprintf(
"%d: Access denied: 0x%08x (%s)\n",
PsGetCurrentProcessId(),
access,
isThread ? "Thread" : "Process"
);
/* Access denied. */
return STATUS_ACCESS_DENIED;
}
}
}
return KphOldObOpenObjectByPointer(
Object,
HandleAttributes,
PassedAccessState,
DesiredAccess,
ObjectType,
AccessMode,
Handle
);
}
/* KphProtectAddEntry
*
* Protects the specified process.
*/
PKPH_PROCESS_ENTRY KphProtectAddEntry(
PEPROCESS Process,
HANDLE Tag,
ACCESS_MASK ProcessAllowMask,
ACCESS_MASK ThreadAllowMask
)
{
KIRQL oldIrql;
PKPH_PROCESS_ENTRY entry =
ExAllocateFromNPagedLookasideList(&ProtectedProcessLookasideList);
if (entry == NULL)
return NULL;
entry->Process = Process;
entry->Tag = Tag;
entry->ProcessAllowMask = ProcessAllowMask;
entry->ThreadAllowMask = ThreadAllowMask;
KeAcquireSpinLock(&ProtectedProcessListLock, &oldIrql);
InsertHeadList(&ProtectedProcessListHead, &entry->ListEntry);
KeReleaseSpinLock(&ProtectedProcessListLock, oldIrql);
return entry;
}
/* KphProtectCopyEntry
*
* Copies process protection data for the specified process.
*/
BOOLEAN KphProtectCopyEntry(
PEPROCESS Process,
PKPH_PROCESS_ENTRY ProcessEntry
)
{
KIRQL oldIrql;
PLIST_ENTRY entry = ProtectedProcessListHead.Flink;
KeAcquireSpinLock(&ProtectedProcessListLock, &oldIrql);
while (entry != &ProtectedProcessListHead)
{
PKPH_PROCESS_ENTRY processEntry =
CONTAINING_RECORD(entry, KPH_PROCESS_ENTRY, ListEntry);
if (processEntry->Process == Process)
{
memcpy(ProcessEntry, processEntry, sizeof(KPH_PROCESS_ENTRY));
KeReleaseSpinLock(&ProtectedProcessListLock, oldIrql);
return TRUE;
}
entry = entry->Flink;
}
KeReleaseSpinLock(&ProtectedProcessListLock, oldIrql);
return FALSE;
}
/* KphProtectFindEntry
*
* Finds process protection data.
*/
PKPH_PROCESS_ENTRY KphProtectFindEntry(
PEPROCESS Process,
HANDLE Tag
)
{
KIRQL oldIrql;
PLIST_ENTRY entry = ProtectedProcessListHead.Flink;
KeAcquireSpinLock(&ProtectedProcessListLock, &oldIrql);
while (entry != &ProtectedProcessListHead)
{
PKPH_PROCESS_ENTRY processEntry =
CONTAINING_RECORD(entry, KPH_PROCESS_ENTRY, ListEntry);
if (
(Process != NULL && processEntry->Process == Process) ||
(Tag != NULL && processEntry->Tag == Tag)
)
{
KeReleaseSpinLock(&ProtectedProcessListLock, oldIrql);
return processEntry;
}
entry = entry->Flink;
}
KeReleaseSpinLock(&ProtectedProcessListLock, oldIrql);
return NULL;
}
/* KphProtectRemoveByProcess
*
* Removes protection from the specified process.
*/
BOOLEAN KphProtectRemoveByProcess(
PEPROCESS Process
)
{
PKPH_PROCESS_ENTRY entry = KphProtectFindEntry(Process, NULL);
if (entry == NULL)
return FALSE;
KphpProtectRemoveEntry(entry);
return TRUE;
}
/* KphProtectRemoveByTag
*
* Removes protection from all processes with the specified tag.
*/
ULONG KphProtectRemoveByTag(
HANDLE Tag
)
{
KIRQL oldIrql;
ULONG count = 0;
PKPH_PROCESS_ENTRY entry;
/* Keep removing entries until we can't find any more. */
while (entry = KphProtectFindEntry(NULL, Tag))
{
KphpProtectRemoveEntry(entry);
count++;
}
return count;
}
/* KphpIsCurrentProcessProtected
*
* Determines whether the current process is protected.
*/
BOOLEAN KphpIsCurrentProcessProtected()
{
return KphProtectFindEntry(PsGetCurrentProcess(), NULL) != NULL;
}
/* KphpProtectRemoveEntry
*
* Removes and frees process protection data.
*/
VOID KphpProtectRemoveEntry(
PKPH_PROCESS_ENTRY Entry
)
{
KIRQL oldIrql;
KeAcquireSpinLock(&ProtectedProcessListLock, &oldIrql);
RemoveEntryList(&Entry->ListEntry);
ExFreeToNPagedLookasideList(
&ProtectedProcessLookasideList,
Entry
);
KeReleaseSpinLock(&ProtectedProcessListLock, oldIrql);
}
+2
View File
@@ -9,6 +9,8 @@ SOURCES= \
kprocesshacker.c \
version.c \
kph.c \
hook.c \
protect.c \
mm.c \
ob.c \
ps.c \
+6 -5
View File
@@ -118,6 +118,7 @@ NTSTATUS KvInit()
OffEpProtectedProcessOff = 0;
OffEpProtectedProcessBit = 0;
OffEpRundownProtect = 0x80;
OffKtProcess = 0x220; /* it's actually in the ETHREAD, but let's ignore that */
OffOtiGenericMapping = 0x60 + 0x8;
OffOhBody = 0x18;
@@ -182,6 +183,7 @@ NTSTATUS KvInit()
OffEpProtectedProcessOff = 0x224;
OffEpProtectedProcessBit = 0xb;
OffEpRundownProtect = 0x98;
OffKtProcess = 0x144;
OffOhBody = 0x18;
INIT_SCAN(
@@ -232,6 +234,7 @@ NTSTATUS KvInit()
OffEpProtectedProcessOff = 0x25c;
OffEpProtectedProcessBit = 0xb;
OffEpRundownProtect = 0xb0;
OffKtProcess = 0x154;
OffOtiGenericMapping = 0x28 + 0xc;
OffOhBody = 0x18;
@@ -266,13 +269,11 @@ NTSTATUS KvInit()
}
PVOID KvVerifyPrologue(
ULONG_PTR Offset
PVOID Address
)
{
PVOID address = (PVOID)((ULONG_PTR)__NtClose + Offset);
if (memcmp(address, StandardPrologue, 5) == 0)
return address;
if (memcmp(Address, StandardPrologue, 5) == 0)
return Address;
else
return NULL;
}
+41 -4
View File
@@ -76,7 +76,10 @@ namespace ProcessHacker.Native
KphTerminateThread,
GetFeatures,
KphSetHandleGrantedAccess,
KphAssignImpersonationToken
KphAssignImpersonationToken,
ProtectAdd,
ProtectRemove,
ProtectQuery
}
[Flags]
@@ -113,9 +116,8 @@ namespace ProcessHacker.Native
shandle.Delete();
}
}
catch (Exception)
{
}
catch
{ }
try
{
@@ -546,6 +548,41 @@ namespace ProcessHacker.Native
bytesWritten = returnLength;
}
public void ProtectAdd(ProcessHandle processHandle, ProcessAccess ProcessAllowMask, ThreadAccess ThreadAllowMask)
{
byte* inData = stackalloc byte[12];
*(int*)inData = processHandle;
*(int*)(inData + 4) = (int)ProcessAllowMask;
*(int*)(inData + 8) = (int)ThreadAllowMask;
_fileHandle.IoControl(CtlCode(Control.ProtectAdd), inData, 12, null, 0);
}
public void ProtectQuery(ProcessHandle processHandle, out ProcessAccess ProcessAllowMask, out ThreadAccess ThreadAllowMask)
{
byte* inData = stackalloc byte[12];
ProcessAccess processAllowMask;
ThreadAccess threadAllowMask;
*(int*)inData = processHandle;
*(int*)(inData + 4) = (int)&processAllowMask;
*(int*)(inData + 8) = (int)&threadAllowMask;
_fileHandle.IoControl(CtlCode(Control.ProtectQuery), inData, 12, null, 0);
ProcessAllowMask = processAllowMask;
ThreadAllowMask = threadAllowMask;
}
public void ProtectRemove(ProcessHandle processHandle)
{
int processHandleInt = processHandle;
_fileHandle.IoControl(CtlCode(Control.ProtectRemove),
(byte*)&processHandleInt, 4, null, 0);
}
public byte[] Read(int address, int length)
{
byte[] buffer = new byte[length];
+66 -23
View File
@@ -29,6 +29,7 @@ using ProcessHacker.Native.Api;
using ProcessHacker.Native.Objects;
using ProcessHacker.Native.Security;
using ProcessHacker.UI;
using Microsoft.Win32;
namespace ProcessHacker.Components
{
@@ -409,41 +410,83 @@ namespace ProcessHacker.Components
private void unloadMenuItem_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Are you sure you want to unload this library?", "Process Hacker",
if (MessageBox.Show("Are you sure you want to unload this " +
(_pid != 4 ? "library" : "driver") + "?", "Process Hacker",
MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) == DialogResult.No)
return;
try
if (_pid == 4)
{
IntPtr kernel32 = Win32.GetModuleHandle("kernel32.dll");
IntPtr freeLibrary = Win32.GetProcAddress(kernel32, "FreeLibrary");
if (freeLibrary == IntPtr.Zero)
throw new Exception("Could not find the entry point of FreeLibrary in kernel32.dll!");
using (ProcessHandle phandle = new ProcessHandle(_pid,
Program.MinProcessQueryRights | Program.MinProcessReadMemoryRights |
Program.MinProcessWriteMemoryRights | ProcessAccess.CreateThread))
try
{
IntPtr baseAddress = ((ModuleItem)listModules.SelectedItems[0].Tag).BaseAddress;
string fileName = ((ModuleItem)listModules.SelectedItems[0].Tag).FileName;
RegistryKey servicesKey =
Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Services", true);
string serviceName = Misc.MakeRandomString(8);
RegistryKey serviceKey = servicesKey.CreateSubKey(serviceName);
phandle.SetModuleReferenceCount(baseAddress, 1);
serviceKey.SetValue("ErrorControl", 1, RegistryValueKind.DWord);
serviceKey.SetValue("ImagePath", "\\??\\" + fileName, RegistryValueKind.ExpandString);
serviceKey.SetValue("Start", 1, RegistryValueKind.DWord);
serviceKey.SetValue("Type", 1, RegistryValueKind.DWord);
serviceKey.Close();
servicesKey.Flush();
var thread = phandle.CreateThread(freeLibrary, baseAddress, ThreadAccess.All);
thread.Wait(1000);
int exitCode = thread.GetExitCode();
if (exitCode == 0)
try
{
throw new Exception("Error unloading the library.");
Windows.UnloadDriver(serviceName);
}
finally
{
servicesKey.DeleteSubKeyTree(serviceName);
servicesKey.Close();
}
}
catch (System.Security.SecurityException ex)
{
MessageBox.Show("Could not unload the driver. Make sure Process Hacker " +
"is running with administrative privileges. Error:\n\n" +
ex.Message, "Process Hacker", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Process Hacker", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (Exception ex)
else
{
MessageBox.Show(ex.Message, "Process Hacker", MessageBoxButtons.OK, MessageBoxIcon.Error);
try
{
IntPtr kernel32 = Win32.GetModuleHandle("kernel32.dll");
IntPtr freeLibrary = Win32.GetProcAddress(kernel32, "FreeLibrary");
if (freeLibrary == IntPtr.Zero)
throw new Exception("Could not find the entry point of FreeLibrary in kernel32.dll!");
using (ProcessHandle phandle = new ProcessHandle(_pid,
Program.MinProcessQueryRights | Program.MinProcessReadMemoryRights |
Program.MinProcessWriteMemoryRights | ProcessAccess.CreateThread))
{
IntPtr baseAddress = ((ModuleItem)listModules.SelectedItems[0].Tag).BaseAddress;
phandle.SetModuleReferenceCount(baseAddress, 1);
var thread = phandle.CreateThread(freeLibrary, baseAddress, ThreadAccess.All);
thread.Wait(1000);
int exitCode = thread.GetExitCode();
if (exitCode == 0)
{
throw new Exception("Error unloading the library.");
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Process Hacker", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
+19 -10
View File
@@ -41,6 +41,7 @@
this.menuItem5 = new System.Windows.Forms.MenuItem();
this.affinityProcessMenuItem = new System.Windows.Forms.MenuItem();
this.injectDllProcessMenuItem = new System.Windows.Forms.MenuItem();
this.protectionProcessMenuItem = new System.Windows.Forms.MenuItem();
this.setTokenProcessMenuItem = new System.Windows.Forms.MenuItem();
this.terminatorProcessMenuItem = new System.Windows.Forms.MenuItem();
this.priorityMenuItem = new System.Windows.Forms.MenuItem();
@@ -189,6 +190,7 @@
this.menuItem5,
this.affinityProcessMenuItem,
this.injectDllProcessMenuItem,
this.protectionProcessMenuItem,
this.setTokenProcessMenuItem,
this.terminatorProcessMenuItem,
this.priorityMenuItem,
@@ -264,22 +266,28 @@
this.injectDllProcessMenuItem.Text = "Inject DLL...";
this.injectDllProcessMenuItem.Click += new System.EventHandler(this.injectDllProcessMenuItem_Click);
//
// protectionProcessMenuItem
//
this.protectionProcessMenuItem.Index = 10;
this.protectionProcessMenuItem.Text = "Protection...";
this.protectionProcessMenuItem.Click += new System.EventHandler(this.protectionProcessMenuItem_Click);
//
// setTokenProcessMenuItem
//
this.setTokenProcessMenuItem.Index = 10;
this.setTokenProcessMenuItem.Index = 11;
this.setTokenProcessMenuItem.Text = "Set Token...";
this.setTokenProcessMenuItem.Click += new System.EventHandler(this.setTokenProcessMenuItem_Click);
//
// terminatorProcessMenuItem
//
this.terminatorProcessMenuItem.Index = 11;
this.terminatorProcessMenuItem.Index = 12;
this.terminatorProcessMenuItem.Text = "Terminator...";
this.terminatorProcessMenuItem.Click += new System.EventHandler(this.terminatorProcessMenuItem_Click);
//
// priorityMenuItem
//
this.vistaMenu.SetImage(this.priorityMenuItem, global::ProcessHacker.Properties.Resources.control_equalizer_blue);
this.priorityMenuItem.Index = 12;
this.priorityMenuItem.Index = 13;
this.priorityMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.realTimeMenuItem,
this.highMenuItem,
@@ -333,7 +341,7 @@
//
// runAsProcessMenuItem
//
this.runAsProcessMenuItem.Index = 13;
this.runAsProcessMenuItem.Index = 14;
this.runAsProcessMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.launchAsUserProcessMenuItem,
this.launchAsThisUserProcessMenuItem});
@@ -355,37 +363,37 @@
//
this.propertiesProcessMenuItem.DefaultItem = true;
this.vistaMenu.SetImage(this.propertiesProcessMenuItem, global::ProcessHacker.Properties.Resources.application_form_magnify);
this.propertiesProcessMenuItem.Index = 14;
this.propertiesProcessMenuItem.Index = 15;
this.propertiesProcessMenuItem.Text = "&Properties...";
this.propertiesProcessMenuItem.Click += new System.EventHandler(this.propertiesProcessMenuItem_Click);
//
// menuItem7
//
this.menuItem7.Index = 15;
this.menuItem7.Index = 16;
this.menuItem7.Text = "-";
//
// searchProcessMenuItem
//
this.searchProcessMenuItem.Index = 16;
this.searchProcessMenuItem.Index = 17;
this.searchProcessMenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlM;
this.searchProcessMenuItem.Text = "&Search Online...";
this.searchProcessMenuItem.Click += new System.EventHandler(this.searchProcessMenuItem_Click);
//
// reanalyzeProcessMenuItem
//
this.reanalyzeProcessMenuItem.Index = 17;
this.reanalyzeProcessMenuItem.Index = 18;
this.reanalyzeProcessMenuItem.Text = "Re-analyze";
this.reanalyzeProcessMenuItem.Click += new System.EventHandler(this.reanalyzeProcessMenuItem_Click);
//
// copyProcessMenuItem
//
this.vistaMenu.SetImage(this.copyProcessMenuItem, global::ProcessHacker.Properties.Resources.page_copy);
this.copyProcessMenuItem.Index = 18;
this.copyProcessMenuItem.Index = 19;
this.copyProcessMenuItem.Text = "&Copy";
//
// selectAllProcessMenuItem
//
this.selectAllProcessMenuItem.Index = 19;
this.selectAllProcessMenuItem.Index = 20;
this.selectAllProcessMenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlA;
this.selectAllProcessMenuItem.Text = "Select &All";
this.selectAllProcessMenuItem.Click += new System.EventHandler(this.selectAllProcessMenuItem_Click);
@@ -1343,6 +1351,7 @@
private System.Windows.Forms.MenuItem commitHistoryMenuItem;
private System.Windows.Forms.MenuItem physMemHistoryMenuItem;
private System.Windows.Forms.MenuItem closeNetworkMenuItem;
private System.Windows.Forms.MenuItem protectionProcessMenuItem;
}
}
+9 -1
View File
@@ -1163,6 +1163,11 @@ namespace ProcessHacker
}
}
private void protectionProcessMenuItem_Click(object sender, EventArgs e)
{
(new ProtectProcessWindow(processSelectedPID)).ShowDialog();
}
private void setTokenProcessMenuItem_Click(object sender, EventArgs e)
{
ProcessPickerWindow picker = new ProcessPickerWindow();
@@ -2318,7 +2323,7 @@ namespace ProcessHacker
treeProcesses.RefreshItems();
}
private void LoadFixMenuItems()
public void LoadFixMenuItems()
{
if (!System.IO.File.Exists(Application.StartupPath + "\\Assistant.exe"))
{
@@ -2332,6 +2337,9 @@ namespace ProcessHacker
if (KProcessHacker.Instance == null || !OSVersion.HasSetAccessToken)
setTokenProcessMenuItem.Visible = false;
if (KProcessHacker.Instance == null || !Properties.Settings.Default.EnableExperimentalFeatures)
protectionProcessMenuItem.Visible = false;
if (!OSVersion.HasUac)
virtualizationProcessMenuItem.Visible = false;
+33 -19
View File
@@ -50,6 +50,7 @@
this.label23 = new System.Windows.Forms.Label();
this.textIconMenuProcesses = new System.Windows.Forms.NumericUpDown();
this.tabAdvanced = new System.Windows.Forms.TabPage();
this.checkHidePhConnections = new System.Windows.Forms.CheckBox();
this.textMaxSamples = new System.Windows.Forms.NumericUpDown();
this.label6 = new System.Windows.Forms.Label();
this.buttonChangeReplaceTaskManager = new System.Windows.Forms.Button();
@@ -95,7 +96,7 @@
this.toolTipProvider = new System.Windows.Forms.ToolTip(this.components);
this.buttonCancel = new System.Windows.Forms.Button();
this.buttonApply = new System.Windows.Forms.Button();
this.checkHidePhConnections = new System.Windows.Forms.CheckBox();
this.checkEnableExperimentalFeatures = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.textUpdateInterval)).BeginInit();
this.tabControl.SuspendLayout();
this.tabGeneral.SuspendLayout();
@@ -177,7 +178,7 @@
//
this.checkWarnDangerous.AutoSize = true;
this.checkWarnDangerous.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.checkWarnDangerous.Location = new System.Drawing.Point(6, 78);
this.checkWarnDangerous.Location = new System.Drawing.Point(6, 102);
this.checkWarnDangerous.Name = "checkWarnDangerous";
this.checkWarnDangerous.Size = new System.Drawing.Size(228, 18);
this.checkWarnDangerous.TabIndex = 4;
@@ -383,6 +384,7 @@
//
// tabAdvanced
//
this.tabAdvanced.Controls.Add(this.checkEnableExperimentalFeatures);
this.tabAdvanced.Controls.Add(this.checkHidePhConnections);
this.tabAdvanced.Controls.Add(this.textMaxSamples);
this.tabAdvanced.Controls.Add(this.label6);
@@ -400,6 +402,19 @@
this.tabAdvanced.Text = "Advanced";
this.tabAdvanced.UseVisualStyleBackColor = true;
//
// checkHidePhConnections
//
this.checkHidePhConnections.AutoSize = true;
this.checkHidePhConnections.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.checkHidePhConnections.Location = new System.Drawing.Point(6, 150);
this.checkHidePhConnections.Name = "checkHidePhConnections";
this.checkHidePhConnections.Size = new System.Drawing.Size(235, 18);
this.checkHidePhConnections.TabIndex = 21;
this.checkHidePhConnections.Text = "Hide Process Hacker network connections";
this.toolTipProvider.SetToolTip(this.checkHidePhConnections, "Hides network connections made by Process Hacker. This may be useful when Process" +
" Hacker is resolving addresses.");
this.checkHidePhConnections.UseVisualStyleBackColor = true;
//
// textMaxSamples
//
this.textMaxSamples.Increment = new decimal(new int[] {
@@ -407,7 +422,7 @@
0,
0,
0});
this.textMaxSamples.Location = new System.Drawing.Point(118, 154);
this.textMaxSamples.Location = new System.Drawing.Point(118, 178);
this.textMaxSamples.Maximum = new decimal(new int[] {
10000,
0,
@@ -430,7 +445,7 @@
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(6, 156);
this.label6.Location = new System.Drawing.Point(6, 180);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(106, 13);
this.label6.TabIndex = 19;
@@ -440,7 +455,7 @@
// buttonChangeReplaceTaskManager
//
this.buttonChangeReplaceTaskManager.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.buttonChangeReplaceTaskManager.Location = new System.Drawing.Point(257, 51);
this.buttonChangeReplaceTaskManager.Location = new System.Drawing.Point(257, 75);
this.buttonChangeReplaceTaskManager.Name = "buttonChangeReplaceTaskManager";
this.buttonChangeReplaceTaskManager.Size = new System.Drawing.Size(89, 23);
this.buttonChangeReplaceTaskManager.TabIndex = 18;
@@ -452,7 +467,7 @@
//
this.checkReplaceTaskManager.AutoSize = true;
this.checkReplaceTaskManager.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.checkReplaceTaskManager.Location = new System.Drawing.Point(6, 54);
this.checkReplaceTaskManager.Location = new System.Drawing.Point(6, 78);
this.checkReplaceTaskManager.Name = "checkReplaceTaskManager";
this.checkReplaceTaskManager.Size = new System.Drawing.Size(245, 18);
this.checkReplaceTaskManager.TabIndex = 17;
@@ -477,7 +492,7 @@
//
this.checkHideHandlesWithNoName.AutoSize = true;
this.checkHideHandlesWithNoName.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.checkHideHandlesWithNoName.Location = new System.Drawing.Point(6, 102);
this.checkHideHandlesWithNoName.Location = new System.Drawing.Point(6, 126);
this.checkHideHandlesWithNoName.Name = "checkHideHandlesWithNoName";
this.checkHideHandlesWithNoName.Size = new System.Drawing.Size(160, 18);
this.checkHideHandlesWithNoName.TabIndex = 13;
@@ -489,7 +504,7 @@
//
this.checkVerifySignatures.AutoSize = true;
this.checkVerifySignatures.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.checkVerifySignatures.Location = new System.Drawing.Point(6, 30);
this.checkVerifySignatures.Location = new System.Drawing.Point(6, 54);
this.checkVerifySignatures.Name = "checkVerifySignatures";
this.checkVerifySignatures.Size = new System.Drawing.Size(254, 18);
this.checkVerifySignatures.TabIndex = 4;
@@ -932,18 +947,16 @@
this.buttonApply.UseVisualStyleBackColor = true;
this.buttonApply.Click += new System.EventHandler(this.buttonApply_Click);
//
// checkHidePhConnections
// checkEnableExperimentalFeatures
//
this.checkHidePhConnections.AutoSize = true;
this.checkHidePhConnections.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.checkHidePhConnections.Location = new System.Drawing.Point(6, 126);
this.checkHidePhConnections.Name = "checkHidePhConnections";
this.checkHidePhConnections.Size = new System.Drawing.Size(235, 18);
this.checkHidePhConnections.TabIndex = 21;
this.checkHidePhConnections.Text = "Hide Process Hacker network connections";
this.toolTipProvider.SetToolTip(this.checkHidePhConnections, "Hides network connections made by Process Hacker. This may be useful when Process" +
" Hacker is resolving addresses.");
this.checkHidePhConnections.UseVisualStyleBackColor = true;
this.checkEnableExperimentalFeatures.AutoSize = true;
this.checkEnableExperimentalFeatures.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.checkEnableExperimentalFeatures.Location = new System.Drawing.Point(6, 30);
this.checkEnableExperimentalFeatures.Name = "checkEnableExperimentalFeatures";
this.checkEnableExperimentalFeatures.Size = new System.Drawing.Size(168, 18);
this.checkEnableExperimentalFeatures.TabIndex = 22;
this.checkEnableExperimentalFeatures.Text = "Enable experimental features";
this.checkEnableExperimentalFeatures.UseVisualStyleBackColor = true;
//
// OptionsWindow
//
@@ -1054,5 +1067,6 @@
private System.Windows.Forms.CheckBox checkUndecorate;
private System.Windows.Forms.Button buttonApply;
private System.Windows.Forms.CheckBox checkHidePhConnections;
private System.Windows.Forms.CheckBox checkEnableExperimentalFeatures;
}
}
@@ -235,6 +235,7 @@ namespace ProcessHacker
checkVerifySignatures.Checked = Properties.Settings.Default.VerifySignatures;
checkHideHandlesWithNoName.Checked = Properties.Settings.Default.HideHandlesWithNoName;
checkEnableKPH.Checked = Properties.Settings.Default.EnableKPH;
checkEnableExperimentalFeatures.Checked = Properties.Settings.Default.EnableExperimentalFeatures;
checkStartHidden.Checked = Properties.Settings.Default.StartHidden;
checkHidePhConnections.Checked = Properties.Settings.Default.HideProcessHackerNetworkConnections;
@@ -341,6 +342,7 @@ namespace ProcessHacker
Properties.Settings.Default.HideHandlesWithNoName = checkHideHandlesWithNoName.Checked;
Properties.Settings.Default.StartHidden = checkStartHidden.Checked;
Properties.Settings.Default.EnableKPH = checkEnableKPH.Checked;
Properties.Settings.Default.EnableExperimentalFeatures = checkEnableExperimentalFeatures.Checked;
Properties.Settings.Default.ImposterNames = textImposterNames.Text.ToLower();
Properties.Settings.Default.HideProcessHackerNetworkConnections = checkHidePhConnections.Checked;
@@ -414,6 +416,7 @@ namespace ProcessHacker
Program.ImposterNames.Add(s.Trim());
Program.HackerWindow.ApplyIconVisibilities();
Program.HackerWindow.LoadFixMenuItems();
Program.ProcessProvider.Interval = Properties.Settings.Default.RefreshInterval;
Program.HackerWindow.ServiceProvider.Interval = Properties.Settings.Default.RefreshInterval;
Program.HackerWindow.NetworkProvider.Interval = Properties.Settings.Default.RefreshInterval;
+24 -24
View File
@@ -563,7 +563,7 @@
this.tabStatistics.Location = new System.Drawing.Point(4, 42);
this.tabStatistics.Name = "tabStatistics";
this.tabStatistics.Padding = new System.Windows.Forms.Padding(3);
this.tabStatistics.Size = new System.Drawing.Size(454, 383);
this.tabStatistics.Size = new System.Drawing.Size(481, 409);
this.tabStatistics.TabIndex = 9;
this.tabStatistics.Text = "Statistics";
this.tabStatistics.UseVisualStyleBackColor = true;
@@ -575,7 +575,7 @@
this.tabPerformance.Location = new System.Drawing.Point(4, 42);
this.tabPerformance.Name = "tabPerformance";
this.tabPerformance.Padding = new System.Windows.Forms.Padding(3);
this.tabPerformance.Size = new System.Drawing.Size(454, 383);
this.tabPerformance.Size = new System.Drawing.Size(481, 409);
this.tabPerformance.TabIndex = 8;
this.tabPerformance.Text = "Performance";
this.tabPerformance.UseVisualStyleBackColor = true;
@@ -594,7 +594,7 @@
this.tablePerformance.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tablePerformance.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tablePerformance.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tablePerformance.Size = new System.Drawing.Size(448, 377);
this.tablePerformance.Size = new System.Drawing.Size(475, 403);
this.tablePerformance.TabIndex = 1;
//
// groupCPUUsage
@@ -603,7 +603,7 @@
this.groupCPUUsage.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupCPUUsage.Location = new System.Drawing.Point(3, 3);
this.groupCPUUsage.Name = "groupCPUUsage";
this.groupCPUUsage.Size = new System.Drawing.Size(442, 119);
this.groupCPUUsage.Size = new System.Drawing.Size(469, 128);
this.groupCPUUsage.TabIndex = 0;
this.groupCPUUsage.TabStop = false;
this.groupCPUUsage.Text = "CPU Usage (Kernel, User)";
@@ -626,7 +626,7 @@
this.plotterCPUUsage.Name = "plotterCPUUsage";
this.plotterCPUUsage.OverlaySecondLine = false;
this.plotterCPUUsage.ShowGrid = true;
this.plotterCPUUsage.Size = new System.Drawing.Size(436, 100);
this.plotterCPUUsage.Size = new System.Drawing.Size(463, 109);
this.plotterCPUUsage.TabIndex = 0;
this.plotterCPUUsage.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
this.plotterCPUUsage.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0)))));
@@ -640,9 +640,9 @@
//
this.groupBox3.Controls.Add(this.plotterIO);
this.groupBox3.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox3.Location = new System.Drawing.Point(3, 253);
this.groupBox3.Location = new System.Drawing.Point(3, 271);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(442, 121);
this.groupBox3.Size = new System.Drawing.Size(469, 129);
this.groupBox3.TabIndex = 0;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "I/O (R+O, W)";
@@ -665,7 +665,7 @@
this.plotterIO.Name = "plotterIO";
this.plotterIO.OverlaySecondLine = true;
this.plotterIO.ShowGrid = true;
this.plotterIO.Size = new System.Drawing.Size(436, 102);
this.plotterIO.Size = new System.Drawing.Size(463, 110);
this.plotterIO.TabIndex = 0;
this.plotterIO.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
this.plotterIO.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0)))));
@@ -679,9 +679,9 @@
//
this.groupBox2.Controls.Add(this.plotterMemory);
this.groupBox2.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox2.Location = new System.Drawing.Point(3, 128);
this.groupBox2.Location = new System.Drawing.Point(3, 137);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(442, 119);
this.groupBox2.Size = new System.Drawing.Size(469, 128);
this.groupBox2.TabIndex = 0;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Memory (Private Pages, Working Set)";
@@ -704,7 +704,7 @@
this.plotterMemory.Name = "plotterMemory";
this.plotterMemory.OverlaySecondLine = true;
this.plotterMemory.ShowGrid = true;
this.plotterMemory.Size = new System.Drawing.Size(436, 100);
this.plotterMemory.Size = new System.Drawing.Size(463, 109);
this.plotterMemory.TabIndex = 0;
this.plotterMemory.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
this.plotterMemory.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0)))));
@@ -720,7 +720,7 @@
this.tabThreads.ImageKey = "hourglass";
this.tabThreads.Location = new System.Drawing.Point(4, 42);
this.tabThreads.Name = "tabThreads";
this.tabThreads.Size = new System.Drawing.Size(454, 383);
this.tabThreads.Size = new System.Drawing.Size(481, 409);
this.tabThreads.TabIndex = 3;
this.tabThreads.Text = "Threads";
this.tabThreads.UseVisualStyleBackColor = true;
@@ -733,7 +733,7 @@
this.listThreads.Location = new System.Drawing.Point(0, 0);
this.listThreads.Name = "listThreads";
this.listThreads.Provider = null;
this.listThreads.Size = new System.Drawing.Size(454, 383);
this.listThreads.Size = new System.Drawing.Size(481, 409);
this.listThreads.TabIndex = 0;
//
// tabToken
@@ -742,7 +742,7 @@
this.tabToken.Location = new System.Drawing.Point(4, 42);
this.tabToken.Name = "tabToken";
this.tabToken.Padding = new System.Windows.Forms.Padding(3);
this.tabToken.Size = new System.Drawing.Size(454, 383);
this.tabToken.Size = new System.Drawing.Size(481, 409);
this.tabToken.TabIndex = 1;
this.tabToken.Text = "Token";
this.tabToken.UseVisualStyleBackColor = true;
@@ -753,7 +753,7 @@
this.tabModules.ImageKey = "page_white_wrench";
this.tabModules.Location = new System.Drawing.Point(4, 42);
this.tabModules.Name = "tabModules";
this.tabModules.Size = new System.Drawing.Size(454, 383);
this.tabModules.Size = new System.Drawing.Size(481, 409);
this.tabModules.TabIndex = 6;
this.tabModules.Text = "Modules";
this.tabModules.UseVisualStyleBackColor = true;
@@ -765,7 +765,7 @@
this.listModules.Location = new System.Drawing.Point(0, 0);
this.listModules.Name = "listModules";
this.listModules.Provider = null;
this.listModules.Size = new System.Drawing.Size(454, 383);
this.listModules.Size = new System.Drawing.Size(481, 409);
this.listModules.TabIndex = 0;
//
// tabMemory
@@ -778,7 +778,7 @@
this.tabMemory.Location = new System.Drawing.Point(4, 42);
this.tabMemory.Name = "tabMemory";
this.tabMemory.Padding = new System.Windows.Forms.Padding(3);
this.tabMemory.Size = new System.Drawing.Size(454, 383);
this.tabMemory.Size = new System.Drawing.Size(481, 409);
this.tabMemory.TabIndex = 4;
this.tabMemory.Text = "Memory";
this.tabMemory.UseVisualStyleBackColor = true;
@@ -874,7 +874,7 @@
this.listMemory.Location = new System.Drawing.Point(6, 59);
this.listMemory.Name = "listMemory";
this.listMemory.Provider = null;
this.listMemory.Size = new System.Drawing.Size(442, 318);
this.listMemory.Size = new System.Drawing.Size(469, 344);
this.listMemory.TabIndex = 0;
//
// tabEnvironment
@@ -884,7 +884,7 @@
this.tabEnvironment.Location = new System.Drawing.Point(4, 42);
this.tabEnvironment.Name = "tabEnvironment";
this.tabEnvironment.Padding = new System.Windows.Forms.Padding(3);
this.tabEnvironment.Size = new System.Drawing.Size(454, 383);
this.tabEnvironment.Size = new System.Drawing.Size(481, 409);
this.tabEnvironment.TabIndex = 10;
this.tabEnvironment.Text = "Environment";
this.tabEnvironment.UseVisualStyleBackColor = true;
@@ -900,7 +900,7 @@
this.listEnvironment.Location = new System.Drawing.Point(3, 3);
this.listEnvironment.Name = "listEnvironment";
this.listEnvironment.ShowItemToolTips = true;
this.listEnvironment.Size = new System.Drawing.Size(448, 377);
this.listEnvironment.Size = new System.Drawing.Size(475, 403);
this.listEnvironment.Sorting = System.Windows.Forms.SortOrder.Ascending;
this.listEnvironment.TabIndex = 0;
this.listEnvironment.UseCompatibleStateImageBehavior = false;
@@ -924,7 +924,7 @@
this.tabHandles.Location = new System.Drawing.Point(4, 42);
this.tabHandles.Name = "tabHandles";
this.tabHandles.Padding = new System.Windows.Forms.Padding(3);
this.tabHandles.Size = new System.Drawing.Size(454, 383);
this.tabHandles.Size = new System.Drawing.Size(481, 409);
this.tabHandles.TabIndex = 5;
this.tabHandles.Text = "Handles";
this.tabHandles.UseVisualStyleBackColor = true;
@@ -950,7 +950,7 @@
this.listHandles.Location = new System.Drawing.Point(6, 30);
this.listHandles.Name = "listHandles";
this.listHandles.Provider = null;
this.listHandles.Size = new System.Drawing.Size(442, 347);
this.listHandles.Size = new System.Drawing.Size(469, 373);
this.listHandles.TabIndex = 0;
//
// tabJob
@@ -958,7 +958,7 @@
this.tabJob.ImageKey = "wrench";
this.tabJob.Location = new System.Drawing.Point(4, 42);
this.tabJob.Name = "tabJob";
this.tabJob.Size = new System.Drawing.Size(454, 383);
this.tabJob.Size = new System.Drawing.Size(481, 409);
this.tabJob.TabIndex = 11;
this.tabJob.Text = "Job";
this.tabJob.UseVisualStyleBackColor = true;
@@ -968,7 +968,7 @@
this.tabServices.ImageKey = "cog";
this.tabServices.Location = new System.Drawing.Point(4, 42);
this.tabServices.Name = "tabServices";
this.tabServices.Size = new System.Drawing.Size(454, 383);
this.tabServices.Size = new System.Drawing.Size(481, 409);
this.tabServices.TabIndex = 7;
this.tabServices.Text = "Services";
this.tabServices.UseVisualStyleBackColor = true;
+206 -210
View File
@@ -123,8 +123,8 @@
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>577, 17</value>
</metadata>
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>577, 17</value>
<metadata name="menuSearch.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>338, 17</value>
</metadata>
<metadata name="imageList.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>235, 17</value>
@@ -133,223 +133,219 @@
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAA2
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAy
MQAAAk1TRnQBSQFMAgEBCwEAAQwBAAEEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABMAMAAQEBAAEgBgABMFYAAxUBHQMjATQDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AyQBNgMk
ATYDJAE2AyMBMwMVAR0IAAJeAVoC1QGDAT8B/wHRAWsBOQH/A1QBr2wAAYcBAAGAAf8BgwEAASkB/wEq
AQABKAH/AScBAAEnAf8BJAEAASYB/wHGAgAB/wHGAgAB/wHEAgAB/wHAAgAB/wHAAgAB/wG/AgAB/wEn
AgAB/wElAgAB/wEiAgAB/wEgAgAB/wEeAgAB/wQAAyMBNAN0AfUDvAH9A/wB/wP8Af8D/AH/A/wB/wP8
Af8D/AH/A/wB/wP8Af8DvAH9A3AB8wMjATMEAANcAcwB3wGkAYEB/wHqAcIBqwH/AeoBwAGoAf8B3AGZ
AV8B/wNUAa9qAAHzAf8BmQGbAf4B/wGWAZgB/gH/AZMBlQH+Af8BkQGTAf4B/wHJAgAB/wHgAZMBCAH/
Ad8BjwEEAf8B3wGNAQAB/wHeAYoBAAH/AcACAAH/AaIByQGeAf8BnQHGAZkB/wGYAcMBlQH/AZQBwAGR
Af8BAAEYAQAB/wMAAQEDJAE2A88B/gP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8
Af8DvAH9AyQBNgQAAdsBlwFdAf8B7QHIAbMB/wHnAbgBmwH/AeYBtAGYAf8B6gHDAasB/wHeAZwBYQH/
A1QBr2YAAfUB/wGeAaAB/gH/AQYBCQH+Af8BAQEEAf4B/wGVAZcB/gH/Ac0CAAH/AeEBlwEOAf8B2gGA
AQAB/wHZASgBAAH/Ad8BjwEDAf8BxgIAAf8BqAHNAaQB/wEiAbABHAH/ARsBqwEVAf8BmgHEAZYB/wEA
ASEBAAH/AwABAQMkATYD/AH/A/wB/wPdAf8D2wH/A9kB/wPXAf8D1QH/A9QB/wPUAf8D1AH/A/sB/wP8
Af8DJAE2AwABAQHdAZ8BZwH/Ae0BzAG3Af8B6AG9AaMB/wHkAbEBkgH/AeYBtgGaAf8B6gHDAawB/wHe
AZwBYgH/AlQBUwGsYgAB9gH/AaIBpAH+Af8BDQERAf4B/wEIAQwB/gH/AZkBmwH+Af8BzwIAAf8B4wGc
ARcB/wHcAYYBAAH/AdsBgwEAAf8B4AGUAQkB/wHGAgAB/wGvAdEBqwH/AYABtwElAf8BJAGyAR4B/wGg
ATYDJAE2AyMBMwMVAR0IAAJeAVoC1QGDATwB/wHRAWgBNgH/A1QBr2wAAYcBAAGAAf8BgwEAASYB/wEn
AQABJQH/ASQBAAEkAf8BIQEAASMB/wHGAgAB/wHGAgAB/wHEAgAB/wHAAgAB/wHAAgAB/wG/AgAB/wEk
AgAB/wEiAgAB/wEfAgAB/wEdAgAB/wEbAgAB/wQAAyMBNANuAfUDuQH9A/wB/wP8Af8D/AH/A/wB/wP8
Af8D/AH/A/wB/wP8Af8DuQH9A20B8wMjATMEAANcAcwB3wGkAYEB/wHqAcIBqwH/AeoBwAGoAf8B3AGZ
AVwB/wNUAa9qAAHzAf8BmQGbAf4B/wGWAZgB/gH/AZMBlQH+Af8BkQGTAf4B/wHJAgAB/wHgAZMBBQH/
Ad8BjwEBAf8B3wGNAQAB/wHeAYoBAAH/AcACAAH/AaIByQGeAf8BnQHGAZkB/wGYAcMBlQH/AZQBwAGR
Af8BAAEVAQAB/wMAAQEDJAE2A8kB/gP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8
Af8DuQH9AyQBNgQAAdsBlwFaAf8B7QHIAbMB/wHnAbgBmwH/AeYBtAGYAf8B6gHDAasB/wHeAZwBXgH/
A1QBr2YAAfUB/wGeAaAB/gH/AQMBBgH+Af8BAAEBAf4B/wGVAZcB/gH/Ac0CAAH/AeEBlwELAf8B2gGA
AQAB/wHZASUBAAH/Ad8BjwEAAf8BxgIAAf8BqAHNAaQB/wEfAbABGQH/ARgBqwESAf8BmgHEAZYB/wEA
AR4BAAH/AwABAQMkATYD/AH/A/wB/wPdAf8D2wH/A9kB/wPXAf8D1QH/A9QB/wPUAf8D1AH/A/sB/wP8
Af8DJAE2AwABAQHdAZ8BZAH/Ae0BzAG3Af8B6AG9AaMB/wHkAbEBkgH/AeYBtgGaAf8B6gHDAawB/wHe
AZwBXwH/AlQBUwGsYgAB9gH/AaIBpAH+Af8BCgEOAf4B/wEFAQkB/gH/AZkBmwH+Af8BzwIAAf8B4wGc
ARQB/wHcAYYBAAH/AdsBgwEAAf8B4AGUAQYB/wHGAgAB/wGvAdEBqwH/AYABtwEiAf8BIQGyARsB/wGg
AcgBnAH/AQABgAEAAf8DAAEBAyQBNgP8Af8D/AH/A/wB/wP8Af8D+wH/A/sB/wP6Af8D+gH/A/oB/wP6
Af8D+gH/A/wB/wMkATYDAAEBA0wBkgHmAbMBlAH/Ae4BzAG4Af8B6QG+AaUB/wHlAbMBlAH/AeYBtwGb
Af8B6gHEAa0B/wHeAZ4BZgH/AlQBUwGsXAACBgH4Af8BqAGqAf4B/wEWARoB/gH/ARABFAH+Af8BngGg
Af4B/wHRAQsBAAH/AeUBogEfAf8B3gGMAQAB/wHdAYkBAAH/AeIBmQERAf8ByQIAAf8BtQHVAbAB/wGK
Ab0BgwH/AYMBuAEoAf8BpwHNAaMB/wEAAYsBAAH/AwABAQMkATYD/AH/A/wB/wPWAf8D0wH/A88B/wPN
Af8B6gHEAa0B/wHeAZ4BYwH/AlQBUwGsXAACAwH4Af8BqAGqAf4B/wETARcB/gH/AQ0BEQH+Af8BngGg
Af4B/wHRAQgBAAH/AeUBogEcAf8B3gGMAQAB/wHdAYkBAAH/AeIBmQEOAf8ByQIAAf8BtQHVAbAB/wGK
Ab0BgwH/AYMBuAElAf8BpwHNAaMB/wEAAYsBAAH/AwABAQMkATYD/AH/A/wB/wPWAf8D0wH/A88B/wPN
Af8DywH/A8gB/wPIAf8DxgH/A/gB/wP8Af8DJAE2AwABAQQAA0wBkgHmAbQBmAH/Ae4BzQG6Af8B6QG/
AaUB/wHlAbQBlgH/AecBuQGdAf8B6wHGAa4B/wHeAZ8BZwH/A1MBqlgAAQ4BDwH6Af8BrAGvAf4B/wEd
ASEB/gH/ARgBHAH+Af8BogGkAf4B/wHWARQBAAH/AecBpwEmAf8B4AGSAQcB/wHfAY8BAQH/AeQBngEZ
AaUB/wHlAbQBlgH/AecBuQGdAf8B6wHGAa4B/wHeAZ8BZAH/A1MBqlgAAQsBDAH6Af8BrAGvAf4B/wEa
AR4B/gH/ARUBGQH+Af8BogGkAf4B/wHWAREBAAH/AecBpwEjAf8B4AGSAQQB/wHfAY8BAAH/AeQBngEW
Af8BzQIAAf8BugHZAbUB/wG3AdYBsQH/AbMB0wGuAf8BrgHRAakB/wEAAZYBAAH/AwABAQMkATYD/AH/
A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/sB/wP5Af8D+QH/A/gB/wP8Af8DJAE2AwABAQgAA0wBkgHm
AbcBmQH/Ae4BzgG7Af8B6QHAAacB/wHoAb0BowH/AewByAGzAf8B3wGkAYEB/wNcAclYAAEVARcB/AH/
AbABswH+Af8BJAEpAf4B/wEgASQB/gH/AagBqgH+Af8B2AEfAQAB/wHoAa0BgwH/AeIBmAEQAf8B4QGV
AQsB/wHlAaMBIQH/Ac8BAgEAAf8BCwG8ARcB/wEHAbYBEgH/AQIBsAEMAf8BAAGoAQcB/wEAAaEBAAH/
AwABAQMkATYD/AH/A/wB/wPOAf8DygH/A8YB/wPDAf8DwAH/A70B/wO8Af8DugH/A/YB/wP8Af8DJAE2
AwABAQwAA0wBkgHmAbcBnAH/Ae8BzwG8Af8B7gHOAboB/wHiAa4BjAH/AdIBmwFpAf8DbQH3AxkBI1QA
ARsBHgH9Af8BtAG3Af4B/wGBAYUB/gH/AScBgQH+Af8BrAGvAf4B/wHZASYBAAH/AeoBsgGKAf8B5AGf
ARkB/wHjAZwBFQH/AecBqAEoAf8B0QENAQAB/xcAAQEDJAE2A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/
A/sB/wP4Af8D9gH/A/MB/wPyAf8D/AH/AyQBNgMAAQEQAANMAZIB5wG5AZwB/wHmAbYBmAH/AdgBqQGM
Af8D0gH/A7UB/wN/Af4DYgH7A18B+wNgAdYDQAFwRAABHwEjAf4B/wG4AbsB/gH/AbYBuQH+Af8BswG2
Af4B/wGwAbMB/gH/Ad8BhAEAAf8B7AG3AZIB/wHmAaUBIwH/AeYBogEeAf8B6QGtAYUB/wHWARYBAAH/
FwABAQMkATYD/AH/A/wB/wPHAf8DwgH/A74B/wO4Af8DtAH/A7EB/wOuAf8DrAH/A+0B/wP8Af8DJAE2
AwABARQAA0wBkgNcAc8DgAH7A8cB/wPMAf8DxwH/A8YB/wPDAf8DwAH/A2QB9QNAAXBAAAEfASMB/gH/
AR8BIwH+Af8BHQEhAf4B/wEZARwB/QH/ARUBFwH8Af8B4QGNAQAB/wHtAbsBmQH/AekBrAGBAf8B5wGo
AScB/wHqAbMBjQH/AdgBHwEAAf8XAAEBAyQBNgP8Af8D+wH/A/wB/wP8Af8D+wH/A/gB/wP1Af8D8QH/
A+wB/wPqAf8D5gH/A/wB/wMkATYDAAEBHAADLgFIA38B/gPUAf8DyAH/A7wB/wO6Af8DwgH/A8QB/wNg
AdZUAAHiAZIBBwH/Ae4BwQGgAf8B6gGxAYkB/wHpAa4BhQH/Ae0BtwGUAf8B2wEnAQAB/xcAAQEDJAE2
A/wB/wP5Af8DwAH/A7oB/wO0Af8DrwH/A6oB/wOlAf8D/AH/A/wB/wP8Af8D/AH/AyQBNgMAAQEgAAN1
AfwD3QH/A8UB/wNYAcEDWwHDA6wB/wPXAf8DYgH7VAAB5gGbARIB/wHwAcUBpgH/AewBtgGRAf8B6wGz
AYwB/wHuAbwBmwH/Ad8BhQEAAf8XAAEBAyQBNgP8Af8D9wH/A/kB/wP3Af8D9wH/A/MB/wPwAf8D6gH/
A/wB/wP2Af8D9AH/A00BkQMXASAkAAOFAfsD5AH/A88B/wNZAcIEAAOOAf8DjAH/A2oB+1QAAegBoAEb
Af8B8gHIAawB/wHwAcYBqAH/AfABxQGmAf8B7wHCAaIB/wHhAY4BAAH/GAADJAE2A7wB/QP0Af8D9QH/
A/UB/wP1Af8D8QH/A+8B/wPpAf8D/AH/A+cB/wNNAZEDFwEgAwEBAiQAA2AB1gPiAf8D5wH/A7kB/wOT
Af9gAAHqAaYBIgH/AegBpAEfAf8B6AGgARkB/wHmAZ0BFgH/AeQBmQEQAf8B4gGVAQkB/xgAAyMBMwNm
AfADvAH9A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/gB/wNNAZEDFwEgAwEBAigAA0ABcANrAfUD5AH/
A+4B/wOWAf+QAAMUARwDIwEzAyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDFwEgAwEBAjAA
A0ABcANgAdYDhwH7A4YB+2QAAwoBDQEiAiEBMQMgAS8DBQEHGAADEQEXAasCAAH/AWIBWQFIAfYDKQE/
NAADBgEIAUACPwFuA1YBswFeAlgB3QFSAl0B9AFAAYQBpgH9AgABswH/AgABqAH/AkABnAH9AlIBXQH0
AVoCWAHdA1YBswFAAj8BbgMGAQhQAAMYASEDUAGdAV0CVAHwA6EB/wOrAf8DpwH/A5UB/wFkAlwB5wNK
AYoDEAEWDAABugIAAf8BwAGJAQAB/wG/AYkBAAH/Aa8CAAH/AyoBQTAAAVsCWQHEAYcBtwHgAf8BlQHG
AeYB/wGbAc0B6QH/AZwBzQHpAf8BmQHHAecB/wGVAcEB5AH/AY4BuAHgAf8BiQGwAd0B/wGBAacB1wH/
AQABmwHPAf8BAAGMAcIB/wIAAa4B/wFbAlkBxBAAAwkBDAJGAUcBgQJZAVwByQIAAegB/wMfAS0oAAMv
AUoBZQJdAfQDzgH/A+0B/wP0Af8D9QH/A/QB/wPvAf8D4gH/A7oB/wFkAlwB5wMkATUIAAHDAYgBAAH/
Ac8BogEAAf8BzQGiAYEB/wHAAYwBAAH/AbACAAH/AU4CTQGVAzEBTgMmATkDFgEeAwMBBBwAAVsCWQHE
AZgBuQHUAf8BxQHHAcQB/wHsAdgBxwH/AfYB6wHjAf8B+gH1AfEB/wHzAecB3gH/Ad8BvwGmAf8B0AGk
AYEB/wHLAZoBAAH/AcgBlwEAAf8BowGTAYwB/wIAAZwB/wFbAlkBxAwAAy0BRQJaAWAB3gIAAesB/wEF
AQYB5wH/AgAB6QH/Ax8BLQFdAlkB0gFcAlkByQFHAkYBgQMJAQwYAAFcAlUB6gPeAf8D8wH/A9sB/wPS
Af8D2wH/A9YB/wPAAf8DyQH/A+YB/wPEAf8BXAJVAeoIAANAAXEBzAGZAQAB/wHQAaMBgQH/Ac8BpAGD
Af8BygGeAQAB/wG8AYUBAAH/Aa8CAAH/AacCAAH/AZ4CAAH/AVsCWAHGAwcBCRgAAx0BKgHmAcMBpQH/
Ae8B1gHAAf8B+wHyAeoB/wH+AfwB+gL/Af4B/QH/Af4B/QH8Af8B/AH2AfAB/wH4AegB2QH/AfYB4wHR
Af8B9gHiAc4B/wHmAcgBrQH/Ac4BoAEAAf8DHQEqCAADNAFUAgAB8wH/ARYBGAHuAf8BlAGZAesB/wGN
AZEB6QH/AgAB7AH/Ax8BLQFdAlkB0gHWAY4BAAH/AbgCAAH/AWACWgHeAy4BSBQAAVwCVQHqA/AB/wPe
Af8D1AH/A9IB/wPbAf8D1gH/A78B/wOwAf8DswH/A94B/wFcAlUB6gwAA0EBcgHOAZ0BAAH/AdUBrAGM
Af8BywGbAQAB/wHMAaABAAH/AcgBmwEAAf8BxQGVAQAB/wHAAY8BAAH/AawCAAH/A0IBdhwAAVgCVgG5
Ae0B0wG7Af8B+gHwAeUB/wH9AfkB9QH/Af4B/AH6Af8B/gH9AfwB/wH9AfkB9AH/AfYB4wHPAf8B9wHl
AdMB/wH2AeMB0QH/Ad0BuQGaAf8BVwJWAbgIAAMQARUDXwHzAZUBmQHyAf8BpQGqAe4B/wEUAYEB5gH/
AZcBmgHrAf8CAAHvAf8DHwEtAV0BWwFZAdIB2wGZAQkB/wHmAaQBGAH/AcsBgAEAAf8BpgIAAf8DNAFU
EAABXAJVAeoD8gH/A+IB/wPYAf8D1QH/A9wB/wPYAf8DwAH/A7MB/wO3Af8D4AH/AVwCVQHqEAABVgJV
AbEB0wGoAYYB/wHWAawBjgH/AckBmAEAAf8BxAGQAQAB/wG/AYoBAAH/AcIBjwEAAf8BvwGLAQAB/wFf
AV0BRgH7Ax0BKRwAAVUCUwGwA38B/gH3AeoB3gH/Af4B+gH3Af8B/gH8AfkB/wH9AfcB8gH/AfoB7QHi
Af8B6wHQAbcB/wJ/AX4B/gNUAa4MAAMNAREDTgGZAmIBagH5AYQBhQH0Af8BowGoAe8B/wGgAaUB7QH/
AgAB8QH/Ax8BLQJdAVkB0gHeAaEBEgH/Ad4BiQEAAf8B5gGmARgB/wHQAYcBAAH/AV8CTAHzAxABFQwA
AVwCVQHqA/MB/wPnAf8D3QH/A9kB/wPgAf8D2wH/A8QB/wO4Af8DuwH/A+EB/wFcAlUB6hAAAzEBTgHU
AaMBAAH/AdwBtQGYAf8B0AGhAQAB/wHMAZoBAAH/Ac8BpAGDAf8ByAGaAQAB/wEAAYwBAAH/AQABuAEA
Af8BXwFOATAB+wNUAa8DBwEJGAADJwE6AWECWwHhAfMB4gHSAf8B/AH0Ae0B/wH7AfEB5wH/AekBzAG1
Af8BYQJcAdwDJgE4EAADQgFzAzwBZgMUARsDSgGNAl0BXwHzARUBFwHzAf8CAAH0Af8DHwEtAl0BWQHS
AeEBqAGBAf8B4AGSAQAB/wHZARIBAAH/AecBqAGEAf8BvgEJAQAB/wNIAYQMAAFcAlUB6gP0Af8D6gH/
A+EB/wPdAf8D4wH/A94B/wPJAf8DvQH/A78B/wPiAf8BXAJVAeoQAAMmATkB2wGrAYkB/wHhAb0BogH/
AdYBqgGHAf8B2QGzAZQB/wHOAZ8BAAH/AV8CXQH7AQABvAEAAf8BkwIAAf8BsAIAAf8BpAIAAf8BYQJe
AdoDAwEEHAADWQHHAfQB4wHQAf8B8wHfAc0B/wFbAlkBwxgAAVkBXAFZAc8BkAG/AZMB/wFVAVwBVQHq
A0EBcgMVAR0DRAF7A10B7QMfAS0CXQFZAdIB5AGwAYsB/wHjAZwBBgH/Ad0BhQEAAf8B4gGWAQAB/wHa
AZcBBgH/AVwCWQHPDAABXAJVAeoD9QH/A+4B/wPmAf8D4gH/A+YB/wPhAf8DzQH/A8IB/wPCAf8D4wH/
AVwCVQHqEAADFgEeAeABsQGPAf8B5gHEAasB/wHiAb8BpAH/AdgBrQGOAf8DTQH6A0MBdwMrAfwBuwGE
AQAB/wHAAY8BAAH/AbwBigEAAf8BnAIAAf8DFgEeHAABWwJZAcMB9AHhAc4B/wHzAd8BzAH/AVkCVwHC
GAABWgJdAfABygHoAcgB/wGvAdkBqwH/AZIBvwGUAf8DXQHtAUUBRgFFAX4DDwEUAxIBGAJdAVkB0gHn
AbcBkwH/AecBpgEQAf8B4AGQAQAB/wHeAY4BAAH/AeYBrQGIAf8BXwFUAUwB8wwAAVwCVQHqA/YB/wPr
Af8D3gH/A9YB/wPVAf8D0QH/A8MB/wO8Af8DwAH/A+UB/wFcAlUB6hAAAwMBBAFhAl4B2gHkAbsBnwH/
AeQBuwGfAf8DKwH8AQABwQEAAf8DKwH8AccBlgEAAf8BywGeAQAB/wG8AYUBAAH/AcMBkgEAAf8BpgIA
Af8DJgE5FAADJgE4AV4CWAHdAfMB3QHJAf8B+gHuAeIB/wH5AesB3gH/Ae0B0AG2Af8BXwJaAdsDJgE4
EAABYAJqAfkBtgHgAbEB/wEUAcwBCAH/AZIB0gGJAf8BrQHZAakB/wGJAbgBiwH/A1ABnQM1AVYCYgFJ
AfYB7wHIAakB/wHmAaYBDAH/AeIBmwEAAf8B4gGYAQAB/wHnAbMBjwH/AV0BXAFOAfAMAAFcAlUB6gP3
Af8D5wH/A+8B/wP2Af8D+wH/A/oB/wPwAf8D3gH/A8MB/wPmAf8BXAJVAeoUAAMHAQkDVAGvAWoCZgH5
AQABxQGCAf8BtQGwAYEB/wHYAbABkgH/AdcBrgGPAf8ByQGXAQAB/wHDAY8BAAH/AcgBmwEAAf8BsQIA
Af8DMQFOEAADVAGvA38B/gH5AewB4AH/Af0B+AH0Af8B+wHwAeYB/wH4AecB1wH/AfkB6wHeAf8B8gHa
AcUB/wN/Af4DVAGuDAADXAHPAboB3wG4Af8BEwHMAQYB/wEAAcYBAAH/AQsByAEAAf8BqAHaAaMB/wEB
AagBBgH/AygBPANbAcMB5gG1AY4B/wHwAcwBrAH/AeUBpgEKAf8B6QGxAYQB/wHjAa8BiAH/AlwBWQHP
DAABXAJVAeoD+AH/A/4Z/wP7Af8D6gH/AVwCVQHqHAADGwEmAagBpgGEAf0B4gG+AaMB/wHfAbcBmgH/
AdUBqAGGAf8B0AGhAQAB/wHLAZoBAAH/Ac4BogGBAf8BvwGLAQAB/wFOAk0BlQwAAVcCVgG4AfkB4wHN
Af8B+wHzAewB/wH+AfoB9wH/Af4B+wH4Af8B/AH1Ae0B/wH3AeYB1QH/AfYB4QHMAf8B+QHsAd8B/wH5
AesB3QH/AesBzgG0Af8BVwJWAbgIAANIAYQBswHaAbUB/wGiAdgBmgH/AQYBygEAAf8BAAHGAQAB/wGA
AcwBDgH/AaMBzgGjAf8BWQFcAVkBzwMiATIBLgIrAfwB8gHRAbIB/wHrAbkBjQH/AfAByQGqAf8B2AGc
AQkB/wNIAYQMAAFZAlcBvwPhAf8D/hn/A/sB/wPPAf8BUgJRAaEgAANCAXYB5AG6AZ0B/wHmAcQBqwH/
AeIBvgGkAf8B3gG5AZwB/wHZAbIBkwH/AdEBowEAAf8B0QGmAYUB/wG7AgAB/wMpAT8EAAMdASoBwAHF
Ac0B/wGaAbcB3AH/AQABpgHVAf8BAAGVAcoB/wEAAYcBvgH/AgABswH/AgABqAH/AgABnwH/AgABmAH/
AgABmgH/AQABgwGnAf8BiAGUAZoB/wMdASoEAAMNARIDXwHzAb4B4QG+Af8BlAHUAYkB/wEHAcoBAAH/
AQcByQEAAf8BngHWAZcB/wGTAcEBlgH/Az0BaQNOAZYB5wG0AY4B/wHzAdMBtQH/AekBuwGYAf8CXwFM
AfMDDQESDAADHQEqAVwCWAHRA9AB/wPoAf8D8wH/A/0B/wP8Af8D7QH/A+AB/wPCAf8BWwJZAcMDFAEb
IAADBwEJAVsCWAHGAeMBtAGTAf8B3wGxAY4B/wHaAasBiQH/AdoBrQGMAf8B3AG1AZgB/wHXAa8BkAH/
AcwBmwEAAf8DTQH6BAABXAJYAdEBhwG3AeAB/wGVAcYB5gH/AZsBzQHpAf8BnAHNAekB/wGZAccB5wH/
AZUBwQHkAf8BjgG4AeAB/wGJAbAB3QH/AYEBpwHXAf8BAAGbAc8B/wEAAYwBwgH/AgABrgH/AVwCWAHR
CAADMgFRAaAB1QGoAf8BugHgAbsB/wGnAdoBoAH/ARYBzgEJAf8BGAHNAQwB/wGwAdkBrQH/A10B7QMZ
ASMDXQHtAesBwgGeAf8B3QGiAQwB/wMyAVEUAAMFAQcBNQI0AVUDVAGuAWACWwHWAV8CXQH7AWoCZgH5
AVwCWgHNA1IBqQMtAUYDAgEDKAADAwEEAxYBHgMmATkDMQROAZQB2AGnAYIB/wHXAawBiwH/AdMBpwGE
Af8BYgFcAUkB9gQAAVsCWQHEAYcBtwHgAf8BlQHGAeYB/wGdAc8B6gH/AaEB0wHsAf8BoAHRAesB/wGb
AcoB6AH/AZYBwgHlAf8BjwG6AeIB/wGHAbEB3QH/AQABowHUAf8BAAGQAcQB/wIAAa4B/wFbAlkBxAwA
AykBPwNgAd4BtAHcAbcB/wG8AeABugH/AbkB4QG1Af8BzgHqAcsB/wGkAc4BpgH/AU0CTgGWAz0BaQNg
Ad4DKQE/fAADKQE+AV8CXQH7AWICXAH2Ay4BSAQAAwYBCAFAAj8BbgNWAbMBXgJYAd0BZQJdAfQBQAGd
AaYB/QEAAZkB0QH/AQABkAHIAf8BQAGEAaYB/QFSAl0B9AFaAlgB3QNWAbMBQAI/AW4DBgEIEAADCQEM
A0YBfgNbAcYDKwH8AysB/ANbAcYDRQF9AwIBAwMHAQoRAAGdAdkB/wEAAZkB2AH/AQABlAHXAf8BAAGQ
AdYB/wEAAYwB1QH/AQABiAHUAf8BAAGEAdMB/wEAAYEB0gH/AgAB0QH/AgAB0QH/AgAB0AH/AgABzwH/
AgABzwH/AgABzgH/YAADOwFjAVkCVwG/AVgCVwG/AzsBYyAAAxUBHQMjATQDJAE2AyQBNgMkATYDJAE2
AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AyMBMwMVAR0BAAGjAdoB/wG8AesB+gH/AbwB6wH8Af8BvwHu
Af4B/wHGAfQC/wHOAfgC/wHTAfoC/wHQAfgC/wHHAfIC/wG6AekB/AH/AbMB5AH5Af8BsAHiAfgB/wGw
AeIB+AH/AgABzwH/VAADHQEpAwoBDgMBAQIBXAJVAeoDvQH/A7IB/wFcAlUB6gMBAQIDCgEOAx0BKRQA
AyMBNANZAfUBqAKmAf0D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wGoAqYB/QFfAl0B8wMj
ATMBAAGoAdsB/wG/AewB+wH/AQABzwH1Af8BAAGwAewB/wMAAf8CAAGJAf8BAAGJAb4B/wEAAZoByAH/
AQABrgHnAf8BAAGlAeYB/wEAAZoB4QH/AQABuAHuAf8BsQHjAfgB/wIAAdAB/wgAA1IBqQHDAY4BAAH/
AcABiwEAAf8BvgGIAQAB/wG7AYUBAAH/AbkBgwEAAf8BtAIAAf8BsgIAAf8BsQIAAf8BrgIAAf8BrQIA
Af8BqwIAAf8BqQIAAf8BqQIAAf8DUgGpDAABUAJPAZsDQAH9AWQCXAHnAxIBGQFkAlwB5wPLAf8DxwH/
AWMCXAHnAxIBGQNcAecDQAH9AVACTwGbCAADNwFbAV0BVAFOAfABYgFcAUgB9gHlAbcBmgH/AfsC+gH/
A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/AagCpgH9AyQBNgEAAa0B3AH/AcEB7gH7
Af8BAAHTAfcB/wEAAdsB/AH/AgABhQH/AZQBxwH5Af8BkQHJAfkB/wEAAYUByQH/AgABrgH/AQABvQHs
Af8BAAG+Ae8B/wEAAboB7gH/AbMB4wH5Af8CAAHRAf8IAAHIAZIBADX/AakCAAH/CAADRAF7A7wB/wPe
Af8DpgH/AWUCXQH0A38B/gPEAf8DwgH/AW4CbQH+AWUCXQH0A6YB/wPSAf8DgQH/A0QBewQAAWICWAHv
AeYBuAGcAf8B6QG/AaUB/wHcAZsBAAH/AeUBuAGdAf8D/AH/A/wB/wP8Af8D+wH/A/sB/wP7Af8D+wH/
A/sB/wP7Af8D/AH/AyQBNgEAAbIB3QH/AcMB7wH7Af8BAAHWAfgB/wEAAbYB7AH/AQABiQGqAf8B4AHy
Av8BAAGaAdgB/wIAAb4B/wEAAZgBxQH/AQABhgHFAf8BAAGbAd4B/wEAAb4B7wH/AbQB5QH5Af8CAAHS
Af8IAAHKAZQBAAv/Af4D/wH9Af8C/gH9Af8C/gH8Af8C/gH8Af8C/gH8Af8C/gH8Af8C/gH6Af8C/gH6
Af8C/AH5Bf8BqgIAAf8IAANFAX0DfwH+A9UB/wPFAf8DywH/A9EB/wPJAf8DxwH/A8wB/wPFAf8DvQH/
A8sB/wFvAm4B/gNFAX0EAAFtAmcB9wHrAcQBrQH/AewByAGyAf8B6gHBAakB/wHeAZ4BAAH/AecBuwGh
Af8D/AH/A/sB/wP7Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP8Af8DJAE2AQABtwHeAf8BxgHwAfwB/wEA
AdkB+AH/AQAB4gH9Af8BAAG3AdkB/wEAAbYB1QH/AZABtwHRAf8BAAHJAeQB/wEAAd8B9QH/AQAB0AHt
Af8BAAGYAdwB/wEAAboB7QH/AbYB5wH5Af8BAAGDAdMB/wgAAcwBlwEAB/8B/AP/Af0B/wL+AfwB/wL+
AfwB/wL+AfsB/wL9AfoB/wL9AfoB/wL9AfoB/wL9AfoB/wL8AfcB/wL7AfYF/wGsAgAB/wwAA0gBhQPF
Af8DwQH/A8UB/wPHAf8DqgH/A6cB/wPBAf8DvgH/A7UB/wOqAf8DSAGFCAADQgF1AWoCZgH5AewBxwGw
Af8B7QHKAbUB/wHrAcMBqwH/Ad4BoQEAAf8B5wG6AZ8B/wP7Af8D+wH/A/sB/wP6Af8D+gH/A/gB/wP4
Af8D/AH/AyQBNgEAAbsB3wH/AccB8QH8Af8BAAHcAfkB/wEAAbsB7QH/AQABvQHvAf8BAAHGAecB/wEA
AbgB1gH/AcIB9gH9Af8BAAHfAfcB/wEAAeIB+AH/AQAB0wHwAf8BAAGXAdwB/wGoAdwB9QH/AQABiAHU
Af8IAAHRAZwBAAX/Av4B/AH/Av4B/AH/Av4B/AH/Av0B+wH/Av0B+wH/Av0B+gH/Av0B+AH/AvsB+QH/
AfsB+gH3Af8B+wH6AfYB/wH7AfgB9AX/AbACAAH/BAABXAJaAc0BXwJYAeMBYQJWAe4DzwH/A8YB/wPM
Af8BWwJYAcYDLAFEAywBRAFbAlgBxgPBAf8DvAH/A7kB/wFhAlYB7gFbAlgB4wNaAc0EAANDAXgDfwH+
Ae0ByAGzAf8B7QHNAbgB/wHpAb4BowH/AdYBjgEAAf8D/AH/A/wB/wP8Af8D+wH/A/kB/wP5Af8D+AH/
A/wB/wMkATYBAAG/AeAB/wHIAfMB/AH/AQAB3wH5Af8BiQHmAf0B/wGVAecC/wGaAeUC/wEAAcoB5wH/
AQABywHnAf8BxwH3Af0B/wEAAdwB9QH/AQAB4QH3Af8BAAHUAfEB/wEAAZkB3gH/AQABjQHWAf8IAAHU
AZ4BAAX/Av4B/AH/Av0B+wH/Av0B/AH/Av0B+wH/Av0B+QH/AvwB+AH/AfsB+QH3Af8B+wH5AfUB/wH7
AfgB9AH/AfsB9wHyAf8B+wH1AfIF/wGyAgAB/wQAAagCpgH9A+IB/wPSAf8DxgH/A80B/wOxAf8DLAFE
CAADLAFEA6gB/wPCAf8DtwH/A8AB/wPSAf8DQAH9BwABAQNMAZIB4AGpAYgB/wHrAccBsAH/Ad0BoQEA
Af8BvAGlAZUB/wOsAf8D0AH/A9QB/wPvAf8D+QH/A/YB/wP2Af8D/AH/AyQBNgEAAcIB4QH/AckB8wH8
Af8BywHzAf0B/wHUAfYB/gH/AdcB9gL/AdgB9AL/AeAB+AL/AakB4wH1Af8BAAHTAe4B/wHHAfcB/QH/
AQAB3AH1Af8BAAHiAfcB/wEAAdYB8gH/AQABmAHeAf8DIQEwBAAB1QGgAQAF/wL9AfwB/wL9AfsB/wL9
AfoB/wL8AfkB/wH8AfsB9wH/AfsB+QH1Af8B+wH4AfQB/wH7AfcB8wH/AfsB9QHyAf8B+gHzAe8B/wH4
AfIB7AX/AbUCAAH/BAABqAKmAf0D6QH/A9YB/wPJAf8DzgH/A6UB/wMsAUQIAAMsAUQDrAH/A8QB/wO6
Af8DxgH/A90B/wNAAf0HAAEBAyQBNgHwAdYBxgH/Ad4BrQGQAf8BxAGvAaMB/wPVAf8DuwH/A6YB/wOg
Af8DkAH/A8kB/wPzAf8D8gH/A/wB/wMkATYBAAHDAeEB/wGIAaABqAH/A5EB/wOOAf8BAAG5AdwB/wEA
AbgB3wH/AQABtQHeAf8BAAGxAd0B/wEAAbAB3gH/AQAB1AHuAf8BxAH2Af0B/wEAAd0B9gH/AQABygHt
Af8BAAGjAdcB/wFgAlkB7AMbASYB2AGiAQAF/wL9AfoB/wL8AfoB/wH8AfsB+QH/AfsB+gH2Af8B+wH4
AfUB/wH7AfcB9AH/AfsB9gHxAf8B+AH0Ae4B/wH3AfIB6wH/AfcB8AHqAf8B9gHsAegF/wG3AYEBAAH/
BAABXAJaAc0BXwJYAeMBYQJWAe4D2AH/A80B/wO8Af8BWwJYAcYDLAFEAywBRAFbAlgBxgPDAf8DwgH/
A80B/wFhAlYB7gFfAlgB4wFcAloBzQcAAQEDJAE2A/wB/wP7Af8DrAH/A8sB/wPSAf8DyQH/A9IB/wPG
Af8DjwH/A+8B/wPtAf8D/AH/AyQBNgQAAVsCWQHDA8YB/wOUAf8DBgEIEAADNwFaAQAB0wHrAf8BsgHj
AfkB/wGLAcAB5wH/Aa4B0wH2Af8BxAHgAfwB/wNnAfcB2QGjAQAF/wH8AfsB+QH/AfwB+wH4Af8B+wH5
AfcB/wH7AfcB9AH/AfoB9wHyAf8B+QH1AfAB/wH3AfMB7QH/AfYB7wHqAf8B9QHrAecB/wHzAeoB5AH/
AfIB5wHeBf8BugGFAQAB/wwAA0gBhQPUAf8DzAH/A8kB/wO6Af8DnAH/A6EB/wPCAf8DxgH/A8EB/wO3
Af8DSAGFDwABAQMkATYD/AH/A/sB/wPbAf8DsgH/A9YB/wOgAf8DkgH/A8AB/wOKAf8D6gH/A+YB/wP8
Af8DJAE2BAADVAGuA8QB/wOhAf8DHQEpEAADHQEpAQABmQGpAf8BAAG+AecB/wG0AdIB8AH/AeUB8wL/
AawB0gHvAf8BXwJXAegB2wGkAQA1/wG9AYcBAAH/CAADRQF9A38B/gPcAf8D1AH/A9kB/wPbAf8D1gH/
A9QB/wPZAf8D0gH/A8sB/wPIAf8BegJ5Af4DRQF9CwABAQMkATYD/AH/A/kB/wPaAf8DtQH/A+YB/wOa
Af8DsAH/A68B/wO9Af8D/AH/A/wB/wP8Af8DJAE2BAADQgF1A7oB/wO/Af8BXgJYAd0DFgEfAwQBBQME
AQUDFgEfAWUCXgHlA6gB/wEAAaQBswH/AQABpQHYAf8BhQGxAdsB/wEAAZ0B0AH/AzgBXgHcAacBAAH/
AdwBpwEAAf8B3AGnAQAB/wHcAacBAAH/AdwBpwEAAf8B3AGnAQAB/wHcAacBAAH/AdwBpwEAAf8B3AGn
AQAB/wHcAacBAAH/AdwBpwEAAf8B3AGnAQAB/wHcAacBAAH/AdwBpwEAAf8BwAGLAQAB/wgAA0QBewPc
Af8D7QH/A9sB/wFlAl0B9AN/Af4D1gH/A9QB/wN/Af4BZQJdAfQDywH/A+cB/wO3Af8DRAF7CwABAQMk
ATYD/AH/A/cB/wPvAf8DpgH/A+EB/wPSAf8DtAH/A+oB/wP8Af8D9gH/A/QB/wFNAkwBkQMXASAEAAMJ
AQwBXwJaAdsDxAH/A74B/wOhAf8DlgH/A5MB/wOXAf8DrgH/A64B/wFfAloB2wMHAQkMAAGoAaYBgwH9
AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5
AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8BqAGOAUAB/QwAAVACTwGb
AagCpgH9AWQCXAHnAxIBGQFkAlwB5wPeAf8D3QH/AWQCXAHnAxIBGQFkAlwB5wGnAqUB/QFQAk8BmxAA
AyQBNgGoAqYB/QP0Af8D9QH/A9QB/wOlAf8DnQH/A74B/wPpAf8D/AH/A+cB/wFNAkwBkQMXASADAQEC
CAADIQEwAWACWgHeA7wB/wPKAf8DzAH/A8oB/wPCAf8DrQH/AWACWgHeAyEBMBAAAz4BawFlAl0B9AHc
AacBAAH/AdwBpgEAAf8B2gGkAQAB/wHYAaIBAAH/AdUBoAEAAf8B1AGeAQAB/wHSAZ0BAAH/Ac8BmgEA
Af8BzgGZAQAB/wHLAZYBAAH/AckBlAEAAf8BZQJdAfQDPgFrEAADHQEpAwoBDgMBAQIBXAJVAeoD5QH/
A+QB/wFcAlUB6gMBAQIDCgEOAx0BKRQAAyMBMwFdAlQB8AGoAqYB/QP8Af8D/AH/A/wB/wP8Af8D/AH/
A/wB/wP4Af8BTQJMAZEDFwEgAwEBAhAAAwkBDAFHAkYBgQFXAlUBugFcAlkBzAFcAlkBzAFXAlUBugFH
AkYBgQMJAQxsAAM7AWMBWQJXAb8BWQJXAb8DOwFjIAADFAEcAyMBMwMkATYDJAE2AyQBNgMkATYDJAE2
AyQBNgMkATYDJAE2AxcBIAMBAQIIAAFCAU0BPgcAAT4DAAEoAwABQAMAATADAAEBAQABAQUAAYABARYA
A/8BAAL/AYABAQGHAf8EAAGAAQEBAwH/BQACAQH/BwAB/wcAAX8GAAGAAT8GAAHAAT8GAAHgAR8DAAEf
AgAB8AEBAwABHwIAAfgEAAEfAgAB/gMAAfgBHwIAAf8DAAH4AR8BAAEBAf8BCAIAAfgBHwGAAQEB/wEH
AgAB+AEfAYABAwH/AQcCAAL/AYABBwH/AYcCAAH8AT8BDwH/AYABAQL/AeACBwH/AYABAQHgAf8BwAED
AQABPwGAAQEBwAEPAcABAwEAAR8BgAEBAYABBwHAAQMBgAEfAcABAwEAAQMBwAEDAcABDwHgAQcBAAEB
AcABAwHAAQMB8AEPAQABAQHAAQMBwAEBAfwBPwEAAQEBwAEDAcABAQH8AT8BAAEBAcABAwHAAQEB8AEP
AQABAQHAAQMB4AEBAeABBwEAAQEBwAEDAfgBAQHAAQMBAAEBAcABAwH8AQABgAEBAQABAQHAAQMB/AEA
AYABAQGAAQMB4AEHAf4BAAGAAQEBwAEHA/8B8AGAAQEB4AEPAQABAwL/AfwBPwHAAgABAwL/AeABBwHA
AgABAwEAAQEBwAEDAwABAwEAAQEBgAEBAwABAwEAAQEBgAEBAwABAwEAAQEBwAEDAwABAwEAAQECAAGA
AgABAwEAAgECgAIAAQEBAAIBAoAEAAEBAgABgAEAAYcBgAEAAQEBwAEDAYABAAGHAYABAAEBAYABAQGA
AQABgAIAAQEBgAEBAYABAAGAAQcBAAEBAcABAwHAAQABwAEPAQABAQHgAQcBwAEBAeABHwL/AfwBPwHA
AQML
AbcBmQH/Ae4BzgG7Af8B6QHAAacB/wHoAb0BowH/AewByAGzAf8B3wGkAYEB/wNcAclYAAESARQB/AH/
AbABswH+Af8BIQEmAf4B/wEdASEB/gH/AagBqgH+Af8B2AEcAQAB/wHoAa0BgwH/AeIBmAENAf8B4QGV
AQgB/wHlAaMBHgH/Ac8CAAH/AQgBvAEUAf8BBAG2AQ8B/wEAAbABCQH/AQABqAEEAf8BAAGhAQAB/wMA
AQEDJAE2A/wB/wP8Af8DzgH/A8oB/wPGAf8DwwH/A8AB/wO9Af8DvAH/A7oB/wP2Af8D/AH/AyQBNgMA
AQEMAANMAZIB5gG3AZwB/wHvAc8BvAH/Ae4BzgG6Af8B4gGuAYwB/wHSAZsBZgH/A20B9wMZASNUAAEY
ARsB/QH/AbQBtwH+Af8BgQGFAf4B/wEkAYEB/gH/AawBrwH+Af8B2QEjAQAB/wHqAbIBigH/AeQBnwEW
Af8B4wGcARIB/wHnAagBJQH/AdEBCgEAAf8XAAEBAyQBNgP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP7
Af8D+AH/A/YB/wPzAf8D8gH/A/wB/wMkATYDAAEBEAADTAGSAecBuQGcAf8B5gG2AZgB/wHYAakBjAH/
A9IB/wO1Af8DfwH+A18B+wNfAfsDYAHWA0ABcEQAARwBIAH+Af8BuAG7Af4B/wG2AbkB/gH/AbMBtgH+
Af8BsAGzAf4B/wHfAYQBAAH/AewBtwGSAf8B5gGlASAB/wHmAaIBGwH/AekBrQGFAf8B1gETAQAB/xcA
AQEDJAE2A/wB/wP8Af8DxwH/A8IB/wO+Af8DuAH/A7QB/wOxAf8DrgH/A6wB/wPtAf8D/AH/AyQBNgMA
AQEUAANMAZIDXAHPA3kB+wPHAf8DzAH/A8cB/wPGAf8DwwH/A8AB/wNeAfUDQAFwQAABHAEgAf4B/wEc
ASAB/gH/ARoBHgH+Af8BFgEZAf0B/wESARQB/AH/AeEBjQEAAf8B7QG7AZkB/wHpAawBgQH/AecBqAEk
Af8B6gGzAY0B/wHYARwBAAH/FwABAQMkATYD/AH/A/sB/wP8Af8D/AH/A/sB/wP4Af8D9QH/A/EB/wPs
Af8D6gH/A+YB/wP8Af8DJAE2AwABARwAAy4BSAN/Af4D1AH/A8gB/wO8Af8DugH/A8IB/wPEAf8DYAHW
VAAB4gGSAQQB/wHuAcEBoAH/AeoBsQGJAf8B6QGuAYUB/wHtAbcBlAH/AdsBJAEAAf8XAAEBAyQBNgP8
Af8D+QH/A8AB/wO6Af8DtAH/A68B/wOqAf8DpQH/A/wB/wP8Af8D/AH/A/wB/wMkATYDAAEBIAADcgH8
A90B/wPFAf8DWAHBA1sBwwOsAf8D1wH/A18B+1QAAeYBmwEPAf8B8AHFAaYB/wHsAbYBkQH/AesBswGM
Af8B7gG8AZsB/wHfAYUBAAH/FwABAQMkATYD/AH/A/cB/wP5Af8D9wH/A/cB/wPzAf8D8AH/A+oB/wP8
Af8D9gH/A/QB/wNNAZEDFwEgJAADggH7A+QB/wPPAf8DWQHCBAADjgH/A4wB/wNiAftUAAHoAaABGAH/
AfIByAGsAf8B8AHGAagB/wHwAcUBpgH/Ae8BwgGiAf8B4QGOAQAB/xgAAyQBNgO5Af0D9AH/A/UB/wP1
Af8D9QH/A/EB/wPvAf8D6QH/A/wB/wPnAf8DTQGRAxcBIAMBAQIkAANgAdYD4gH/A+cB/wO5Af8DkwH/
YAAB6gGmAR8B/wHoAaQBHAH/AegBoAEWAf8B5gGdARMB/wHkAZkBDQH/AeIBlQEGAf8YAAMjATMDYQHw
A7kB/QP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP4Af8DTQGRAxcBIAMBAQIoAANAAXADaAH1A+QB/wPu
Af8DlgH/kAADFAEcAyMBMwMkATYDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AxcBIAMBAQIwAANA
AXADYAHWA4QB+wODAftkAAMKAQ0BIgIhATEDIAEvAwUBBxgAAxEBFwGrAgAB/wFiAVkBSAH2AykBPzQA
AwYBCAFAAj8BbgNWAbMBXgJYAd0BUgJdAfQBQAGEAaYB/QIAAbMB/wIAAagB/wJAAZwB/QJSAV0B9AFa
AlgB3QNWAbMBQAI/AW4DBgEIUAADGAEhA1ABnQFdAlQB8AOhAf8DqwH/A6cB/wOVAf8BZAJcAecDSgGK
AxABFgwAAboCAAH/AcABiQEAAf8BvwGJAQAB/wGvAgAB/wMqAUEwAAFbAlkBxAGHAbcB4AH/AZUBxgHm
Af8BmwHNAekB/wGcAc0B6QH/AZkBxwHnAf8BlQHBAeQB/wGOAbgB4AH/AYkBsAHdAf8BgQGnAdcB/wEA
AZsBzwH/AQABjAHCAf8CAAGuAf8BWwJZAcQQAAMJAQwCRgFHAYECWQFcAckCAAHoAf8DHwEtKAADLwFK
AWUCXQH0A84B/wPtAf8D9AH/A/UB/wP0Af8D7wH/A+IB/wO6Af8BZAJcAecDJAE1CAABwwGIAQAB/wHP
AaIBAAH/Ac0BogGBAf8BwAGMAQAB/wGwAgAB/wFOAk0BlQMxAU4DJgE5AxYBHgMDAQQcAAFbAlkBxAGY
AbkB1AH/AcUBxwHEAf8B7AHYAccB/wH2AesB4wH/AfoB9QHxAf8B8wHnAd4B/wHfAb8BpgH/AdABpAGB
Af8BywGaAQAB/wHIAZcBAAH/AaMBkwGMAf8CAAGcAf8BWwJZAcQMAAMtAUUCWgFgAd4CAAHrAf8BAgED
AecB/wIAAekB/wMfAS0BXQJZAdIBXAJZAckBRwJGAYEDCQEMGAABXAJVAeoD3gH/A/MB/wPbAf8D0gH/
A9sB/wPWAf8DwAH/A8kB/wPmAf8DxAH/AVwCVQHqCAADQAFxAcwBmQEAAf8B0AGjAYEB/wHPAaQBgwH/
AcoBngEAAf8BvAGFAQAB/wGvAgAB/wGnAgAB/wGeAgAB/wFbAlgBxgMHAQkYAAMdASoB5gHDAaUB/wHv
AdYBwAH/AfsB8gHqAf8B/gH8AfoC/wH+Af0B/wH+Af0B/AH/AfwB9gHwAf8B+AHoAdkB/wH2AeMB0QH/
AfYB4gHOAf8B5gHIAa0B/wHOAaABAAH/Ax0BKggAAzQBVAIAAfMB/wETARUB7gH/AZQBmQHrAf8BjQGR
AekB/wIAAewB/wMfAS0BXQJZAdIB1gGOAQAB/wG4AgAB/wFgAloB3gMuAUgUAAFcAlUB6gPwAf8D3gH/
A9QB/wPSAf8D2wH/A9YB/wO/Af8DsAH/A7MB/wPeAf8BXAJVAeoMAANBAXIBzgGdAQAB/wHVAawBjAH/
AcsBmwEAAf8BzAGgAQAB/wHIAZsBAAH/AcUBlQEAAf8BwAGPAQAB/wGsAgAB/wNCAXYcAAFYAlYBuQHt
AdMBuwH/AfoB8AHlAf8B/QH5AfUB/wH+AfwB+gH/Af4B/QH8Af8B/QH5AfQB/wH2AeMBzwH/AfcB5QHT
Af8B9gHjAdEB/wHdAbkBmgH/AVcCVgG4CAADEAEVA18B8wGVAZkB8gH/AaUBqgHuAf8BEQGBAeYB/wGX
AZoB6wH/AgAB7wH/Ax8BLQFdAVsBWQHSAdsBmQEGAf8B5gGkARUB/wHLAYABAAH/AaYCAAH/AzQBVBAA
AVwCVQHqA/IB/wPiAf8D2AH/A9UB/wPcAf8D2AH/A8AB/wOzAf8DtwH/A+AB/wFcAlUB6hAAAVYCVQGx
AdMBqAGGAf8B1gGsAY4B/wHJAZgBAAH/AcQBkAEAAf8BvwGKAQAB/wHCAY8BAAH/Ab8BiwEAAf8BXwFd
AUYB+wMdASkcAAFVAlMBsAN/Af4B9wHqAd4B/wH+AfoB9wH/Af4B/AH5Af8B/QH3AfIB/wH6Ae0B4gH/
AesB0AG3Af8CfwF+Af4DVAGuDAADDQERA04BmQJiAWoB+QGEAYUB9AH/AaMBqAHvAf8BoAGlAe0B/wIA
AfEB/wMfAS0CXQFZAdIB3gGhAQ8B/wHeAYkBAAH/AeYBpgEVAf8B0AGHAQAB/wFfAkwB8wMQARUMAAFc
AlUB6gPzAf8D5wH/A90B/wPZAf8D4AH/A9sB/wPEAf8DuAH/A7sB/wPhAf8BXAJVAeoQAAMxAU4B1AGj
AQAB/wHcAbUBmAH/AdABoQEAAf8BzAGaAQAB/wHPAaQBgwH/AcgBmgEAAf8BAAGMAQAB/wEAAbgBAAH/
AV8BTgEwAfsDVAGvAwcBCRgAAycBOgFhAlsB4QHzAeIB0gH/AfwB9AHtAf8B+wHxAecB/wHpAcwBtQH/
AWECXAHcAyYBOBAAA0IBcwM8AWYDFAEbA0oBjQJdAV8B8wESARQB8wH/AgAB9AH/Ax8BLQJdAVkB0gHh
AagBgQH/AeABkgEAAf8B2QEPAQAB/wHnAagBhAH/Ab4BBgEAAf8DSAGEDAABXAJVAeoD9AH/A+oB/wPh
Af8D3QH/A+MB/wPeAf8DyQH/A70B/wO/Af8D4gH/AVwCVQHqEAADJgE5AdsBqwGJAf8B4QG9AaIB/wHW
AaoBhwH/AdkBswGUAf8BzgGfAQAB/wFfAl0B+wEAAbwBAAH/AZMCAAH/AbACAAH/AaQCAAH/AWECXgHa
AwMBBBwAA1kBxwH0AeMB0AH/AfMB3wHNAf8BWwJZAcMYAAFZAVwBWQHPAZABvwGTAf8BVQFcAVUB6gNB
AXIDFQEdA0QBewNdAe0DHwEtAl0BWQHSAeQBsAGLAf8B4wGcAQMB/wHdAYUBAAH/AeIBlgEAAf8B2gGX
AQMB/wFcAlkBzwwAAVwCVQHqA/UB/wPuAf8D5gH/A+IB/wPmAf8D4QH/A80B/wPCAf8DwgH/A+MB/wFc
AlUB6hAAAxYBHgHgAbEBjwH/AeYBxAGrAf8B4gG/AaQB/wHYAa0BjgH/A00B+gNDAXcDKwH8AbsBhAEA
Af8BwAGPAQAB/wG8AYoBAAH/AZwCAAH/AxYBHhwAAVsCWQHDAfQB4QHOAf8B8wHfAcwB/wFZAlcBwhgA
AVoCXQHwAcoB6AHIAf8BrwHZAasB/wGSAb8BlAH/A10B7QFFAUYBRQF+Aw8BFAMSARgCXQFZAdIB5wG3
AZMB/wHnAaYBDQH/AeABkAEAAf8B3gGOAQAB/wHmAa0BiAH/AV8BVAFMAfMMAAFcAlUB6gP2Af8D6wH/
A94B/wPWAf8D1QH/A9EB/wPDAf8DvAH/A8AB/wPlAf8BXAJVAeoQAAMDAQQBYQJeAdoB5AG7AZ8B/wHk
AbsBnwH/AysB/AEAAcEBAAH/AysB/AHHAZYBAAH/AcsBngEAAf8BvAGFAQAB/wHDAZIBAAH/AaYCAAH/
AyYBORQAAyYBOAFeAlgB3QHzAd0ByQH/AfoB7gHiAf8B+QHrAd4B/wHtAdABtgH/AV8CWgHbAyYBOBAA
AWACagH5AbYB4AGxAf8BEQHMAQUB/wGSAdIBiQH/Aa0B2QGpAf8BiQG4AYsB/wNQAZ0DNQFWAmIBSQH2
Ae8ByAGpAf8B5gGmAQkB/wHiAZsBAAH/AeIBmAEAAf8B5wGzAY8B/wFdAVwBTgHwDAABXAJVAeoD9wH/
A+cB/wPvAf8D9gH/A/sB/wP6Af8D8AH/A94B/wPDAf8D5gH/AVwCVQHqFAADBwEJA1QBrwFqAmYB+QEA
AcUBggH/AbUBsAGBAf8B2AGwAZIB/wHXAa4BjwH/AckBlwEAAf8BwwGPAQAB/wHIAZsBAAH/AbECAAH/
AzEBThAAA1QBrwN/Af4B+QHsAeAB/wH9AfgB9AH/AfsB8AHmAf8B+AHnAdcB/wH5AesB3gH/AfIB2gHF
Af8DfwH+A1QBrgwAA1wBzwG6Ad8BuAH/ARABzAEDAf8BAAHGAQAB/wEIAcgBAAH/AagB2gGjAf8BAAGo
AQMB/wMoATwDWwHDAeYBtQGOAf8B8AHMAawB/wHlAaYBBwH/AekBsQGEAf8B4wGvAYgB/wJcAVkBzwwA
AVwCVQHqA/gB/wP+Gf8D+wH/A+oB/wFcAlUB6hwAAxsBJgGoAaYBhAH9AeIBvgGjAf8B3wG3AZoB/wHV
AagBhgH/AdABoQEAAf8BywGaAQAB/wHOAaIBgQH/Ab8BiwEAAf8BTgJNAZUMAAFXAlYBuAH5AeMBzQH/
AfsB8wHsAf8B/gH6AfcB/wH+AfsB+AH/AfwB9QHtAf8B9wHmAdUB/wH2AeEBzAH/AfkB7AHfAf8B+QHr
Ad0B/wHrAc4BtAH/AVcCVgG4CAADSAGEAbMB2gG1Af8BogHYAZoB/wEDAcoBAAH/AQABxgEAAf8BgAHM
AQsB/wGjAc4BowH/AVkBXAFZAc8DIgEyAysB/AHyAdEBsgH/AesBuQGNAf8B8AHJAaoB/wHYAZwBBgH/
A0gBhAwAAVkCVwG/A+EB/wP+Gf8D+wH/A88B/wFSAlEBoSAAA0IBdgHkAboBnQH/AeYBxAGrAf8B4gG+
AaQB/wHeAbkBnAH/AdkBsgGTAf8B0QGjAQAB/wHRAaYBhQH/AbsCAAH/AykBPwQAAx0BKgHAAcUBzQH/
AZoBtwHcAf8BAAGmAdUB/wEAAZUBygH/AQABhwG+Af8CAAGzAf8CAAGoAf8CAAGfAf8CAAGYAf8CAAGa
Af8BAAGDAacB/wGIAZQBmgH/Ax0BKgQAAw0BEgNfAfMBvgHhAb4B/wGUAdQBiQH/AQQBygEAAf8BBAHJ
AQAB/wGeAdYBlwH/AZMBwQGWAf8DPQFpA04BlgHnAbQBjgH/AfMB0wG1Af8B6QG7AZgB/wJfAUwB8wMN
ARIMAAMdASoBXAJYAdED0AH/A+gB/wPzAf8D/QH/A/wB/wPtAf8D4AH/A8IB/wFbAlkBwwMUARsgAAMH
AQkBWwJYAcYB4wG0AZMB/wHfAbEBjgH/AdoBqwGJAf8B2gGtAYwB/wHcAbUBmAH/AdcBrwGQAf8BzAGb
AQAB/wNNAfoEAAFcAlgB0QGHAbcB4AH/AZUBxgHmAf8BmwHNAekB/wGcAc0B6QH/AZkBxwHnAf8BlQHB
AeQB/wGOAbgB4AH/AYkBsAHdAf8BgQGnAdcB/wEAAZsBzwH/AQABjAHCAf8CAAGuAf8BXAJYAdEIAAMy
AVEBoAHVAagB/wG6AeABuwH/AacB2gGgAf8BEwHOAQYB/wEVAc0BCQH/AbAB2QGtAf8DXQHtAxkBIwNd
Ae0B6wHCAZ4B/wHdAaIBCQH/AzIBURQAAwUBBwE1AjQBVQNUAa4BYAJbAdYBXwJdAfsBagJmAfkBXAJa
Ac0DUgGpAy0BRgMCAQMoAAMDAQQDFgEeAyYBOQMxBE4BlAHYAacBggH/AdcBrAGLAf8B0wGnAYQB/wFi
AVwBSQH2BAABWwJZAcQBhwG3AeAB/wGVAcYB5gH/AZ0BzwHqAf8BoQHTAewB/wGgAdEB6wH/AZsBygHo
Af8BlgHCAeUB/wGPAboB4gH/AYcBsQHdAf8BAAGjAdQB/wEAAZABxAH/AgABrgH/AVsCWQHEDAADKQE/
A2AB3gG0AdwBtwH/AbwB4AG6Af8BuQHhAbUB/wHOAeoBywH/AaQBzgGmAf8BTQJOAZYDPQFpA2AB3gMp
AT98AAMpAT4BXwJdAfsBYgJcAfYDLgFIBAADBgEIAUACPwFuA1YBswFeAlgB3QFlAl0B9AFAAZ0BpgH9
AQABmQHRAf8BAAGQAcgB/wFAAYQBpgH9AVICXQH0AVoCWAHdA1YBswFAAj8BbgMGAQgQAAMJAQwDRgF+
A1sBxgMrAfwDKwH8A1sBxgNFAX0DAgEDAwcBChEAAZ0B2QH/AQABmQHYAf8BAAGUAdcB/wEAAZAB1gH/
AQABjAHVAf8BAAGIAdQB/wEAAYQB0wH/AQABgQHSAf8CAAHRAf8CAAHRAf8CAAHQAf8CAAHPAf8CAAHP
Af8CAAHOAf9gAAM7AWMBWQJXAb8BWAJXAb8DOwFjIAADFQEdAyMBNAMkATYDJAE2AyQBNgMkATYDJAE2
AyQBNgMkATYDJAE2AyQBNgMkATYDIwEzAxUBHQEAAaMB2gH/AbwB6wH6Af8BvAHrAfwB/wG/Ae4B/gH/
AcYB9AL/Ac4B+AL/AdMB+gL/AdAB+AL/AccB8gL/AboB6QH8Af8BswHkAfkB/wGwAeIB+AH/AbAB4gH4
Af8CAAHPAf9UAAMdASkDCgEOAwEBAgFcAlUB6gO9Af8DsgH/AVwCVQHqAwEBAgMKAQ4DHQEpFAADIwE0
A1kB9QGoAqYB/QP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/AagCpgH9AV8CXQHzAyMBMwEA
AagB2wH/Ab8B7AH7Af8BAAHPAfUB/wEAAbAB7AH/AwAB/wIAAYkB/wEAAYkBvgH/AQABmgHIAf8BAAGu
AecB/wEAAaUB5gH/AQABmgHhAf8BAAG4Ae4B/wGxAeMB+AH/AgAB0AH/CAADUgGpAcMBjgEAAf8BwAGL
AQAB/wG+AYgBAAH/AbsBhQEAAf8BuQGDAQAB/wG0AgAB/wGyAgAB/wGxAgAB/wGuAgAB/wGtAgAB/wGr
AgAB/wGpAgAB/wGpAgAB/wNSAakMAAFQAk8BmwNAAf0BZAJcAecDEgEZAWQCXAHnA8sB/wPHAf8BYwJc
AecDEgEZA1wB5wNAAf0BUAJPAZsIAAM3AVsBXQFUAU4B8AFiAVwBSAH2AeUBtwGaAf8B+wL6Af8D/AH/
A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8BqAKmAf0DJAE2AQABrQHcAf8BwQHuAfsB/wEA
AdMB9wH/AQAB2wH8Af8CAAGFAf8BlAHHAfkB/wGRAckB+QH/AQABhQHJAf8CAAGuAf8BAAG9AewB/wEA
Ab4B7wH/AQABugHuAf8BswHjAfkB/wIAAdEB/wgAAcgBkgEANf8BqQIAAf8IAANEAXsDvAH/A94B/wOm
Af8BZQJdAfQDfwH+A8QB/wPCAf8BbgJtAf4BZQJdAfQDpgH/A9IB/wOBAf8DRAF7BAABYgJYAe8B5gG4
AZwB/wHpAb8BpQH/AdwBmwEAAf8B5QG4AZ0B/wP8Af8D/AH/A/wB/wP7Af8D+wH/A/sB/wP7Af8D+wH/
A/sB/wP8Af8DJAE2AQABsgHdAf8BwwHvAfsB/wEAAdYB+AH/AQABtgHsAf8BAAGJAaoB/wHgAfIC/wEA
AZoB2AH/AgABvgH/AQABmAHFAf8BAAGGAcUB/wEAAZsB3gH/AQABvgHvAf8BtAHlAfkB/wIAAdIB/wgA
AcoBlAEAC/8B/gP/Af0B/wL+Af0B/wL+AfwB/wL+AfwB/wL+AfwB/wL+AfwB/wL+AfoB/wL+AfoB/wL8
AfkF/wGqAgAB/wgAA0UBfQN/Af4D1QH/A8UB/wPLAf8D0QH/A8kB/wPHAf8DzAH/A8UB/wO9Af8DywH/
AW8CbgH+A0UBfQQAAW0CZwH3AesBxAGtAf8B7AHIAbIB/wHqAcEBqQH/Ad4BngEAAf8B5wG7AaEB/wP8
Af8D+wH/A/sB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/wB/wMkATYBAAG3Ad4B/wHGAfAB/AH/AQAB2QH4
Af8BAAHiAf0B/wEAAbcB2QH/AQABtgHVAf8BkAG3AdEB/wEAAckB5AH/AQAB3wH1Af8BAAHQAe0B/wEA
AZgB3AH/AQABugHtAf8BtgHnAfkB/wEAAYMB0wH/CAABzAGXAQAH/wH8A/8B/QH/Av4B/AH/Av4B/AH/
Av4B+wH/Av0B+gH/Av0B+gH/Av0B+gH/Av0B+gH/AvwB9wH/AvsB9gX/AawCAAH/DAADSAGFA8UB/wPB
Af8DxQH/A8cB/wOqAf8DpwH/A8EB/wO+Af8DtQH/A6oB/wNIAYUIAANCAXUBagJmAfkB7AHHAbAB/wHt
AcoBtQH/AesBwwGrAf8B3gGhAQAB/wHnAboBnwH/A/sB/wP7Af8D+wH/A/oB/wP6Af8D+AH/A/gB/wP8
Af8DJAE2AQABuwHfAf8BxwHxAfwB/wEAAdwB+QH/AQABuwHtAf8BAAG9Ae8B/wEAAcYB5wH/AQABuAHW
Af8BwgH2Af0B/wEAAd8B9wH/AQAB4gH4Af8BAAHTAfAB/wEAAZcB3AH/AagB3AH1Af8BAAGIAdQB/wgA
AdEBnAEABf8C/gH8Af8C/gH8Af8C/gH8Af8C/QH7Af8C/QH7Af8C/QH6Af8C/QH4Af8C+wH5Af8B+wH6
AfcB/wH7AfoB9gH/AfsB+AH0Bf8BsAIAAf8EAAFcAloBzQFfAlgB4wFhAlYB7gPPAf8DxgH/A8wB/wFb
AlgBxgMsAUQDLAFEAVsCWAHGA8EB/wO8Af8DuQH/AWECVgHuAVsCWAHjA1oBzQQAA0MBeAN/Af4B7QHI
AbMB/wHtAc0BuAH/AekBvgGjAf8B1gGOAQAB/wP8Af8D/AH/A/wB/wP7Af8D+QH/A/kB/wP4Af8D/AH/
AyQBNgEAAb8B4AH/AcgB8wH8Af8BAAHfAfkB/wGJAeYB/QH/AZUB5wL/AZoB5QL/AQABygHnAf8BAAHL
AecB/wHHAfcB/QH/AQAB3AH1Af8BAAHhAfcB/wEAAdQB8QH/AQABmQHeAf8BAAGNAdYB/wgAAdQBngEA
Bf8C/gH8Af8C/QH7Af8C/QH8Af8C/QH7Af8C/QH5Af8C/AH4Af8B+wH5AfcB/wH7AfkB9QH/AfsB+AH0
Af8B+wH3AfIB/wH7AfUB8gX/AbICAAH/BAABqAKmAf0D4gH/A9IB/wPGAf8DzQH/A7EB/wMsAUQIAAMs
AUQDqAH/A8IB/wO3Af8DwAH/A9IB/wNAAf0HAAEBA0wBkgHgAakBiAH/AesBxwGwAf8B3QGhAQAB/wG8
AaUBlQH/A6wB/wPQAf8D1AH/A+8B/wP5Af8D9gH/A/YB/wP8Af8DJAE2AQABwgHhAf8ByQHzAfwB/wHL
AfMB/QH/AdQB9gH+Af8B1wH2Av8B2AH0Av8B4AH4Av8BqQHjAfUB/wEAAdMB7gH/AccB9wH9Af8BAAHc
AfUB/wEAAeIB9wH/AQAB1gHyAf8BAAGYAd4B/wMhATAEAAHVAaABAAX/Av0B/AH/Av0B+wH/Av0B+gH/
AvwB+QH/AfwB+wH3Af8B+wH5AfUB/wH7AfgB9AH/AfsB9wHzAf8B+wH1AfIB/wH6AfMB7wH/AfgB8gHs
Bf8BtQIAAf8EAAGoAqYB/QPpAf8D1gH/A8kB/wPOAf8DpQH/AywBRAgAAywBRAOsAf8DxAH/A7oB/wPG
Af8D3QH/A0AB/QcAAQEDJAE2AfAB1gHGAf8B3gGtAZAB/wHEAa8BowH/A9UB/wO7Af8DpgH/A6AB/wOQ
Af8DyQH/A/MB/wPyAf8D/AH/AyQBNgEAAcMB4QH/AYgBoAGoAf8DkQH/A44B/wEAAbkB3AH/AQABuAHf
Af8BAAG1Ad4B/wEAAbEB3QH/AQABsAHeAf8BAAHUAe4B/wHEAfYB/QH/AQAB3QH2Af8BAAHKAe0B/wEA
AaMB1wH/AWACWQHsAxsBJgHYAaIBAAX/Av0B+gH/AvwB+gH/AfwB+wH5Af8B+wH6AfYB/wH7AfgB9QH/
AfsB9wH0Af8B+wH2AfEB/wH4AfQB7gH/AfcB8gHrAf8B9wHwAeoB/wH2AewB6AX/AbcBgQEAAf8EAAFc
AloBzQFfAlgB4wFhAlYB7gPYAf8DzQH/A7wB/wFbAlgBxgMsAUQDLAFEAVsCWAHGA8MB/wPCAf8DzQH/
AWECVgHuAV8CWAHjAVwCWgHNBwABAQMkATYD/AH/A/sB/wOsAf8DywH/A9IB/wPJAf8D0gH/A8YB/wOP
Af8D7wH/A+0B/wP8Af8DJAE2BAABWwJZAcMDxgH/A5QB/wMGAQgQAAM3AVoBAAHTAesB/wGyAeMB+QH/
AYsBwAHnAf8BrgHTAfYB/wHEAeAB/AH/A2cB9wHZAaMBAAX/AfwB+wH5Af8B/AH7AfgB/wH7AfkB9wH/
AfsB9wH0Af8B+gH3AfIB/wH5AfUB8AH/AfcB8wHtAf8B9gHvAeoB/wH1AesB5wH/AfMB6gHkAf8B8gHn
Ad4F/wG6AYUBAAH/DAADSAGFA9QB/wPMAf8DyQH/A7oB/wOcAf8DoQH/A8IB/wPGAf8DwQH/A7cB/wNI
AYUPAAEBAyQBNgP8Af8D+wH/A9sB/wOyAf8D1gH/A6AB/wOSAf8DwAH/A4oB/wPqAf8D5gH/A/wB/wMk
ATYEAANUAa4DxAH/A6EB/wMdASkQAAMdASkBAAGZAakB/wEAAb4B5wH/AbQB0gHwAf8B5QHzAv8BrAHS
Ae8B/wFfAlcB6AHbAaQBADX/Ab0BhwEAAf8IAANFAX0DfwH+A9wB/wPUAf8D2QH/A9sB/wPWAf8D1AH/
A9kB/wPSAf8DywH/A8gB/wF6AnkB/gNFAX0LAAEBAyQBNgP8Af8D+QH/A9oB/wO1Af8D5gH/A5oB/wOw
Af8DrwH/A70B/wP8Af8D/AH/A/wB/wMkATYEAANCAXUDugH/A78B/wFeAlgB3QMWAR8DBAEFAwQBBQMW
AR8BZQJeAeUDqAH/AQABpAGzAf8BAAGlAdgB/wGFAbEB2wH/AQABnQHQAf8DOAFeAdwBpwEAAf8B3AGn
AQAB/wHcAacBAAH/AdwBpwEAAf8B3AGnAQAB/wHcAacBAAH/AdwBpwEAAf8B3AGnAQAB/wHcAacBAAH/
AdwBpwEAAf8B3AGnAQAB/wHcAacBAAH/AdwBpwEAAf8B3AGnAQAB/wHAAYsBAAH/CAADRAF7A9wB/wPt
Af8D2wH/AWUCXQH0A38B/gPWAf8D1AH/A38B/gFlAl0B9APLAf8D5wH/A7cB/wNEAXsLAAEBAyQBNgP8
Af8D9wH/A+8B/wOmAf8D4QH/A9IB/wO0Af8D6gH/A/wB/wP2Af8D9AH/AU0CTAGRAxcBIAQAAwkBDAFf
AloB2wPEAf8DvgH/A6EB/wOWAf8DkwH/A5cB/wOuAf8DrgH/AV8CWgHbAwcBCQwAAagBpgGDAf0B6AG5
AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/
AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wGoAY4BQAH9DAABUAJPAZsBqAKm
Af0BZAJcAecDEgEZAWQCXAHnA94B/wPdAf8BZAJcAecDEgEZAWQCXAHnAacCpQH9AVACTwGbEAADJAE2
AagCpgH9A/QB/wP1Af8D1AH/A6UB/wOdAf8DvgH/A+kB/wP8Af8D5wH/AU0CTAGRAxcBIAMBAQIIAAMh
ATABYAJaAd4DvAH/A8oB/wPMAf8DygH/A8IB/wOtAf8BYAJaAd4DIQEwEAADPgFrAWUCXQH0AdwBpwEA
Af8B3AGmAQAB/wHaAaQBAAH/AdgBogEAAf8B1QGgAQAB/wHUAZ4BAAH/AdIBnQEAAf8BzwGaAQAB/wHO
AZkBAAH/AcsBlgEAAf8ByQGUAQAB/wFlAl0B9AM+AWsQAAMdASkDCgEOAwEBAgFcAlUB6gPlAf8D5AH/
AVwCVQHqAwEBAgMKAQ4DHQEpFAADIwEzAV0CVAHwAagCpgH9A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/
A/gB/wFNAkwBkQMXASADAQECEAADCQEMAUcCRgGBAVcCVQG6AVwCWQHMAVwCWQHMAVcCVQG6AUcCRgGB
AwkBDGwAAzsBYwFZAlcBvwFZAlcBvwM7AWMgAAMUARwDIwEzAyQBNgMkATYDJAE2AyQBNgMkATYDJAE2
AyQBNgMkATYDFwEgAwEBAggAAUIBTQE+BwABPgMAASgDAAFAAwABMAMAAQEBAAEBBQABgAEBFgAD/wEA
Av8BgAEBAYcB/wQAAYABAQEDAf8FAAIBAf8HAAH/BwABfwYAAYABPwYAAcABPwYAAeABHwMAAR8CAAHw
AQEDAAEfAgAB+AQAAR8CAAH+AwAB+AEfAgAB/wMAAfgBHwEAAQEB/wEIAgAB+AEfAYABAQH/AQcCAAH4
AR8BgAEDAf8BBwIAAv8BgAEHAf8BhwIAAfwBPwEPAf8BgAEBAv8B4AIHAf8BgAEBAeAB/wHAAQMBAAE/
AYABAQHAAQ8BwAEDAQABHwGAAQEBgAEHAcABAwGAAR8BwAEDAQABAwHAAQMBwAEPAeABBwEAAQEBwAED
AcABAwHwAQ8BAAEBAcABAwHAAQEB/AE/AQABAQHAAQMBwAEBAfwBPwEAAQEBwAEDAcABAQHwAQ8BAAEB
AcABAwHgAQEB4AEHAQABAQHAAQMB+AEBAcABAwEAAQEBwAEDAfwBAAGAAQEBAAEBAcABAwH8AQABgAEB
AYABAwHgAQcB/gEAAYABAQHAAQcD/wHwAYABAQHgAQ8BAAEDAv8B/AE/AcACAAEDAv8B4AEHAcACAAED
AQABAQHAAQMDAAEDAQABAQGAAQEDAAEDAQABAQGAAQEDAAEDAQABAQHAAQMDAAEDAQABAQIAAYACAAED
AQACAQKAAgABAQEAAgECgAQAAQECAAGAAQABhwGAAQABAQHAAQMBgAEAAYcBgAEAAQEBgAEBAYABAAGA
AgABAQGAAQEBgAEAAYABBwEAAQEBwAEDAcABAAHAAQ8BAAEBAeABBwHAAQEB4AEfAv8B/AE/AcABAws=
</value>
</data>
<metadata name="menuSearch.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>338, 17</value>
</metadata>
<metadata name="timerUpdate.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>457, 17</value>
</metadata>
+143
View File
@@ -0,0 +1,143 @@
namespace ProcessHacker
{
partial class ProtectProcessWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.checkProtect = new System.Windows.Forms.CheckBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.listProcessAccess = new System.Windows.Forms.CheckedListBox();
this.listThreadAccess = new System.Windows.Forms.CheckedListBox();
this.buttonCancel = new System.Windows.Forms.Button();
this.buttonOK = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// checkProtect
//
this.checkProtect.AutoSize = true;
this.checkProtect.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.checkProtect.Location = new System.Drawing.Point(12, 12);
this.checkProtect.Name = "checkProtect";
this.checkProtect.Size = new System.Drawing.Size(125, 18);
this.checkProtect.TabIndex = 0;
this.checkProtect.Text = "Protect this process";
this.checkProtect.UseVisualStyleBackColor = true;
this.checkProtect.CheckedChanged += new System.EventHandler(this.checkProtect_CheckedChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 42);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(124, 13);
this.label1.TabIndex = 1;
this.label1.Text = "Allowed process access:";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(12, 155);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(117, 13);
this.label2.TabIndex = 2;
this.label2.Text = "Allowed thread access:";
//
// listProcessAccess
//
this.listProcessAccess.FormattingEnabled = true;
this.listProcessAccess.Location = new System.Drawing.Point(12, 58);
this.listProcessAccess.Name = "listProcessAccess";
this.listProcessAccess.Size = new System.Drawing.Size(474, 94);
this.listProcessAccess.TabIndex = 3;
//
// listThreadAccess
//
this.listThreadAccess.FormattingEnabled = true;
this.listThreadAccess.Location = new System.Drawing.Point(12, 171);
this.listThreadAccess.Name = "listThreadAccess";
this.listThreadAccess.Size = new System.Drawing.Size(474, 94);
this.listThreadAccess.TabIndex = 3;
//
// buttonCancel
//
this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonCancel.Location = new System.Drawing.Point(411, 271);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
this.buttonCancel.TabIndex = 4;
this.buttonCancel.Text = "Cancel";
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
//
// buttonOK
//
this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonOK.Location = new System.Drawing.Point(330, 271);
this.buttonOK.Name = "buttonOK";
this.buttonOK.Size = new System.Drawing.Size(75, 23);
this.buttonOK.TabIndex = 4;
this.buttonOK.Text = "OK";
this.buttonOK.UseVisualStyleBackColor = true;
this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);
//
// ProtectProcessWindow
//
this.AcceptButton = this.buttonOK;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(498, 306);
this.Controls.Add(this.buttonOK);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.listThreadAccess);
this.Controls.Add(this.listProcessAccess);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.checkProtect);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "ProtectProcessWindow";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Protect Process";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.CheckBox checkProtect;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.CheckedListBox listProcessAccess;
private System.Windows.Forms.CheckedListBox listThreadAccess;
private System.Windows.Forms.Button buttonCancel;
private System.Windows.Forms.Button buttonOK;
}
}
@@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ProcessHacker.Native;
using ProcessHacker.Native.Objects;
using ProcessHacker.Native.Security;
namespace ProcessHacker
{
public partial class ProtectProcessWindow : Form
{
private int _pid;
private bool _isProtected;
public ProtectProcessWindow(int pid)
{
InitializeComponent();
_pid = pid;
ProcessAccess processAccess;
ThreadAccess threadAccess;
if (ProtectQuery(_pid, out processAccess, out threadAccess))
checkProtect.Checked = _isProtected = true;
foreach (string value in Enum.GetNames(typeof(ProcessAccess)))
{
if (value == "All")
continue;
listProcessAccess.Items.Add(value,
(processAccess & (ProcessAccess)Enum.Parse(typeof(ProcessAccess), value)) != 0);
}
foreach (string value in Enum.GetNames(typeof(ThreadAccess)))
{
if (value == "All")
continue;
listThreadAccess.Items.Add(value,
(threadAccess & (ThreadAccess)Enum.Parse(typeof(ThreadAccess), value)) != 0);
}
checkProtect_CheckedChanged(null, null);
}
private bool ProtectQuery(int pid, out ProcessAccess processAccess, out ThreadAccess threadAccess)
{
try
{
using (var phandle = new ProcessHandle(pid, Program.MinProcessQueryRights))
KProcessHacker.Instance.ProtectQuery(phandle, out processAccess, out threadAccess);
return true;
}
catch
{
processAccess = 0;
threadAccess = 0;
return false;
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void buttonOK_Click(object sender, EventArgs e)
{
// remove protection
if (_isProtected)
{
try
{
using (var phandle = new ProcessHandle(_pid, Program.MinProcessQueryRights))
KProcessHacker.Instance.ProtectRemove(phandle);
}
catch
{ }
}
// re-add protection (with new masks)
if (checkProtect.Checked)
{
ProcessAccess processAccess = 0;
ThreadAccess threadAccess = 0;
foreach (string value in listProcessAccess.CheckedItems)
processAccess |= (ProcessAccess)Enum.Parse(typeof(ProcessAccess), value);
foreach (string value in listThreadAccess.CheckedItems)
threadAccess |= (ThreadAccess)Enum.Parse(typeof(ThreadAccess), value);
try
{
using (var phandle = new ProcessHandle(_pid, Program.MinProcessQueryRights))
KProcessHacker.Instance.ProtectAdd(phandle, processAccess, threadAccess);
}
catch
{ }
}
this.Close();
}
private void checkProtect_CheckedChanged(object sender, EventArgs e)
{
listProcessAccess.Enabled = checkProtect.Checked;
listThreadAccess.Enabled = checkProtect.Checked;
}
}
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+9
View File
@@ -230,6 +230,9 @@
<DependentUpon>ProcessWindow.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Forms\ProtectProcessWindow.resx">
<DependentUpon>ProtectProcessWindow.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\StructWindow.resx">
<DependentUpon>StructWindow.cs</DependentUpon>
</EmbeddedResource>
@@ -330,6 +333,12 @@
<Compile Include="Components\ProcessStatistics.Designer.cs">
<DependentUpon>ProcessStatistics.cs</DependentUpon>
</Compile>
<Compile Include="Forms\ProtectProcessWindow.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\ProtectProcessWindow.Designer.cs">
<DependentUpon>ProtectProcessWindow.cs</DependentUpon>
</Compile>
<Compile Include="UI\Icons\CommitHistoryIcon.cs" />
<Compile Include="UI\Icons\PhysMemHistoryIcon.cs" />
<Compile Include="UI\Icons\CpuUsageIcon.cs" />
+12
View File
@@ -1452,5 +1452,17 @@ namespace ProcessHacker.Properties {
this["HideProcessHackerNetworkConnections"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool EnableExperimentalFeatures {
get {
return ((bool)(this["EnableExperimentalFeatures"]));
}
set {
this["EnableExperimentalFeatures"] = value;
}
}
}
}
@@ -359,5 +359,8 @@
<Setting Name="HideProcessHackerNetworkConnections" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="EnableExperimentalFeatures" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
</Settings>
</SettingsFile>
+3
View File
@@ -364,6 +364,9 @@
<setting name="HideProcessHackerNetworkConnections" serializeAs="String">
<value>True</value>
</setting>
<setting name="EnableExperimentalFeatures" serializeAs="String">
<value>False</value>
</setting>
</ProcessHacker.Properties.Settings>
</userSettings>
</configuration>