internal T CallRoutine <T>(IntPtr routineAddress, params dynamic[] arguments) where T : unmanaged { var returnAddress = Memory.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 = ShellcodeAssembler.AssembleCall32(callDescriptor); } else { var callDescriptor = new CallDescriptor <long>(routineAddress, Array.ConvertAll(arguments, argument => (long)argument), returnAddress); shellcodeBytes = ShellcodeAssembler.AssembleCall64(callDescriptor); } // Execute the shellcode ExecuteShellcode(shellcodeBytes); return(Memory.ReadStructure <T>(returnAddress)); } finally { Memory.FreeBuffer(returnAddress); } }
internal void CallRoutine(IntPtr routineAddress, params dynamic[] arguments) { // 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), IntPtr.Zero); shellcodeBytes = ShellcodeAssembler.AssembleCall32(callDescriptor); } else { var callDescriptor = new CallDescriptor <long>(routineAddress, Array.ConvertAll(arguments, argument => (long)argument), IntPtr.Zero); shellcodeBytes = ShellcodeAssembler.AssembleCall64(callDescriptor); } // Execute the shellcode ExecuteShellcode(shellcodeBytes); }