M src/Inject/NosSmooth.Inject/nossmooth.cpp => src/Inject/NosSmooth.Inject/nossmooth.cpp +6 -7
@@ 105,17 105,17 @@ int LoadAndCallMethod(LoadParams* params)
{
if (!load_hostfxr())
{
- return 2;
+ return 0;
}
load_assembly_and_get_function_pointer_fn load_assembly_and_get_function_pointer = nullptr;
load_assembly_and_get_function_pointer = get_dotnet_load_assembly(params->runtimeConfigPath);
if (load_assembly_and_get_function_pointer == nullptr)
{
- return 3;
+ return 1;
}
- typedef void (CORECLR_DELEGATE_CALLTYPE* main_entry_point_fn)();
+ typedef int (CORECLR_DELEGATE_CALLTYPE* main_entry_point_fn)(char* data);
main_entry_point_fn main = nullptr;
int rc = load_assembly_and_get_function_pointer(
params->libraryPath,
@@ 123,12 123,11 @@ int LoadAndCallMethod(LoadParams* params)
params->methodName,
UNMANAGEDCALLERSONLY_METHOD,
nullptr,
- (void**)&main);
+ reinterpret_cast<void**>(&main));
if (rc != 0 || main == nullptr)
{
- return 4;
+ return 2;
}
- main();
- return 1;
+ return main(params->userData) + 3;
}=
\ No newline at end of file
M src/Inject/NosSmooth.Inject/nossmooth.h => src/Inject/NosSmooth.Inject/nossmooth.h +1 -0
@@ 8,6 8,7 @@ struct LoadParams
wchar_t *runtimeConfigPath;
wchar_t *typePath;
wchar_t *methodName;
+ char *userData;
};
#pragma pack(pop)
#define DllExport extern "C" __declspec( dllexport )
M src/Inject/NosSmooth.Injector.CLI/Commands/InjectCommand.cs => src/Inject/NosSmooth.Injector.CLI/Commands/InjectCommand.cs +19 -5
@@ 37,7 37,7 @@ namespace NosSmooth.Injector.CLI.Commands
/// <param name="methodName">The name of the UnmanagedCallersOnly method. Default is Main.</param>
/// <returns>A result that may or may not have succeeded.</returns>
[Command("inject")]
- public Task<Result> Inject
+ public async Task<Result> Inject
(
[Description("The id of the process to inject into.")]
string process,
@@ 51,18 51,32 @@ namespace NosSmooth.Injector.CLI.Commands
{
if (!int.TryParse(process, out var processId))
{
- var foundProcess = Process.GetProcesses().FirstOrDefault(x => x.ProcessName.Contains(process, StringComparison.OrdinalIgnoreCase));
+ var foundProcess = Process.GetProcesses().FirstOrDefault
+ (x => x.ProcessName.Contains(process, StringComparison.OrdinalIgnoreCase));
if (foundProcess is null)
{
- return Task.FromResult(Result.FromError(new NotFoundError("Could not find the given process.")));
+ return Result.FromError(new NotFoundError("Could not find the given process."));
}
processId = foundProcess.Id;
}
var dllName = Path.GetFileNameWithoutExtension(dllPath);
- return Task.FromResult
- (_injector.Inject(processId, dllPath, typeName ?? $"{dllName}.DllMain, {dllName}", methodName ?? "Main"));
+ var result = _injector.Inject
+ (
+ processId,
+ dllPath,
+ typeName ?? $"{dllName}.DllMain, {dllName}",
+ methodName ?? "Main",
+ new byte[] { 1, 2, 3, 4, 5 }
+ );
+ if (!result.IsSuccess)
+ {
+ return Result.FromError(result);
+ }
+
+ Console.WriteLine($"Got {result.Entity} from the managed injected dll.");
+ return Result.FromSuccess();
}
}
}=
\ No newline at end of file
M src/Inject/NosSmooth.Injector/InjectionResult.cs => src/Inject/NosSmooth.Injector/InjectionResult.cs +3 -8
@@ 12,14 12,9 @@ namespace NosSmooth.Injector;
public enum InjectionResult
{
/// <summary>
- /// Successful result.
- /// </summary>
- Ok = 1,
-
- /// <summary>
/// Hostfxr.dll was not found, is .NET installed? It should be as this is a .NET application injecting the dll...
/// </summary>
- HostfxrNotFound = 2,
+ HostfxrNotFound = 0,
/// <summary>
/// A runtimeconfig.json of the assembly to be injected was not found.
@@ 28,7 23,7 @@ public enum InjectionResult
/// Be sure to include <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
/// in a library that will be injected.
/// </remarks>
- RuntimeConfigNotFound = 3,
+ RuntimeConfigNotFound = 1,
/// <summary>
/// The specified class or type was not found.
@@ 37,5 32,5 @@ public enum InjectionResult
/// Be sure to put it in this format: "namespace.type.method, assembly",
/// see samples.
/// </remarks>
- ClassOrMethodNotFound = 4
+ ClassOrMethodNotFound = 2
}=
\ No newline at end of file
M src/Inject/NosSmooth.Injector/LoadParams.cs => src/Inject/NosSmooth.Injector/LoadParams.cs +5 -0
@@ 40,5 40,10 @@ namespace NosSmooth.Injector
/// The name of the method to execute.
/// </summary>
public int MethodName;
+
+ /// <summary>
+ /// The user data to pass.
+ /// </summary>
+ public int UserData;
}
}
M src/Inject/NosSmooth.Injector/ManagedMemoryAllocation.cs => src/Inject/NosSmooth.Injector/ManagedMemoryAllocation.cs +5 -2
@@ 41,7 41,10 @@ internal class ManagedMemoryAllocation : IDisposable
/// <inheritdoc />
public void Dispose()
{
- _memory.Free(Pointer);
- Pointer = nuint.Zero;
+ if (Allocated)
+ {
+ _memory.Free(Pointer);
+ Pointer = nuint.Zero;
+ }
}
}=
\ No newline at end of file
M src/Inject/NosSmooth.Injector/NosInjector.cs => src/Inject/NosSmooth.Injector/NosInjector.cs +32 -9
@@ 47,17 47,19 @@ public class NosInjector
/// <param name="dllPath">The absolute path to the dll to inject.</param>
/// <param name="classPath">The full path to the class. Such as "MyLibrary.DllMain, MyLibrary".</param>
/// <param name="methodName">The name of the method to execute. The method should return void and have no parameters.</param>
+ /// <param name="data">The data to pass to the process. The array will be allocated inside the target process.</param>
/// <returns>A result that may or may not have succeeded.</returns>
- public Result Inject
+ public Result<int> Inject
(
int processId,
string dllPath,
string classPath,
- string methodName = "Main"
+ string methodName = "Main",
+ byte[]? data = default
)
{
using var process = Process.GetProcessById(processId);
- return Inject(process, dllPath, classPath, methodName);
+ return Inject(process, dllPath, classPath, methodName, data);
}
/// <summary>
@@ 70,13 72,15 @@ public class NosInjector
/// <param name="dllPath">The absolute path to the dll to inject.</param>
/// <param name="classPath">The full path to the class. Such as "MyLibrary.DllMain, MyLibrary".</param>
/// <param name="methodName">The name of the method to execute. The method should return void and have no parameters.</param>
+ /// <param name="data">The data to pass to the process. The array will be allocated inside the target process.</param>
/// <returns>A result that may or may not have succeeded.</returns>
- public Result Inject
+ public Result<int> Inject
(
Process process,
string dllPath,
string classPath,
- string methodName = "Main"
+ string methodName = "Main",
+ byte[]? data = default
)
{
try
@@ 100,7 104,7 @@ public class NosInjector
if (!netHostInjectionResult.IsSuccess)
{
- return netHostInjectionResult;
+ return Result<int>.FromError(netHostInjectionResult);
}
var directoryName = Path.GetDirectoryName(dllPath);
@@ 121,6 125,7 @@ public class NosInjector
using var classPathMemory = AllocateString(memory, classPath);
using var methodNameMemory = AllocateString(memory, methodName);
using var runtimePathMemory = AllocateString(memory, runtimePath);
+ using var userDataMemory = Allocate(memory, data ?? Array.Empty<byte>());
if (!dllPathMemory.Allocated || !classPathMemory.Allocated || !methodNameMemory.Allocated
|| !runtimePathMemory.Allocated)
@@ 133,7 138,8 @@ public class NosInjector
LibraryPath = (int)dllPathMemory.Pointer,
MethodName = (int)methodNameMemory.Pointer,
RuntimeConfigPath = (int)runtimePathMemory.Pointer,
- TypePath = (int)classPathMemory.Pointer
+ TypePath = (int)classPathMemory.Pointer,
+ UserData = (int)userDataMemory.Pointer
};
var nosSmoothInjectPath = Path.GetFullPath(_options.NosSmoothInjectPath);
@@ 153,7 159,7 @@ public class NosInjector
injector.Eject(nosSmoothInjectPath);
- if (functionResult != 1)
+ if (functionResult < 3)
{
return new InjectionFailedError
(
@@ 163,7 169,7 @@ public class NosInjector
);
}
- return Result.FromSuccess();
+ return functionResult - 3;
}
catch (UnauthorizedAccessException)
{
@@ 216,4 222,21 @@ public class NosInjector
memory.SafeWriteRaw(allocated, bytes);
return new ManagedMemoryAllocation(memory, allocated);
}
+
+ private ManagedMemoryAllocation Allocate(IMemory memory, byte[] data)
+ {
+ if (data.Length == 0)
+ {
+ return new ManagedMemoryAllocation(memory, nuint.Zero);
+ }
+
+ var allocated = memory.Allocate(data.Length);
+ if (allocated == nuint.Zero)
+ {
+ return new ManagedMemoryAllocation(memory, allocated);
+ }
+
+ memory.SafeWriteRaw(allocated, data);
+ return new ManagedMemoryAllocation(memory, allocated);
+ }
}=
\ No newline at end of file
M src/Inject/NosSmooth.Injector/NosSmooth.Inject.dll => src/Inject/NosSmooth.Injector/NosSmooth.Inject.dll +0 -0