Skip to content

Commit

Permalink
Release 2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
enkomio committed May 30, 2021
1 parent bee3ba3 commit 95b737a
Show file tree
Hide file tree
Showing 17 changed files with 266 additions and 77 deletions.
3 changes: 3 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### 2.0.0 - 30/05/2021
* added feature to specify an argument to be passed to the inject method

### 1.0.1 - 21/01/2019
* improved code to inspect assembly for depedencies
* some minor bug fixing
Expand Down
43 changes: 31 additions & 12 deletions Src/ES.ManagedInjector/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
using System.Collections.Generic;
using System.IO.Pipes;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace ES.ManagedInjector
{
internal class Client
{
private readonly NamedPipeClientStream _client = new NamedPipeClientStream(".", Constants.NamedPipeCode.ToString("X"), PipeDirection.InOut);
private readonly PipeChanell _pipeChanell = null;
private readonly PipeChanel _pipeChanel = null;
private readonly List<Byte[]> _dependencies = null;
private readonly Dictionary<String, Byte[]> _files = null;
private readonly Byte[] _assemblyContent;
Expand All @@ -24,10 +25,10 @@ public Client(Byte[] assemblyContent, String methodName, List<Byte[]> dependenci
_methodName = methodName;
_dependencies = dependencies;
_files = files;
_pipeChanell = new PipeChanell(_client);
_pipeChanel = new PipeChanel(_client);
}

public void ActivateAssembly()
public void ActivateAssembly(Object context)
{
try
{
Expand All @@ -36,12 +37,13 @@ public void ActivateAssembly()
{
// send assembly and run it
var invocationResult =
_pipeChanell.SendMessage(Constants.Ping) &&
_pipeChanel.SendMessage(Constants.Ping) &&
SendDependencies() &&
SendFiles() &&
SendToken() &&
SendAssembly() &&
_pipeChanell.SendMessage(Constants.Run);
SendAssembly() &&
SendContext(context) &&
_pipeChanel.SendMessage(Constants.Run);

_client.Dispose();
SetLastError();
Expand Down Expand Up @@ -71,8 +73,8 @@ private void SetLastError()
{
if (_lastError == InjectionResult.Success)
{
_lastError = _pipeChanell.GetLastError();
_lastErrorMessage = _pipeChanell.GetLastErrorMessage();
_lastError = _pipeChanel.GetLastError();
_lastErrorMessage = _pipeChanel.GetLastErrorMessage();
}
}

Expand Down Expand Up @@ -142,7 +144,7 @@ private Boolean SendFiles()
foreach (var kv in _files)
{
var value = String.Format("{0}|{1}{2}", kv.Key.Length, kv.Key, Convert.ToBase64String(kv.Value));
result = result && _pipeChanell.SendMessage(Constants.File, value);
result = result && _pipeChanel.SendMessage(Constants.File, value);
}
return result;
}
Expand All @@ -153,15 +155,32 @@ private Boolean SendDependencies()
foreach(var dependency in _dependencies)
{
var stringBuffer = Convert.ToBase64String(dependency);
result = result && _pipeChanell.SendMessage(Constants.Dependency, stringBuffer);
result = result && _pipeChanel.SendMessage(Constants.Dependency, stringBuffer);
}
return result;
}

private Boolean SendContext(Object context)
{
var result = false;
var formatter = new BinaryFormatter();
try
{
using (var memStream = new MemoryStream())
{
formatter.Serialize(memStream, context);
var contextString = Convert.ToBase64String(memStream.ToArray());
result = _pipeChanel.SendMessage(Constants.Context, contextString);
}
}
catch { }
return result;
}

private Boolean SendAssembly()
{
var stringBuffer = Convert.ToBase64String(_assemblyContent);
return _pipeChanell.SendMessage(Constants.Assembly, stringBuffer);
return _pipeChanel.SendMessage(Constants.Assembly, stringBuffer);
}

private (String, Int32) GetModuleNameAndMethodToken()
Expand Down Expand Up @@ -203,7 +222,7 @@ private Boolean SendToken()
}
else
{
result = _pipeChanell.SendMessage(Constants.Token, methodToken.ToString());
result = _pipeChanel.SendMessage(Constants.Token, methodToken.ToString());
}

return result;
Expand Down
4 changes: 2 additions & 2 deletions Src/ES.ManagedInjector/ES.ManagedInjector.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
<Compile Include="Entities.cs" />
<Compile Include="Injector.cs" />
<Compile Include="Native.cs" />
<Compile Include="PipeChanell.cs" />
<Compile Include="PipeChanel.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Remote.cs" />
<Compile Include="Server.cs" />
Expand All @@ -84,7 +84,7 @@
<MSBuild BuildInParallel="true" UseResultsCache="true" Projects="$(MSBuildProjectFullPath)" Properties="DllExportRPkgDyn=true" Targets="Build" />
</Target>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework'">
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v1.0' Or $(TargetFrameworkVersion) == 'v1.1' Or $(TargetFrameworkVersion) == 'v2.0' Or $(TargetFrameworkVersion) == 'v3.0' Or $(TargetFrameworkVersion) == 'v3.5' Or $(TargetFrameworkVersion) == 'v4.0' Or $(TargetFrameworkVersion) == 'v4.0.3' Or $(TargetFrameworkVersion) == 'v4.5' Or $(TargetFrameworkVersion) == 'v4.5.1' Or $(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1' Or $(TargetFrameworkVersion) == 'v4.6.2' Or $(TargetFrameworkVersion) == 'v4.6.3' Or $(TargetFrameworkVersion) == 'v4.7' Or $(TargetFrameworkVersion) == 'v4.7.1' Or $(TargetFrameworkVersion) == 'v4.7.2' Or $(TargetFrameworkVersion) == 'v4.8')">
<ItemGroup>
<Reference Include="RGiesecke.DllExport.Metadata">
<HintPath>..\packages\UnmanagedExports\lib\net\RGiesecke.DllExport.Metadata.dll</HintPath>
Expand Down
4 changes: 3 additions & 1 deletion Src/ES.ManagedInjector/Entities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ internal static class Constants
public static readonly String Assembly = "ASSEMBLY";
public static readonly String Dependency = "DEPENDENCY";
public static readonly String File = "FILE";
public static readonly String Context = "CONTEXTR";
public static readonly String Run = "RUN";
}

