winspool.exe hook problems

Aug 9, 2012 at 12:55 PM

Hello,

I want to hook the "PrvStartDocPrinterW" function in "winspool.exe".

I have been reading & coding during the last 2 weeks, and this is what i have done:

- My setup is VC# 2010 Express, EasyHook 2.6, Win7 x64

- I took the FileMon sample, and i modified it to my needs.

- The injection code:

            Process[] p = Process.GetProcessesByName("spoolsv");
            TargetPID = p[0].Id;

                RemoteHooking.Inject(
                    TargetPID,
                    "SpoolerInject.dll",
                    "SpoolerInject.dll",
                    ChannelName);

- Nothing special here.

- My modified Run method from the EasyHook.IEntryPoint interface:

        public void Run(RemoteHooking.IContext InContext, String InChannelName)
        {
            try
            {
                startDocHook = LocalHook.Create(LocalHook.GetProcAddress("spoolsv.exe", "PrvStartDocPrinterW"), new delegadoStartDoc(StartDoc_Hooked), this);

                startDocHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
            }
            catch (Exception ExtInfo)
            {
                Interface.ReportException(ExtInfo);

                return;
            }

            Interface.IsInstalled(RemoteHooking.GetCurrentProcessId());
            RemoteHooking.WakeUpProcess();

            try
            {
                while (true)
                {
                    Thread.Sleep(2500);

                    if (Cola.Count > 0)
                    {
                        String[] Package = null;

                        lock (Cola)
                        {
                            Package = Cola.ToArray();

                            Cola.Clear();
                        }

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

The special code is here:

startDocHook = LocalHook.Create(LocalHook.GetProcAddress("spoolsv.exe", "PrvStartDocPrinterW"), new delegadoStartDoc(StartDoc_Hooked), this);

It works, but, there is a problem.

And this is my custom code:

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct DOC_INFO_1
        {
            [MarshalAs(UnmanagedType.LPTStr)]
            public string pDocName;                 // Titulo
            [MarshalAs(UnmanagedType.LPTStr)]
            public string pOutputFile;              // Puerto de la impresora (IP, o USB)
            [MarshalAs(UnmanagedType.LPTStr)]
            public string pDatatype;                // Formato datos
        }

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        delegate Int32 delegadoStartDoc(IntPtr Handle, Int32 Level, DOC_INFO_1 info);

        [DllImport("spoolsv.exe", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        static extern Int32 PrvStartDocPrinterW(IntPtr Handle, Int32 Level, DOC_INFO_1 info);

As you can see, i'm doing a DllImport over the binary, and it seems to work.

And this is my hook code:

static Int32 StartDoc_Hooked(IntPtr Handle, Int32 Level, DOC_INFO_1 info)
        {
            Int32 resultado = 0;

            try
            {
                Main This = (Main)HookRuntimeInfo.Callback;

                resultado = PrvStartDocPrinterW(Handle, Level, info);

                lock (This.Cola)
                {
                    string msg = "Handle: " + Handle + " Level: " + Level + " pDocName: " + info.pDocName + " pOutputFile: " + info.pOutputFile + " pDatatype: " + info.pDatatype;
                    This.Cola.Push(msg);
                }
            }
            catch
            {
            }

            return resultado;     
        }

It works, i get the information in the Queue, and it puts the work in the printer queue, but, there is a problem.

Somehow, i think that there is a problem with the Stack after the call to the original PrvStartDocPrinterW.

If i change the code from this:

                Main This = (Main)HookRuntimeInfo.Callback;

                resultado = PrvStartDocPrinterW(Handle, Level, info);

To this (change the order of the 2 lines):

                resultado = PrvStartDocPrinterW(Handle, Level, info);

                Main This = (Main)HookRuntimeInfo.Callback;

I get an exception in the 'Main This' line.

I have been 2 weeks now trying to discover the problem, and i have little experience into this stuff, but a lot of years ago, i was very skilled with Assembler & so.

Some help would be appreciated.

Shall i update to 2.7 alpha ? Are my DllImports the problem ? Thank you !

Aug 19, 2012 at 3:07 PM

Try updating to 2.7, but I'm am guessing the same problem will exist as per your other post.