public static Boolean ServiceSetHandleStatus(CProcess Process, IntPtr hObject, bool Protect, bool Inherit) { bool Is64 = false, Status = true; byte[] W64Thread = { 0xC, 0xC7, 0xA8, 0x6C, 0x4B, 0xF2, 0x5, 0x4C, 0x8, 0xC9, 0x0, 0x60, 0x74, 0x5, 0xFD, 0x46, 0x44, 0x44, 0x44, 0xCC, 0x0, 0x60, 0x75, 0x4B, 0xF2, 0x5, 0x48, 0x8, 0xCF, 0x95, 0xC, 0xCF, 0x4D, 0xCC, 0x0, 0x60, 0x74, 0x5, 0xC9, 0x15, 0x46, 0x5, 0xBB, 0x16, 0x54, 0x77, 0x8D, 0xC1, 0x84, 0x4B, 0xD0, 0x85, 0xCF, 0x85, 0xC, 0xC7, 0x80, 0x6C, 0x87 }; byte[] W32Thread = { 0x11, 0xCF, 0xA8, 0xCF, 0x9, 0x4C, 0x2E, 0x46, 0x4B, 0xF2, 0x5, 0x40, 0xCC, 0x1, 0x4D, 0x4B, 0xF2, 0x5, 0x4C, 0xCC, 0x1, 0x4C, 0xC9, 0x1, 0x4C, 0x14, 0xCF, 0x5, 0x48, 0x2E, 0x40, 0xBB, 0x75, 0xBB, 0x94, 0xB3, 0x9C, 0x5F, 0x84, 0x4, 0x19, 0x86, 0x40, 0x44 }; HANDLE_IN Args; IntPtr hThread = IntPtr.Zero, lpArgs = IntPtr.Zero, lpThread = IntPtr.Zero, WThread = IntPtr.Zero, WArgs = IntPtr.Zero; if (hObject == IntPtr.Zero || Process.Is64(ref Is64) != 1) { Status = false; goto EXIT; } if (IntPtr.Size == 8) { if (!Is64) { Status = false; goto EXIT; } } else { if (Is64) { Status = false; goto EXIT; } } Args = new HANDLE_IN(); Args.hObject = hObject; Args.IStatus = Inherit; Args.PStatus = Protect; Args.Function = Kernel32.GetProcAddress(Kernel32.GetModuleHandleA("ntdll.dll"), "NtSetInformationObject"); if (Args.Function == IntPtr.Zero) { Status = false; goto EXIT; } if ((lpThread = Kernel32.VirtualAllocEx(Process.GetHandle(), IntPtr.Zero, Is64 ? W64Thread.Length : W32Thread.Length, 0x1000, 0x40)) == IntPtr.Zero || (lpArgs = Kernel32.VirtualAllocEx(Process.GetHandle(), IntPtr.Zero, Marshal.SizeOf(typeof(HANDLE_IN)), 0x1000, 0x40)) == IntPtr.Zero) { Status = false; goto EXIT; } for (int i = 0; i < (Is64 ? W64Thread.Length : W32Thread.Length); i++) { if (Is64) { W64Thread[i] ^= 0x44; } else { W32Thread[i] ^= 0x44; } } WArgs = Marshal.AllocHGlobal(Marshal.SizeOf(WArgs)); WThread = Marshal.AllocHGlobal(Is64 ? W64Thread.Length : W32Thread.Length); Marshal.Copy(Is64 ? W64Thread : W32Thread, 0, WThread, Is64 ? W64Thread.Length : W32Thread.Length); Marshal.StructureToPtr(Args, WArgs, true); if (!Kernel32.WriteProcessMemory(Process.GetHandle(), lpThread, WThread, Is64 ? W64Thread.Length : W32Thread.Length, IntPtr.Zero) || !Kernel32.WriteProcessMemory(Process.GetHandle(), lpArgs, WArgs, Marshal.SizeOf(Args), IntPtr.Zero)) { for (int i = 0; i < (Is64 ? W64Thread.Length : W32Thread.Length); i++) { if (Is64) { W64Thread[i] ^= 0x44; } else { W32Thread[i] ^= 0x44; } } Status = false; goto EXIT; } for (int i = 0; i < (Is64 ? W64Thread.Length : W32Thread.Length); i++) { if (Is64) { W64Thread[i] ^= 0x44; } else { W32Thread[i] ^= 0x44; } } if (ntdll.RtlCreateUserThread(Process.GetHandle(), IntPtr.Zero, false, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, lpThread, lpArgs, ref hThread, IntPtr.Zero) != 0) { Status = false; goto EXIT; } Kernel32.WaitForSingleObject(hThread, (0xFFFFFFFF)); EXIT: if ((hThread) != IntPtr.Zero) { Kernel32.CloseHandle(hThread); } if ((WArgs) != IntPtr.Zero) { Marshal.FreeHGlobal(WArgs); } if ((WThread) != IntPtr.Zero) { Marshal.FreeHGlobal(WThread); } if (lpThread != null) { Kernel32.VirtualFreeEx(Process.GetHandle(), lpThread, Is64 ? W64Thread.Length : W32Thread.Length, 0x4000); } if (lpArgs != null) { Kernel32.VirtualFreeEx(Process.GetHandle(), lpArgs, Marshal.SizeOf(typeof(HANDLE_IN)), 0x4000); } return(Status); }
/// <summary> /// This function executes a shellcode to change the handle characteristics /// </summary> public static Boolean ServiceSetHandleStatus(CProcess Process, IntPtr hObject, bool Protect, bool Inherit) { bool Is64 = false, Status = false; byte[] W64Thread = { 0x48, 0x83, 0xEC, 0x28, 0xF, 0xB6, 0x41, 0x8, 0x4C, 0x8D, 0x44, 0x24, 0x30, 0x41, 0xB9, 0x2, 0x0, 0x0, 0x0, 0x88, 0x44, 0x24, 0x31, 0xF, 0xB6, 0x41, 0xC, 0x4C, 0x8B, 0xD1, 0x48, 0x8B, 0x9, 0x88, 0x44, 0x24, 0x30, 0x41, 0x8D, 0x51, 0x2, 0x41, 0xFF, 0x52, 0x10, 0x33, 0xC9, 0x85, 0xC0, 0xF, 0x94, 0xC1, 0x8B, 0xC1, 0x48, 0x83, 0xC4, 0x28, 0xC3 }; byte[] W32Thread = { 0x55, 0x8B, 0xEC, 0x8B, 0x4D, 0x8, 0x6A, 0x2, 0xF, 0xB6, 0x41, 0x4, 0x88, 0x45, 0x9, 0xF, 0xB6, 0x41, 0x8, 0x88, 0x45, 0x8, 0x8D, 0x45, 0x8, 0x50, 0x8B, 0x41, 0xC, 0x6A, 0x4, 0xFF, 0x31, 0xFF, 0xD0, 0xF7, 0xD8, 0x1B, 0xC0, 0x40, 0x5D, 0xC2, 0x4, 0x0 }; HANDLE_IN Args; IntPtr hThread = IntPtr.Zero, lpArgs = IntPtr.Zero, lpThread = IntPtr.Zero, WThread = IntPtr.Zero, WArgs = IntPtr.Zero; if (hObject == IntPtr.Zero || Process.Is64(ref Is64) != 1) { goto EXIT; } if ((IntPtr.Size == 8) ? !Is64 : Is64) { goto EXIT; } if (_NtSetInformationObject == IntPtr.Zero) { _NtSetInformationObject = Kernel32.GetProcAddress(Kernel32.GetModuleHandleA("ntdll.dll"), "NtSetInformationObject"); if (_NtSetInformationObject == IntPtr.Zero) { goto EXIT; } } Args = new HANDLE_IN(hObject, Protect, Inherit, _NtSetInformationObject); if (Args.Function == IntPtr.Zero) { goto EXIT; } if ((lpThread = Kernel32.VirtualAllocEx(Process.GetHandle(), IntPtr.Zero, Is64 ? W64Thread.Length : W32Thread.Length, 0x1000, 0x40)) == IntPtr.Zero || (lpArgs = Kernel32.VirtualAllocEx(Process.GetHandle(), IntPtr.Zero, Marshal.SizeOf(typeof(HANDLE_IN)), 0x1000, 0x40)) == IntPtr.Zero) { goto EXIT; } WArgs = Marshal.AllocHGlobal(Marshal.SizeOf(WArgs)); WThread = Marshal.AllocHGlobal(Is64 ? W64Thread.Length : W32Thread.Length); Marshal.Copy(Is64 ? W64Thread : W32Thread, 0, WThread, Is64 ? W64Thread.Length : W32Thread.Length); Marshal.StructureToPtr(Args, WArgs, true); if (!Kernel32.WriteProcessMemory(Process.GetHandle(), lpThread, WThread, Is64 ? W64Thread.Length : W32Thread.Length, IntPtr.Zero) || !Kernel32.WriteProcessMemory(Process.GetHandle(), lpArgs, WArgs, Marshal.SizeOf(Args), IntPtr.Zero)) { goto EXIT; } if (ntdll.RtlCreateUserThread(Process.GetHandle(), IntPtr.Zero, false, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, lpThread, lpArgs, ref hThread, IntPtr.Zero) != 0) { goto EXIT; } Kernel32.WaitForSingleObject(hThread, (0xFFFFFFFF)); Status = true; EXIT: if ((hThread) != IntPtr.Zero) { Kernel32.CloseHandle(hThread); } if (lpThread != null) { Kernel32.VirtualFreeEx(Process.GetHandle(), lpThread, Is64 ? W64Thread.Length : W32Thread.Length, 0x4000); } if (lpArgs != null) { Kernel32.VirtualFreeEx(Process.GetHandle(), lpArgs, Marshal.SizeOf(typeof(HANDLE_IN)), 0x4000); } return(Status); }