/// <summary> /// Will execute the given static method under system privileges. /// </summary> /// <remarks> /// <para> /// For some tasks it is necessary to have unrestricted access to the windows API. /// For example if you want to enumerate all running processes in all sessions. But /// keep in mind that you only can access these information within the given static /// method and only if it is called through this service. /// </para> /// <para> /// To accomplish this task, your assembly is loaded into a system service which /// executes the given static method in a remoted manner. This implies that the /// return type shall be marked with <see cref="SerializableAttribute" />. All /// handles or other process specific things obtained in the service, will be invalid /// in your application after the call is completed! Also the service will use /// a new instance of your class, so you should only rely on the given parameters /// and avoid using any external variables.. Your method shall be threaded as isolated! /// </para> /// <para> /// The next thing to mention is that all assemblies required for executing the method /// shall either be in the GAC or in the directory of the related EasyHook-Library. /// Otherwise the service won't be able to use your assembly! /// </para> /// <para> /// All unhandled exceptions will be rethrown by the local <see cref="ExecuteAsService" />. /// </para> /// </remarks> /// <typeparam name="TClass">A class containing the given static method.</typeparam> /// <param name="InMethodName">A public static method exposed by the given public class.</param> /// <param name="InParams">A list of serializable parameters being passed to your static method.</param> /// <returns>The same value your method is returning or <c>null</c> if a <c>void</c> method is called.</returns> /// <exception cref="AccessViolationException"> /// The current user is not an administrator. /// </exception> /// <include file='ExecuteAsService.xml' path='example' /> public static Object ExecuteAsService <TClass>( String InMethodName, params Object[] InParams) { return(ServiceMgmt.ExecuteAsService <TClass>(InMethodName, InParams)); }
internal static void InjectEx( Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, params Object[] InPassThruArgs) { MemoryStream PassThru = new MemoryStream(); ManagedRemoteInfo RemoteInfo = new ManagedRemoteInfo(); BinaryFormatter Format = new BinaryFormatter(); Int32 NtStatus; HelperServiceInterface.BeginInjection(InTargetPID); try { RemoteInfo = new ManagedRemoteInfo(); RemoteInfo.HostPID = InHostPID; RemoteInfo.UserParams = InPassThruArgs; GCHandle hPassThru = PrepareInjection( RemoteInfo, ref InLibraryPath_x86, ref InLibraryPath_x64, PassThru); /* * Inject library... */ try { switch (NtStatus = NativeAPI.RhInjectLibraryEx( InTargetPID, InWakeUpTID, NativeAPI.EASYHOOK_INJECT_MANAGED | InNativeOptions, typeof(Config).Assembly.Location, typeof(Config).Assembly.Location, hPassThru.AddrOfPinnedObject(), (int)PassThru.Length)) { case NativeAPI.STATUS_WOW_ASSERTION: { // Use helper application to bypass WOW64... if (InCanBypassWOW64) { WOW64Bypass.Inject( InHostPID, InTargetPID, InWakeUpTID, InNativeOptions, InLibraryPath_x86, InLibraryPath_x64, InPassThruArgs); } else { throw new AccessViolationException("Unable to inject library into target process."); } } break; case NativeAPI.STATUS_ACCESS_DENIED: { // Use service and try again... if (InCanCreateService) { ServiceMgmt.Inject( InHostPID, InTargetPID, InWakeUpTID, InNativeOptions, InLibraryPath_x86, InLibraryPath_x64, InPassThruArgs); } else { NativeAPI.Force(NtStatus); } } break; case NativeAPI.STATUS_SUCCESS: { // wait for injection completion HelperServiceInterface.WaitForInjection(InTargetPID); } break; default: { NativeAPI.Force(NtStatus); } break; } } finally { hPassThru.Free(); } } finally { HelperServiceInterface.EndInjection(InTargetPID); } }
internal static void InjectEx( Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, params Object[] InPassThruArgs) { var PassThru = new MemoryStream(); HelperServiceInterface.BeginInjection(InTargetPID); try { var RemoteInfo = new ManagedRemoteInfo(); RemoteInfo.HostPID = InHostPID; // We first serialise parameters so that they can be deserialised AFTER the UserLibrary is loaded var format = new BinaryFormatter(); var args = new List <object>(); if (InPassThruArgs != null) { foreach (var arg in InPassThruArgs) { using (var ms = new MemoryStream()) { format.Serialize(ms, arg); args.Add(ms.ToArray()); } } } RemoteInfo.UserParams = args.ToArray(); RemoteInfo.RequireStrongName = InRequireStrongName; var hPassThru = PrepareInjection( RemoteInfo, ref InLibraryPath_x86, ref InLibraryPath_x64, PassThru); /* * Inject library... */ try { Int32 NtStatus; switch (NtStatus = NativeAPI.RhInjectLibraryEx( InTargetPID, InWakeUpTID, NativeAPI.EASYHOOK_INJECT_MANAGED | InNativeOptions, typeof(Config).Assembly.Location, typeof(Config).Assembly.Location, hPassThru.AddrOfPinnedObject(), (int)PassThru.Length)) { case NativeAPI.STATUS_WOW_ASSERTION: { // Use helper application to bypass WOW64... if (InCanBypassWOW64) { WOW64Bypass.Inject( InHostPID, InTargetPID, InWakeUpTID, InNativeOptions, InLibraryPath_x86, InLibraryPath_x64, InRequireStrongName, InPassThruArgs); } else { throw new AccessViolationException("Unable to inject library into target process."); } } break; case NativeAPI.STATUS_ACCESS_DENIED: { // Use service and try again... if (InCanCreateService) { ServiceMgmt.Inject( InHostPID, InTargetPID, InWakeUpTID, InNativeOptions, InLibraryPath_x86, InLibraryPath_x64, InRequireStrongName, InPassThruArgs); } else { NativeAPI.Force(NtStatus); } } break; case NativeAPI.STATUS_SUCCESS: { // wait for injection completion HelperServiceInterface.WaitForInjection(InTargetPID); } break; default: { NativeAPI.Force(NtStatus); } break; } } finally { hPassThru.Free(); } } finally { HelperServiceInterface.EndInjection(InTargetPID); } }