/// <summary> /// Executes the assembly code located in the remote process at the specified address. /// </summary> /// <param name="address">The address where the assembly code is located.</param> /// <param name="callingConvention">The calling convention used to execute the assembly code with the parameters.</param> /// <param name="parameters">An array of parameters used to execute the assembly code.</param> /// <returns>The return value is the exit code of the thread created to execute the assembly code.</returns> public T Execute <T>(IntPtr address, CallingConventions callingConvention, params dynamic[] parameters) { // Marshal the parameters var marshalledParameters = parameters.Select(p => AMarshalValue.Marshal(Process, p)).Cast <IAMarshalledValue>().ToArray(); // Start a transaction AAssemblyTransaction t; using (t = BeginTransaction()) { // Get the object dedicated to create mnemonics for the given calling convention var calling = ACallingConventionSelector.Get(callingConvention); // Push the parameters t.AddLine(calling.FormatParameters(marshalledParameters.Select(p => p.Reference).ToArray())); // Call the function t.AddLine(calling.FormatCalling(address)); // Clean the parameters if (calling.Cleanup == CleanupTypes.Caller) { t.AddLine(calling.FormatCleaning(marshalledParameters.Length)); } // Add the return mnemonic t.AddLine("retn"); } // Clean the marshalled parameters foreach (var parameter in marshalledParameters) { parameter.Dispose(); } // Return the exit code return(t.GetExitCode <T>()); }
/// <summary> /// Creates a thread that runs in the remote process. /// </summary> /// <param name="address"> /// A pointer to the application-defined function to be executed by the thread and represents /// the starting address of the thread in the remote process. /// </param> /// <param name="parameter">A variable to be passed to the thread function.</param> /// <param name="isStarted">Sets if the thread must be started just after being created.</param> /// <returns>A new instance of the <see cref="ARemoteThread" /> class.</returns> public IARemoteThread Create(IntPtr address, dynamic parameter, bool isStarted = true) { // Marshal the parameter var marshalledParameter = AMarshalValue.Marshal(Process, parameter); //Create the thread var ret = AThreadHelper.NtQueryInformationThread( AThreadHelper.CreateRemoteThread(Process.Handle, address, marshalledParameter.Reference, ThreadCreationFlags.Suspended)); // Find the managed object corresponding to this thread var result = new ARemoteThread(Process, Process.ThreadFactory.NativeThreads.First(t => t.Id == ret.ThreadId), marshalledParameter); if (isStarted) { result.Resume(); } return(result); }