HookInject.cs
using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.IO; using System.Runtime.InteropServices; using EasyHook; using System.Management.Automation; using System.Management.Automation.Runspaces; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels.Ipc; namespace PoshInternals { public class HookInterface : MarshalByRefObject { private static string _channelName; public Runspace Runspace; public static IpcServerChannel CreateServer() { return RemoteHooking.IpcCreateServer<HookInterface>( ref _channelName, WellKnownObjectMode.SingleCall); } public static void Inject(int pid, string entryPoint, string dll, string typeName, string scriptBlock, string modulePath, string additionalCode, bool log) { var assembly = System.Reflection.Assembly.GetExecutingAssembly(); RemoteHooking.Inject( pid, assembly.Location, // 32-bit version (the same because AnyCPU) assembly.Location, // 64-bit version (the same because AnyCPU) _channelName, entryPoint, dll, typeName, scriptBlock, modulePath, additionalCode, log); } public void ReportError( Int32 InClientPID, Exception e) { throw new Exception(string.Format("Process [{0}] reported error an error!"), e); } public void WriteHost( string e) { Console.WriteLine(e); } } public class HookInjection : EasyHook.IEntryPoint { public Runspace Runspace; public HookInterface Interface = null; public HookInjection( RemoteHooking.IContext InContext, String InChannelName, String entryPoint, String dll, String returnType, String scriptBlock, String modulePath, String additionalCode, bool eventLog) { Log("Opening hook interface channel...", eventLog); Interface = RemoteHooking.IpcConnectClient<HookInterface>(InChannelName); try { Runspace = RunspaceFactory.CreateRunspace(); Runspace.Open(); //Runspace.SessionStateProxy.SetVariable("HookInterface", Interface); } catch (Exception ex) { Log("Failed to open PowerShell runspace." + ex.Message, eventLog); Interface.ReportError(RemoteHooking.GetCurrentProcessId(), ex); } } public void Run( RemoteHooking.IContext InContext, String channelName, String entryPoint, String dll, String returnType, String scriptBlock, String modulePath, String additionalCode, bool eventLog) { try { Log(String.Format("Executing Set-Hook -Local -EntryPoint '{0}' -Dll '{1}' -ReturnType '{2}' -ScriptBlock '{3}' ", entryPoint, dll, returnType, scriptBlock), eventLog); using (var ps = PowerShell.Create()) { ps.Runspace = Runspace; ps.AddCommand("Import-Module"); ps.AddArgument(modulePath); ps.Invoke(); ps.Commands.Clear(); ps.AddCommand("Set-Hook"); ps.AddParameter("EntryPoint", entryPoint); ps.AddParameter("Dll", dll); ps.AddParameter("ReturnType", returnType); ps.AddParameter("AdditionalCode", additionalCode); var sb = ScriptBlock.Create(scriptBlock); ps.AddParameter("ScriptBlock", sb); ps.Invoke(); foreach (var record in ps.Streams.Error) { Log("Caught exception " + record.Exception.Message, eventLog); } } RemoteHooking.WakeUpProcess(); new System.Threading.ManualResetEvent(false).WaitOne(); } catch (Exception e) { Log("Caught exception " + e.Message, eventLog); try { Interface.ReportError(RemoteHooking.GetCurrentProcessId(), e); } catch { } return; } } private static void Log(string message, bool shouldLog) { if (!shouldLog) return; try { if (!System.Diagnostics.EventLog.SourceExists("PoshHook")) { System.Diagnostics.EventLog.CreateEventSource("PoshHook", "Application"); } var log = new System.Diagnostics.EventLog("Application", ".", "PoshHook"); log.WriteEntry(message); } catch { } } } } |