Hooking CreateProcess (kernel32)

Dec 22, 2008 at 2:21 PM
Edited Dec 22, 2008 at 2:22 PM

Hi Chris,

Amazing project BTW. I have a question/issue hopefully you can help me out with. I'm attempting to do a very simple hook into CreateProcess strongly based on your filemon example. I am running into an issue where as it seems like the dll is injected properly however when the injected processes calls CreateProcess the injected application crashes. In addition I am also hooking the example CreateFile within the same injection dll and it is properly capturing all CreateFile calls as expected. Any help would be very much appreciated. Thank you in advance.

Below is the parts of the code that might help diagnose this (I omitted the stuff fthat came directly from filemon based on CreateFile)...

public void Run(RemoteHooking.IContext InContext, String InArg1)
{
            try
            {
                CreateFileHook = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "CreateFileW"), new DCreateFile(CreateFile_Hooked), this);
                CreateFileHook.ThreadACL.SetExclusiveACL(new Int32[1]);

                CreateProcessHook = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "CreateProcessW"), new DCreateProcess(CreateProcess_Hooked), this);
                CreateProcessHook.ThreadACL.SetExclusiveACL(new Int32[1]);

                HookList = new List<LocalHook>();
                HookList.Add(CreateFileHook);
                HookList.Add(CreateProcessHook);
            }
            catch (Exception e)
            {
                Interface.ReportError(RemoteHooking.GetCurrentProcessId(), e);
                return;
            }

            try
            {
                while (Interface.Ping(RemoteHooking.GetCurrentProcessId()))
                {
                    Thread.Sleep(500);

                    //CreateFile
                    lock (CreateFileQueue)
                    {
                        if (CreateFileQueue.Count > 0)
                        {
                            String[] Package = null;

                            Package = CreateFileQueue.ToArray();

                            CreateFileQueue.Clear();

                            Interface.OnCreateFile(RemoteHooking.GetCurrentProcessId(), Package);
                        }
                    }

                    //CreateProcess
                    lock (CreateProcessQueue)
                    {
                        if (CreateProcessQueue.Count > 0)
                        {
                            String[] Package = null;

                            Package = CreateProcessQueue.ToArray();

                            CreateProcessQueue.Clear();

                            Interface.OnCreateProcess(RemoteHooking.GetCurrentProcessId(), Package);
                        }
                    }
                }
            }
            catch
            {
                // NET Remoting will raise an exception if host is unreachable
            }
        }

