internal T CallRoutine <T>(IntPtr routineAddress, params dynamic[] arguments) where T : unmanaged { var returnAddress = Process.AllocateMemory(Unsafe.SizeOf <T>()); // Create the shellcode used to call the routine Span <byte> shellcodeBytes; if (Process.GetArchitecture() == Architecture.X86) { var callDescriptor = new CallDescriptor32(routineAddress, Array.ConvertAll(arguments, argument => (int)argument), returnAddress); shellcodeBytes = Assembler.AssembleCall32(callDescriptor); } else { var routineDescriptor = new CallDescriptor64(routineAddress, Array.ConvertAll(arguments, argument => (long)argument), returnAddress); shellcodeBytes = Assembler.AssembleCall64(routineDescriptor); } try { // Write the shellcode bytes into the process var shellcodeBytesAddress = Process.AllocateMemory(shellcodeBytes.Length, true); try { Process.WriteArray(shellcodeBytesAddress, shellcodeBytes); // Create a thread to execute the shellcode Process.CreateThread(shellcodeBytesAddress); } finally { Process.FreeMemory(shellcodeBytesAddress); } return(Process.ReadStructure <T>(returnAddress)); } finally { Process.FreeMemory(returnAddress); } }
internal T CallRoutine <T>(IntPtr routineAddress, params dynamic[] arguments) where T : unmanaged { var returnAddress = Process.AllocateBuffer(Unsafe.SizeOf <T>(), ProtectionType.ReadWrite); try { // Assemble the shellcode used to call the routine Span <byte> shellcodeBytes; if (Process.GetArchitecture() == Architecture.X86) { var callDescriptor = new CallDescriptor <int>(routineAddress, Array.ConvertAll(arguments, argument => (int)argument), returnAddress); shellcodeBytes = Assembler.AssembleCall32(callDescriptor); } else { var callDescriptor = new CallDescriptor <long>(routineAddress, Array.ConvertAll(arguments, argument => (long)argument), returnAddress); shellcodeBytes = Assembler.AssembleCall64(callDescriptor); } // Write the shellcode into the process var shellcodeAddress = Process.AllocateBuffer(shellcodeBytes.Length, ProtectionType.ExecuteRead); try { Process.WriteSpan(shellcodeAddress, shellcodeBytes); // Create a thread to execute the shellcode Process.CreateThread(shellcodeAddress); } finally { Executor.IgnoreExceptions(() => Process.FreeBuffer(shellcodeAddress)); } return(Process.ReadStruct <T>(returnAddress)); } finally { Executor.IgnoreExceptions(() => Process.FreeBuffer(returnAddress)); } }
internal T CallRoutine <T>(IntPtr routineAddress, params dynamic[] arguments) where T : unmanaged { var returnSize = typeof(T) == typeof(IntPtr) ? Architecture == Architecture.X86 ? sizeof(int) : sizeof(long) : Unsafe.SizeOf <T>(); var returnAddress = Process.AllocateBuffer(returnSize, ProtectionType.ReadWrite); try { // Assemble the shellcode used to call the routine Span <byte> shellcodeBytes; if (Architecture == Architecture.X86) { var descriptor = new CallDescriptor <int>(routineAddress, Array.ConvertAll(arguments, argument => (int)argument), returnAddress); shellcodeBytes = Assembler.AssembleCall32(descriptor); } else { var descriptor = new CallDescriptor <long>(routineAddress, Array.ConvertAll(arguments, argument => (long)argument), returnAddress); shellcodeBytes = Assembler.AssembleCall64(descriptor); } ExecuteShellcode(shellcodeBytes); // Read the return value if (typeof(T) != typeof(IntPtr)) { return(Process.ReadStruct <T>(returnAddress)); } var pointer = Architecture == Architecture.X86 ? UnsafeHelpers.WrapPointer(Process.ReadStruct <int>(returnAddress)) : UnsafeHelpers.WrapPointer(Process.ReadStruct <long>(returnAddress)); return(Unsafe.As <IntPtr, T>(ref pointer)); } finally { Executor.IgnoreExceptions(() => Process.FreeBuffer(returnAddress)); } }
internal void CallRoutine(IntPtr routineAddress, params dynamic[] arguments) { // Assemble the shellcode used to call the routine Span <byte> shellcodeBytes; if (Architecture == Architecture.X86) { var descriptor = new CallDescriptor <int>(routineAddress, Array.ConvertAll(arguments, argument => (int)argument), IntPtr.Zero); shellcodeBytes = Assembler.AssembleCall32(descriptor); } else { var descriptor = new CallDescriptor <long>(routineAddress, Array.ConvertAll(arguments, argument => (long)argument), IntPtr.Zero); shellcodeBytes = Assembler.AssembleCall64(descriptor); } ExecuteShellcode(shellcodeBytes); }
internal void CallRoutine(IntPtr routineAddress, params dynamic[] arguments) { // Create the shellcode used to call the routine Span <byte> shellcodeBytes; if (Process.GetArchitecture() == Architecture.X86) { var callDescriptor = new CallDescriptor32(routineAddress, Array.ConvertAll(arguments, argument => (int)argument), IntPtr.Zero); shellcodeBytes = Assembler.AssembleCall32(callDescriptor); } else { var routineDescriptor = new CallDescriptor64(routineAddress, Array.ConvertAll(arguments, argument => (long)argument), IntPtr.Zero); shellcodeBytes = Assembler.AssembleCall64(routineDescriptor); } // Write the shellcode into the process var shellcodeBytesAddress = Process.AllocateMemory(shellcodeBytes.Length, true); try { Process.WriteArray(shellcodeBytesAddress, shellcodeBytes); // Create a thread to execute the shellcode Process.CreateThread(shellcodeBytesAddress); } finally { Process.FreeMemory(shellcodeBytesAddress); } }