using System.Threading.Tasks;
using WhiteMagic.Assembly;
using WhiteMagic.Execution;
namespace WhiteMagic;
///
/// An exported function resolved in the target process, obtained via
/// magic["module"]["function"]. Executes through one of the session's execution
/// strategies.
///
///
/// The default path uses the always-available
/// (CreateRemoteThread), which is safe for
/// thread-agnostic exports. For a call that touches single-threaded target state, obtain
/// the and route it through a , or use
/// when running in-process.
///
public sealed class RemoteFunction
{
private readonly Magic _magic;
/// The export name this function was resolved from.
public string Name { get; }
/// The absolute address of the function in the target process.
public IntPtr Address { get; }
internal RemoteFunction(Magic magic, string name, IntPtr address)
{
_magic = magic;
Name = name;
Address = address;
}
///
/// Calls the function via a remote thread and returns its result cast to
/// .
///
/// The calling convention (ignored on x64 targets).
/// Arguments to pass; primitives, pointers, enums, strings and
/// structs are supported.
public T Execute(CallConvention convention, params object?[] args)
{
return _magic.RemoteThread.Execute(Address, convention, args);
}
/// Asynchronous variant of .
public Task ExecuteAsync(CallConvention convention, params object?[] args)
{
return _magic.RemoteThread.ExecuteAsync(Address, convention, args);
}
///
/// Creates a managed delegate bound to this function for the in-process scenario.
/// Only valid when the session was opened in-process.
///
public TDelegate CreateDelegate() where TDelegate : Delegate
{
return new InProcessInvoker(_magic.Memory).CreateFunction(Address);
}
}