Expand All @@ -81,6 +82,7 @@ public enum InjectionResult : Int32
UnableToConnectToNamedPipe = 7,
ErrorDuringInvocation = 8,
InvalidAssemblyDependencyBuffer = 9,
InvalidFileBuffer = 10
InvalidFileBuffer = 10,
ErrorInContextDeSerialization = 11
}
}
12 changes: 7 additions & 5 deletions Src/ES.ManagedInjector/Injector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,14 @@ public Injector(Int32 pid, Assembly assembly, String methodName)
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += ResolveAssembly;
AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
}

/// <summary>
/// Execute the injection of the specified assembly
/// </summary>
/// <param name="context">This optional parameter is passed to the Inject method.
/// The parameter value is serialized with a BinaryFormatter (so be sure that it can be serialized)</param>
/// <returns></returns>
public InjectionResult Inject()
public InjectionResult Inject(Object context = null)
{
var result = InjectionResult.UnknownError;
ResolveDependencies();
Expand Down Expand Up @@ -97,7 +99,7 @@ public InjectionResult Inject()
ActivateHook();
if (VerifyInjection())
{
result = ActivateAssembly();
result = ActivateAssembly(context);
break;
}
else
Expand Down Expand Up @@ -240,10 +242,10 @@ private void ResolveDependencies()
}
}

