1

Windows API をフックしようとするのはこれが初めてです。私の目標は、プロセスが作成/オープン/読み取り/書き込みしようとしているすべてのファイルを監視することです。できるだけ冗長にするために、NtCreateFile() や NtOpenFile() などの ntdll.dll API をフックすることにしました。そのため、この目標を達成するために、簡単で堅牢な EasyHook を使用しました。私は本質的に FileMon の例に従い、本当に必要なものを変更しました: Hooked 関数です。開かれるファイルに関する情報を読み取ろうとすると、ObjectName などの OBJECT_ATTRIBUTES 構造から情報を読み取ろうとします。これらは整数ポインターであるため、文字列値を取得するために関数 Marshal.PtrToStringAuto(attributes.objectName) を使用することを期待していました。しかし、結果として、何の意味もなく、悪い文字列しか持てなくなります。また、ファイルアクセスが機能していないようです。おそらく DllImport 署名に、このコードに何か問題があると思います。EasyHook がそれらのマーシャリングについて不平を言っていたため、SafeHandle を IntPtr に置き換える必要があったことに注意してください。誰かが私を助けることができますか?

挿入された DLL の特定のコードは次のとおりです。

Run メソッドのコードは次のとおりです。

public void Run(RemoteHooking.IContext InContext, String inChannelName) 
        {
            // First of all, install all the hooks
            try
            {
                // NtCreateFile
                fileCreationHook = LocalHook.Create(
                    LocalHook.GetProcAddress("ntdll.dll", "NtCreateFile"),
                    new CreateFileDelegate(CreateFile_Hooked),
                    this
                    );

                fileCreationHook = LocalHook.Create(
                    LocalHook.GetProcAddress("ntdll.dll", "NtOpenFile"),
                    new OpenFileDelegate(OpenFile_Hooked),
                    this
                    );

                fileCreationHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
                remoteIf.Log("File creation Hook correctly installed on pid "+RemoteHooking.GetCurrentProcessId());


            }
            catch (Exception e)
            {
                remoteIf.Log(e.Message);
                remoteIf.Log(e.StackTrace);
                return;
            }

            // Wake up the process
            remoteIf.Log("Waiking up process...");
            RemoteHooking.WakeUpProcess();

            while (true)
            {
                Thread.Sleep(500);

                if (queue.Count > 0)
                {
                    String[] package = null;

                    lock (queue)
                    {
                        package = queue.ToArray();
                        queue.Clear();
                    }

                    remoteIf.OnCreateFile(RemoteHooking.GetCurrentProcessId(), package);
                }
                else
                    remoteIf.Ping();
            }

        }

コンストラクターのコードは次のとおりです。

public InjectedDLL(RemoteHooking.IContext InContext, String inChannelName)
        {
            // Create the structure which will contain all the messages
            queue = new Stack<string>();
            // Initiate the connection to the Injector process, getting back its interface
            remoteIf = RemoteHooking.IpcConnectClient<IPCInterface>(inChannelName);
            // Try invocating a method to test the connection.
            remoteIf.Ping();
        }

ここにフックデリゲートとフック関数があります

public delegate int CreateFileDelegate(out  IntPtr handle,
            System.IO.FileAccess access,
            ref OBJECT_ATTRIBUTES objectAttributes,
            out IO_STATUS_BLOCK ioStatus,
            ref long allocSize,
            uint fileAttributes,
            System.IO.FileShare share,
            uint createDisposition,
            uint createOptions,
            IntPtr eaBuffer,
            uint eaLength);

        public int CreateFile_Hooked(
            out  IntPtr handle,
            System.IO.FileAccess access,
            ref OBJECT_ATTRIBUTES objectAttributes,
            out IO_STATUS_BLOCK ioStatus,
            ref long allocSize,
            uint fileAttributes,
            System.IO.FileShare share,
            uint createDisposition,
            uint createOptions,
            IntPtr eaBuffer,
            uint eaLength)
        {

            //string s = Marshal.PtrToStringAuto(objectAttributes.ObjectName);
            int res = NtCreateFile(out handle, access,ref objectAttributes,out ioStatus, ref allocSize,fileAttributes, share,createDisposition,createOptions,eaBuffer,eaLength);
            return res;
        }

ここに NtDll.Dll ネイティブ関数があります。

[DllImport("ntdll.dll", ExactSpelling = true, SetLastError = true)]
        public static extern int NtCreateFile(
            out  IntPtr handle,
            System.IO.FileAccess access,
            ref OBJECT_ATTRIBUTES objectAttributes,
            out IO_STATUS_BLOCK ioStatus,
            ref long allocSize,
            uint fileAttributes,
            System.IO.FileShare share,
            uint createDisposition,
            uint createOptions,
            IntPtr eaBuffer,
            uint eaLength);

        [DllImport("ntdll.dll", ExactSpelling = true, SetLastError = true)]
        public static extern int NtOpenFile(
            out  IntPtr handle,
            System.IO.FileAccess access,
            ref OBJECT_ATTRIBUTES objectAttributes,
            out IO_STATUS_BLOCK ioStatus,
            System.IO.FileShare share,
            uint openOptions
            );

        [StructLayout(LayoutKind.Sequential, Pack = 0)]
        public struct OBJECT_ATTRIBUTES
        {
            public Int32 Length;
            public IntPtr RootDirectory;
            public IntPtr ObjectName;
            public uint Attributes;
            public IntPtr SecurityDescriptor;
            public IntPtr SecurityQualityOfService;

        }

        [StructLayout(LayoutKind.Sequential, Pack = 0)]
        public struct IO_STATUS_BLOCK
        {
            public uint status;
            public IntPtr information;
        }
4

1 に答える 1