[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        delegate bool DCreateProcess(
            String imageName,
            String cmdLine,
            IntPtr lpProcessAttributes,
            IntPtr lpThreadAttributes,
            bool boolInheritHandles,
            Int32 dwCreationFlags,
            IntPtr lpEnvironment,
            IntPtr lpszCurrentDir,
            byte[] si,
            IntPtr pi);

        delegate bool DCreateProcessAsync(
            Int32 InClientPID,
            IntPtr InHandle,
            String imageName,
            String cmdLine,
            IntPtr lpProcessAttributes,
            IntPtr lpThreadAttributes,
            bool boolInheritHandles,
            Int32 dwCreationFlags,
            IntPtr lpEnvironment,
            IntPtr lpszCurrentDir,
            byte[] si,
            IntPtr pi);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        static extern bool CreateProcess(
            String imageName,
            String cmdLine,
            IntPtr lpProcessAttributes,
            IntPtr lpThreadAttributes,
            bool boolInheritHandles,
            Int32 dwCreationFlags,
            IntPtr lpEnvironment,
            IntPtr lpszCurrentDir,
            byte[] si,
            IntPtr pi);

        static bool CreateProcess_Hooked(
            String imageName,
            String cmdLine,
            IntPtr lpProcessAttributes,
            IntPtr lpThreadAttributes,
            bool boolInheritHandles,
            Int32 dwCreationFlags,
            IntPtr lpEnvironment,
            IntPtr lpszCurrentDir,
            byte[] si,
            IntPtr pi)
        {
            try
            {
                ProcessHook This = (ProcessHook)HookRuntimeInfo.Callback;

                lock (This.CreateProcessQueue)
                {
                    if (This.CreateProcessQueue.Count < 1000)
                    {
                        This.CreateProcessQueue.Push(imageName + "|" + cmdLine);
                    }
                }
            }
            catch
            {

            }

            // call original API...
            return CreateProcess(
                imageName,
                cmdLine,
                lpProcessAttributes,
                lpThreadAttributes,
                boolInheritHandles,
                dwCreationFlags,
                lpEnvironment,
                lpszCurrentDir,
                si,
                pi);
        }

Thank you for looking into this,
Tom

Dec 24, 2008 at 7:08 AM
Edited Dec 24, 2008 at 7:10 AM
In my little bit of experience with EasyHook I find the first place to look for problems is the return at the end of my hooked function.  I assume you checked to make sure that your CreateProcess signature is working before you put it in the hook?  You could try changing the signature to return an unmanaged bool. afaik bools are 1 byte in c# and 4 bytes in win32
Dec 30, 2008 at 10:59 AM
I'm new in C# and EasyHook. I did same as tkeller with same result....explorer.exe crashes after calling CreateProcess.   I tried add [return: MarshalAs(UnmanagedType.I1)] to CreateProcess definition but the problem remains. Any Suggestions ?
Jan 7, 2009 at 11:13 AM
Did you try [return: MarshalAs(UnmanagedType.Bool)] ?
Nov 18, 2009 at 7:45 PM

Hello, as using also now EasyHook to port one of the application to win64.... & as unmanaged code cannot be cross injected from 64 to 32 & 32 to 64, I tried today to play with this great EasyHook tool in C# so with the managed toolkit... & I have also the same behavior... I modified the main.cs of FileMonInject & when I am in a 64 bits shell already injected by FileMon & so having FileMonInject running in it,, I can without any problem propagate/inject & so finally hook all started 64 bits prog from this "hooked" shell.

But the problem comes when I try to start a 32 bit app like devenv.exe (which is in the program files X86 dir on my computer) & devenv is started but the hooked shell hangs & disappaear :(

 

Here is the code of the main.cs modified to hook CreateProcessW() :

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using EasyHook;

namespace FileMonInject
{

    unsafe public class Main : EasyHook.IEntryPoint
    {
        FileMon.FileMonInterface Interface;
        LocalHook CreateFileHook;
        LocalHook NtCreateFileHook;
        LocalHook CreateProcessHook;
        Stack<String> NtCreateFileQueue = new Stack<String>();
        Stack<String> CreateProcessQueue = new Stack<String>();
        String InChannelName;

        public Main(
            RemoteHooking.IContext InContext,
            String InChannelName)
        {
            // connect to host...
            Interface = RemoteHooking.IpcConnectClient<FileMon.FileMonInterface>(InChannelName);

            Interface.Ping();
        }

        public void Run(
            RemoteHooking.IContext InContext,
            String InChannelName)
        {
            this.InChannelName = InChannelName;
            // install hook...
            try
            {

                CreateFileHook = LocalHook.Create(
                    LocalHook.GetProcAddress("kernel32.dll", "CreateFileW"),
                    new DCreateFile(CreateFile_Hooked),
                    this);

                CreateProcessHook = LocalHook.Create(
                    LocalHook.GetProcAddress("kernel32.dll", "CreateProcessW"),
                    new DCreateProcess(CreateProcess_Hooked),
                    this);

                /*NtCreateFileHook = LocalHook.Create(
                                    LocalHook.GetProcAddress("NtDll.dll", "NtCreateFile"),
                                    new DNtCreateFile(NtCreateFile_Hooked),
                                    this); */
                
                CreateFileHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
                CreateProcessHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
                //NtCreateFileHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
            }
            catch (Exception ExtInfo)
            {
                Interface.ReportException(ExtInfo);

                return;
            }

            Interface.IsInstalled(RemoteHooking.GetCurrentProcessId());

            RemoteHooking.WakeUpProcess();

            // wait for host process termination...
            try
            {
                while (true)
                {
                    Thread.Sleep(500);

                    // transmit newly monitored file accesses...
                    lock (NtCreateFileQueue)
                    {
                        if (NtCreateFileQueue.Count > 0)
                        {
                            String[] Package = null;

                            Package = NtCreateFileQueue.ToArray();

                            NtCreateFileQueue.Clear();

                            Interface.OnCreateFile(RemoteHooking.GetCurrentProcessId(), Package);
                            //CreateProcess
                        }
                    }
                    lock (CreateProcessQueue)
                    {
                        if (CreateProcessQueue.Count > 0)
                        {
                            String[] Package = null;

                            Package = CreateProcessQueue.ToArray();

                            CreateProcessQueue.Clear();

                            Interface.OnCreateFile(RemoteHooking.GetCurrentProcessId(), Package);
                        }
                    }
                    Interface.Ping();
                }
            }
            catch
            {
                // Ping() will raise an exception if host is unreachable
            }
        }

        [UnmanagedFunctionPointer(
            CallingConvention.StdCall,
            CharSet = CharSet.Unicode,
            SetLastError = true)]
        delegate IntPtr DCreateFile(
            String InFileName,
            UInt32 InDesiredAccess,
            UInt32 InShareMode,
            IntPtr InSecurityAttributes,
            UInt32 InCreationDisposition,
            UInt32 InFlagsAndAttributes,
            IntPtr InTemplateFile);

        // just use a P-Invoke implementation to get native API access from C# (this step is not necessary for C++.NET)
        [DllImport("kernel32.dll",
            CharSet = CharSet.Unicode,
            SetLastError = true,
            CallingConvention = CallingConvention.StdCall)]
        static extern IntPtr CreateFile(
            String InFileName,
            UInt32 InDesiredAccess,
            UInt32 InShareMode,
            IntPtr InSecurityAttributes,
            UInt32 InCreationDisposition,
            UInt32 InFlagsAndAttributes,
            IntPtr InTemplateFile);

        // this is where we are intercepting all file accesses!
        static IntPtr CreateFile_Hooked(
            String InFileName,
            UInt32 InDesiredAccess,
            UInt32 InShareMode,
            IntPtr InSecurityAttributes,
            UInt32 InCreationDisposition,
            UInt32 InFlagsAndAttributes,
            IntPtr InTemplateFile)
        {
            
            try
            {
                Main This = (Main)HookRuntimeInfo.Callback;

                lock (This.NtCreateFileQueue)
                {
                    This.NtCreateFileQueue.Push("[" + RemoteHooking.GetCurrentProcessId() + ":" + 
                        RemoteHooking.GetCurrentThreadId() +  "]: \"" + InFileName + "\"");
                }
            }
            catch
            {
            }

            // call original API...
            return CreateFile(
                InFileName,
                InDesiredAccess,
                InShareMode,
                InSecurityAttributes,
                InCreationDisposition,
                InFlagsAndAttributes,
                InTemplateFile);
        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        struct STARTUPINFO
        {
            public Int32 cb;
            public IntPtr lpReserved;
            public IntPtr lpDesktop;
            public IntPtr lpTitle;
            public Int32 dwX;
            public Int32 dwY;
            public Int32 dwXSize;
            public Int32 dwYSize;
            public Int32 dwXCountChars;
            public Int32 dwYCountChars;
            public Int32 dwFillAttribute;
            public Int32 dwFlags;
            public Int16 wShowWindow;
            public Int16 cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public int dwProcessId;
            public int dwThreadId;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            public int nLength;
            public IntPtr lpSecurityDescriptor;
            public int bInheritHandle;
        }
        [Flags]
        enum CreationFlags
        {
            CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
            CREATE_DEFAULT_ERROR_MODE = 0x04000000,
            CREATE_NEW_CONSOLE = 0x00000010,
            CREATE_NEW_PROCESS_GROUP = 0x00000200,
            CREATE_NO_WINDOW = 0x08000000,
            CREATE_PROTECTED_PROCESS = 0x00040000,
            CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
            CREATE_SEPARATE_WOW_VDM = 0x00001000,
            CREATE_SUSPENDED = 0x00000004,
            CREATE_UNICODE_ENVIRONMENT = 0x00000400,
            DEBUG_ONLY_THIS_PROCESS = 0x00000002,
            DEBUG_PROCESS = 0x00000001,
            DETACHED_PROCESS = 0x00000008,
            EXTENDED_STARTUPINFO_PRESENT = 0x00080000
        }
        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        delegate bool DCreateProcess(
           String lpApplicationName,
           String lpCommandLine, 
           SECURITY_ATTRIBUTES *lpProcessAttributes,
           SECURITY_ATTRIBUTES *lpThreadAttributes, bool bInheritHandles,
           UInt32 dwCreationFlags, void *lpEnvironment, String lpCurrentDirectory,
           STARTUPINFO *lpStartupInfo,
           PROCESS_INFORMATION *lpProcessInformation);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CreateProcess(
           String lpApplicationName,
           String lpCommandLine, 
           SECURITY_ATTRIBUTES *lpProcessAttributes,
           SECURITY_ATTRIBUTES *lpThreadAttributes, bool bInheritHandles,
           UInt32 dwCreationFlags, void *lpEnvironment, String lpCurrentDirectory,
           STARTUPINFO *lpStartupInfo,
           PROCESS_INFORMATION *lpProcessInformation);
        
        static bool CreateProcess_Hooked(string lpApplicationName,
           String lpCommandLine,
           SECURITY_ATTRIBUTES *lpProcessAttributes,
           SECURITY_ATTRIBUTES *lpThreadAttributes, bool bInheritHandles,
           UInt32 dwCreationFlags, void *lpEnvironment, String lpCurrentDirectory,
           STARTUPINFO *lpStartupInfo,
           PROCESS_INFORMATION *lpProcessInformation)
        {
            Main This = (Main)HookRuntimeInfo.Callback;
            try
            {
                lock (This.CreateProcessQueue)
                {
                    This.CreateProcessQueue.Push("[" + RemoteHooking.GetCurrentProcessId() + ":" +
                        RemoteHooking.GetCurrentThreadId() + "]: \"" + lpApplicationName + "|" + lpCommandLine + "\"");
                }
            }
            catch
            {
            }


            // call original API...
            PROCESS_INFORMATION pi;
            if (lpProcessInformation == null) lpProcessInformation = &pi;
            bool bCreatedProcess=CreateProcess(
                lpApplicationName,
                lpCommandLine,
                lpProcessAttributes,
                lpThreadAttributes,
                bInheritHandles,
                dwCreationFlags | (uint)CreationFlags.CREATE_SUSPENDED,
                lpEnvironment,
                lpCurrentDirectory,
                lpStartupInfo,
                lpProcessInformation);

            HelperServiceInterface helper = new HelperServiceInterface();
            helper.InjectEx(
                NativeAPI.GetCurrentProcessId(),
                lpProcessInformation->dwProcessId,
                lpProcessInformation->dwThreadId,
                0x20000000,
                "FileMonInject.dll",
                "FileMonInject.dll",
                true,
                false,
                This.InChannelName);
            
            return bCreatedProcess;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct UNICODE_STRING : IDisposable
        {
            public ushort Length;
            public ushort MaximumLength;
            private IntPtr buffer;

            public UNICODE_STRING(string s)
            {
                Length = (ushort)(s.Length * 2);
                MaximumLength = (ushort)(Length + 2);
                buffer = Marshal.StringToHGlobalUni(s);
            }

            public void Dispose()
            {
                Marshal.FreeHGlobal(buffer);
                buffer = IntPtr.Zero;
            }

            public override string ToString()
            {
                return Marshal.PtrToStringUni(buffer);
            }
        }
        
        [StructLayout(LayoutKind.Sequential)]
        public struct OBJECT_ATTRIBUTES : IDisposable
        {
            public int Length;
            public IntPtr RootDirectory;
            private IntPtr objectName;
            public uint Attributes;
            public IntPtr SecurityDescriptor;
            public IntPtr SecurityQualityOfService;

            public OBJECT_ATTRIBUTES(string name, uint attrs)
            {
                Length = 0;
                RootDirectory = IntPtr.Zero;
                objectName = IntPtr.Zero;
                Attributes = attrs;
                SecurityDescriptor = IntPtr.Zero;
                SecurityQualityOfService = IntPtr.Zero;

                Length = Marshal.SizeOf(this);
                ObjectName = new UNICODE_STRING(name);
            }

            public UNICODE_STRING ObjectName
            {
                get
                {
                    return (UNICODE_STRING)Marshal.PtrToStructure(
                     objectName, typeof(UNICODE_STRING));
                }

                set
                {
                    bool fDeleteOld = objectName != IntPtr.Zero;
                    if (!fDeleteOld)
                        objectName = Marshal.AllocHGlobal(Marshal.SizeOf(value));
                    Marshal.StructureToPtr(value, objectName, fDeleteOld);
                }
            }

            public void Dispose()
            {
                if (objectName != IntPtr.Zero)
                {
                    Marshal.DestroyStructure(objectName, typeof(UNICODE_STRING));
                    Marshal.FreeHGlobal(objectName);
                    objectName = IntPtr.Zero;
                }
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        struct IO_STATUS_BLOCK
        {
            uint status;
            ulong information;
        }

        [UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Unicode,
            SetLastError = true)]
        delegate Int32 DNtCreateFile(
            void* FileHandle,
            UInt32 DesiredAccess,
            OBJECT_ATTRIBUTES* ObjectAttributes,
            IO_STATUS_BLOCK* IoStatusBlock,
            Int64* AllocationSize,
            UInt32 FileAttributes,
            UInt32 ShareAccess,
            UInt32 CreateDisposition,
            UInt32 CreateOptions,
            void* EaBuffer,
            UInt32 EaLength
            );

        [DllImport("ntdll.dll", ExactSpelling = true, SetLastError = true)]
        static extern Int32 NtCreateFile(
            void* FileHandle,
            UInt32 DesiredAccess,
            OBJECT_ATTRIBUTES* ObjectAttributes,
            IO_STATUS_BLOCK* IoStatusBlock,
            Int64* AllocationSize,
            UInt32 FileAttributes,
            UInt32 ShareAccess,
            UInt32 CreateDisposition,
            UInt32 CreateOptions,
            void* EaBuffer,
            UInt32 EaLength
            );

        Int32 NtCreateFile_Hooked(
            void* FileHandle,
            UInt32 DesiredAccess,
            OBJECT_ATTRIBUTES* ObjectAttributes,
            IO_STATUS_BLOCK* IoStatusBlock,
            Int64 *AllocationSize,
            UInt32 FileAttributes,
            UInt32 ShareAccess,
            UInt32 CreateDisposition,
            UInt32 CreateOptions,
            void* EaBuffer,
            UInt32 EaLength
            )
        {
            try
            {
                Main This = (Main)HookRuntimeInfo.Callback;

                lock (This.NtCreateFileQueue)
                {
                    This.NtCreateFileQueue.Push("[" + RemoteHooking.GetCurrentProcessId() + ":" +
                        RemoteHooking.GetCurrentThreadId() + "]: \"" + "NtCreateFile" + "\"");
                }
            }
            catch
            {
            }
            return NtCreateFile(
                FileHandle,
                DesiredAccess,
                ObjectAttributes,
                IoStatusBlock,
                AllocationSize,
                FileAttributes,
                ShareAccess,
                CreateDisposition,
                CreateOptions,
                EaBuffer,
                EaLength
                );
        }

    }
}

For your information,

I also modified the FileMon program to call RemoteHooking.CreateAndInject() when the id on the command is not an integer but a program full path name to test cross injection & it works !

So the problem appears to be really (I suppose from my level of knowledges & tests) is when... hooking specially CreateProcess() & "invoking & injecting" 32 bit progs from hooked 64 progs :(

 

Program.cs of FileMon

using System;
using System.Collections.Generic;
using System.Runtime.Remoting;
using System.Text;
using System.IO;
using EasyHook;
using System.Windows.Forms;

namespace FileMon
{
    public class FileMonInterface : MarshalByRefObject
    {
        public void IsInstalled(Int32 InClientPID)
        {
            Console.WriteLine("FileMon has been installed in target {0}.\r\n", InClientPID);
        }

        public void OnCreateFile(Int32 InClientPID, String[] InFileNames)
        {
            for (int i = 0; i < InFileNames.Length; i++)
            {
                Console.WriteLine(InFileNames[i]);
            }
        }

        public void ReportException(Exception InInfo)
        {
            Console.WriteLine("The target process has reported an error:\r\n" + InInfo.ToString());
        }

        public void Ping()
        {
        }
    }

    class Program
    {
        static String ChannelName = null;

        static void Main(string[] args)
        {
            Int32 TargetPID = 0;

            try
            {
                Config.Register(
                    "A FileMon like demo application.",
                    "FileMon.exe",
                    "FileMonInject.dll");
            }
            catch (ApplicationException)
            {
                MessageBox.Show("This is an administrative task!", "Permission denied...", MessageBoxButtons.OK);

                System.Diagnostics.Process.GetCurrentProcess().Kill();
            }

            RemoteHooking.IpcCreateServer<FileMonInterface>(ref ChannelName, WellKnownObjectMode.SingleCall);

            if ((args.Length != 1))
            {
                Console.WriteLine();
                Console.WriteLine("Usage: FileMon %PID%");
                Console.WriteLine();

                return;
            }

            try
            {
                if(!Int32.TryParse(args[0], out TargetPID))
                {
                    RemoteHooking.CreateAndInject(
                        args[0],
                        "",
                        0,
                        "FileMonInject.dll",
                        "FileMonInject.dll",
                        out TargetPID,
                        ChannelName);
                }
                else
                {
                    RemoteHooking.Inject(
                        TargetPID,
                        "FileMonInject.dll",
                        "FileMonInject.dll",
                        ChannelName);
                }
                
                Console.ReadLine();
            }
            catch (Exception ExtInfo)
            {
                Console.WriteLine("There was an error while connecting to target:\r\n{0}", ExtInfo.ToString());
            }
        }
    }
}

Thx in advance for all your help on my issue. By the way, actually I was unable to be able to inject in cross WOW environment bu hooking CreateProcess()

Regards

Louis

Nov 19, 2009 at 10:56 AM

Arg ! also tried this morning to replace the workflow CreateProcess+Inject by CreateAndInject ! Why : to be sure that I did everything correctly & looking in the code of EasyHook doing CreateProcess+Inject is really similar to CreateAndInject... so I feel that the problem does not come from here (that's only an assumption from my side) :

With this new code below, Still works correctly from 64 bits programs spawning 64 bits programs but not from 64 bits calling/spawning 32 bits programs :( Maybe a specific behavior of the original CreateProcess() when switching to the WOW64 environment & conflicts between CREATED_SUSPENDED/wow64 initializations & EasyHook Injection.... because If you can inject later with filemon by giving the pid....

So it appears that EasyHook is able to inject from 64 bits, 32 bits programs but fully initialized & already running but not freshly suspended 32 bits programs during a CreateProcess step :( maybe still WOW64 barrier issues ?

My new code to call createandinject instead of original createprocess+inject() (don't take care on forced return value, it is only for testing purpose)

            // call original API...
/*            PROCESS_INFORMATION pi;
            if (lpProcessInformation == null) lpProcessInformation = π
            bool bCreatedProcess=CreateProcess(
                lpApplicationName,
                lpCommandLine,
                lpProcessAttributes,
                lpThreadAttributes,
                bInheritHandles,
                dwCreationFlags | (uint)CreationFlags.CREATE_SUSPENDED,
                lpEnvironment,
                lpCurrentDirectory,
                lpStartupInfo,
                lpProcessInformation);

            HelperServiceInterface helper = new HelperServiceInterface();
            helper.InjectEx(
                NativeAPI.GetCurrentProcessId(),
                lpProcessInformation->dwProcessId,
                lpProcessInformation->dwThreadId,
                0x20000000,
                "FileMonInject.dll",
                "FileMonInject.dll",
                true,
                false,
                This.InChannelName);
 */
            int processId;
            RemoteHooking.CreateAndInject(
                lpApplicationName,
                lpCommandLine,
                (int)dwCreationFlags,
                "FileMonInject.dll",
                "FileMonInject.dll",
                out processId,
                This.InChannelName);
            if (lpProcessInformation != null) lpProcessInformation->dwProcessId = processId;
            return true;
            
            //return bCreatedProcess;

 

 

Dec 4, 2009 at 3:21 PM

Ok ! so finally I was able to use EasyHook to inject & hook & without modifying any easyhook sourcode I was able to hook CreateProcess & propagate the injection without any WOW64 limitation.

so I was also able to break the 64 to 32 & 32 to 64 barrier & better, with the unmanaged code API !

Need now to test if my workaround for breaking the 32<>64 barrier in the two way & also being able to inject spawned process from CreateProcess hook, is robust & reliable...

 

 

 

Jan 16, 2010 at 5:35 AM

i know this is an old post but is it possible to attach the above mentioned project please?

Jan 16, 2010 at 10:46 AM

Answered to you by mail ;)

if you wrote your code in c++, don't forget to add extern "c", winapi & other declaration syntaxs for stack parameters order !

to break WOW64/32 barrier,as said by the author, managed in managed code but in std, code, you will have to write your proper mechanism (tcp, events & wait for objects, ...)

don't forget that you cannot inject .net/clr progs  without (for the moment you have to re-write executable or directly mscoree & chain to the old one...) due to MS limitation to reduce virus writers... as said, what's a shame when you see lot of programers like us writing cool progs extending applications features by injection (gamepads, text management, stereo display ...) !

Louis

Jan 16, 2010 at 8:02 PM

My dear llecaroz,

I am in the same boat as gkiller. Is it possible for you to send me response as well?

Thank you!

Feb 25, 2010 at 9:05 AM

Hi! I would love to see that solution too. Perhaps you could send me an email as well? Or post it here? Cheers!

May 2, 2015 at 3:23 PM
Hello!
I would love to see that solution too. I am doing a project and need to solve that problem.
Can i see the solution ?

Thank you!