private InjectionResult ActivateAssembly()
private InjectionResult ActivateAssembly(Object context)
{
var client = new Client(_assemblyContent, _methodName, _dependency, _files);
client.ActivateAssembly();
client.ActivateAssembly(context);
_lastErrorMessage = client.GetLastErrorMessage();
return client.GetLastError();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

namespace ES.ManagedInjector
{
internal class PipeChanell
internal class PipeChanel
{
private readonly StreamReader _reader;
private readonly StreamWriter _writer;
private InjectionResult _lastError = InjectionResult.Success;
private String _lastErrorMessage = String.Empty;

public PipeChanell(Stream stream)
public PipeChanel(Stream stream)
{
_reader = new StreamReader(stream);
_writer = new StreamWriter(stream);
Expand Down
57 changes: 49 additions & 8 deletions Src/ES.ManagedInjector/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -13,17 +14,18 @@ namespace ES.ManagedInjector
internal class Server
{
private readonly NamedPipeServerStream _server = new NamedPipeServerStream(Constants.NamedPipeCode.ToString("X"), PipeDirection.InOut);
private readonly PipeChanell _pipeChanell = null;
private readonly PipeChanel _pipeChanell = null;
private readonly Dictionary<String, Assembly> _dependencies = new Dictionary<String, Assembly>();

private InjectionResult _lastError = InjectionResult.Success;
private String _lastErrorMessage = String.Empty;
private Int32 _metadataToken = 0;
private Byte[] _assemblyBuffer = null;
private Object _context = null;

public Server()
{
_pipeChanell = new PipeChanell(_server);
_pipeChanell = new PipeChanel(_server);
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += ResolveAssembly;
AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
}
Expand Down Expand Up @@ -94,6 +96,30 @@ private Boolean ProcessCommand(PipeMessage msg)
_lastErrorMessage = e.ToString();
}
}
else if (msgType.Equals(Constants.Context, StringComparison.OrdinalIgnoreCase))
{
try
{
var dataString = msg.GetData();
var data = Convert.FromBase64String(dataString);
var formatter = new BinaryFormatter();
using(var memStream = new MemoryStream(data))
{
_context = formatter.Deserialize(memStream);
}
}
catch (SerializationException e)
{
_lastError = InjectionResult.ErrorInContextDeSerialization;
_lastErrorMessage = e.ToString();
}
catch (Exception e)
{
_lastError = InjectionResult.UnknownError;
_lastErrorMessage = e.ToString();
}

}
else if (msgType.Equals(Constants.Run, StringComparison.OrdinalIgnoreCase))
{
if (_assemblyBuffer == null)
Expand All @@ -103,7 +129,7 @@ private Boolean ProcessCommand(PipeMessage msg)
}
else
{
ActivateDll();
ActivateDll(_context);
}

exit = true;
Expand Down Expand Up @@ -149,14 +175,29 @@ private Object CreateType(ParameterInfo parameterInfo)

private Object[] CreateArgumentArray(ParameterInfo[] parameters)
{
return parameters.Select(CreateType).ToArray();
return parameters.Select(CreateType).ToArray();
}

private Object[] CreateInjectMethodArguments(ParameterInfo[] parameters, Object context)
{
Object[] arguments = null;
if (context == null)
{
arguments = CreateArgumentArray(parameters);
}
else if (parameters.Length == 1)
{
arguments = new[] { context };
}

return arguments;
}

private void InvokeMethod(MethodBase method)
private void InvokeMethod(MethodBase method, Object context)
{
try
{
var arguments = CreateArgumentArray(method.GetParameters());
var arguments = CreateInjectMethodArguments(method.GetParameters(), context);
Object thisObj = null;

// check if I have to create an instance to invoke the method
Expand Down Expand Up @@ -202,7 +243,7 @@ private MethodBase ResolveMethod(Assembly assembly)
return methodToInvoke;
}

private void ActivateDll()
private void ActivateDll(Object context)
{
try
{
Expand All @@ -211,7 +252,7 @@ private void ActivateDll()

if (methodToInvoke != null)
{
InvokeMethod(methodToInvoke);
InvokeMethod(methodToInvoke, context);
}
else
{
Expand Down
Loading

0 comments on commit 95b737a

Please sign in to comment.