Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EasyHook示例项目“;RemoteFileMonitor";得到意想不到的结果_C#_C++_Hook - Fatal编程技术网

C# EasyHook示例项目“;RemoteFileMonitor";得到意想不到的结果

C# EasyHook示例项目“;RemoteFileMonitor";得到意想不到的结果,c#,c++,hook,C#,C++,Hook,我已在此处下载了项目“RemoteFileMonitor”: 此项目生成由输入进程id打开的所有文件的控制台日志 应用程序运行时没有问题,但日志显示意外结果 我用不同的程序(包括记事本)对其进行了测试,结果如下: 简而言之,如果多次打开某个文件,则日志仅第一次显示该文件,并且仅显示不同文件的更多结果 我需要它来实时监控外部进程的文件访问,但预进程经常试图打开某个文件,因此日志中的这些信息对我来说很重要 这里是原始源代码的主要部分: namespace FileMonitorHook { pu

我已在此处下载了项目“RemoteFileMonitor”:

此项目生成由输入进程id打开的所有文件的控制台日志

应用程序运行时没有问题,但日志显示意外结果

我用不同的程序(包括记事本)对其进行了测试,结果如下:

简而言之,如果多次打开某个文件,则日志仅第一次显示该文件,并且仅显示不同文件的更多结果

我需要它来实时监控外部进程的文件访问,但预进程经常试图打开某个文件,因此日志中的这些信息对我来说很重要

这里是原始源代码的主要部分:

namespace FileMonitorHook
{

public class InjectionEntryPoint: EasyHook.IEntryPoint
{
    /// <summary>
    /// Reference to the server interface within FileMonitor
    /// </summary>
    ServerInterface _server = null;

    /// <summary>
    /// Message queue of all files accessed
    /// </summary>
    Queue<string> _messageQueue = new Queue<string>();

    /// <summary>
    /// EasyHook requires a constructor that matches <paramref name="context"/> and any additional parameters as provided
    /// in the original call to <see cref="EasyHook.RemoteHooking.Inject(int, EasyHook.InjectionOptions, string, string, object[])"/>.
    /// 
    /// Multiple constructors can exist on the same <see cref="EasyHook.IEntryPoint"/>, providing that each one has a corresponding Run method (e.g. <see cref="Run(EasyHook.RemoteHooking.IContext, string)"/>).
    /// </summary>
    /// <param name="context">The RemoteHooking context</param>
    /// <param name="channelName">The name of the IPC channel</param>
    public InjectionEntryPoint(
        EasyHook.RemoteHooking.IContext context,
        string channelName)
    {
        // Connect to server object using provided channel name
        _server = EasyHook.RemoteHooking.IpcConnectClient<ServerInterface>(channelName);

        // If Ping fails then the Run method will be not be called
        _server.Ping();
    }

    /// <summary>
    /// The main entry point for our logic once injected within the target process. 
    /// This is where the hooks will be created, and a loop will be entered until host process exits.
    /// EasyHook requires a matching Run method for the constructor
    /// </summary>
    /// <param name="context">The RemoteHooking context</param>
    /// <param name="channelName">The name of the IPC channel</param>
    public void Run(
        EasyHook.RemoteHooking.IContext context,
        string channelName)
    {
        // Injection is now complete and the server interface is connected
        _server.IsInstalled(EasyHook.RemoteHooking.GetCurrentProcessId());

        // Install hooks

        // CreateFile https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
        var createFileHook = EasyHook.LocalHook.Create(
            EasyHook.LocalHook.GetProcAddress("kernel32.dll", "CreateFileW"),
            new CreateFile_Delegate(CreateFile_Hook),
            this);

        // ReadFile https://msdn.microsoft.com/en-us/library/windows/desktop/aa365467(v=vs.85).aspx
        var readFileHook = EasyHook.LocalHook.Create(
            EasyHook.LocalHook.GetProcAddress("kernel32.dll", "ReadFile"),
            new ReadFile_Delegate(ReadFile_Hook),
            this);

        // WriteFile https://msdn.microsoft.com/en-us/library/windows/desktop/aa365747(v=vs.85).aspx
        var writeFileHook = EasyHook.LocalHook.Create(
            EasyHook.LocalHook.GetProcAddress("kernel32.dll", "WriteFile"),
            new WriteFile_Delegate(WriteFile_Hook),
            this);

        // Activate hooks on all threads except the current thread
        createFileHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
        readFileHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
        writeFileHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });

        _server.ReportMessage("CreateFile, ReadFile and WriteFile hooks installed");

        // Wake up the process (required if using RemoteHooking.CreateAndInject)
        EasyHook.RemoteHooking.WakeUpProcess();

        try
        {
            // Loop until FileMonitor closes (i.e. IPC fails)
            while (true)
            {
                System.Threading.Thread.Sleep(500);

                string[] queued = null;

                lock (_messageQueue)
                {
                    queued = _messageQueue.ToArray();
                    _messageQueue.Clear();
                }

                // Send newly monitored file accesses to FileMonitor
                if (queued != null && queued.Length > 0)
                {
                    _server.ReportMessages(queued);
                }
                else
                {
                    _server.Ping();
                }
            }
        }
        catch
        {
            // Ping() or ReportMessages() will raise an exception if host is unreachable
        }

        // Remove hooks
        createFileHook.Dispose();
        readFileHook.Dispose();
        writeFileHook.Dispose();

        // Finalise cleanup of hooks
        EasyHook.LocalHook.Release();
    }

    /// <summary>
    /// P/Invoke to determine the filename from a file handle
    /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364962(v=vs.85).aspx
    /// </summary>
    /// <param name="hFile"></param>
    /// <param name="lpszFilePath"></param>
    /// <param name="cchFilePath"></param>
    /// <param name="dwFlags"></param>
    /// <returns></returns>
    [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern uint GetFinalPathNameByHandle(IntPtr hFile, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszFilePath, uint cchFilePath, uint dwFlags);

    #region CreateFileW Hook

    /// <summary>
    /// The CreateFile delegate, this is needed to create a delegate of our hook function <see cref="CreateFile_Hook(string, uint, uint, IntPtr, uint, uint, IntPtr)"/>.
    /// </summary>
    /// <param name="filename"></param>
    /// <param name="desiredAccess"></param>
    /// <param name="shareMode"></param>
    /// <param name="securityAttributes"></param>
    /// <param name="creationDisposition"></param>
    /// <param name="flagsAndAttributes"></param>
    /// <param name="templateFile"></param>
    /// <returns></returns>
    [UnmanagedFunctionPointer(CallingConvention.StdCall,
                CharSet = CharSet.Unicode,
                SetLastError = true)]
    delegate IntPtr CreateFile_Delegate(
                String filename,
                UInt32 desiredAccess,
                UInt32 shareMode,
                IntPtr securityAttributes,
                UInt32 creationDisposition,
                UInt32 flagsAndAttributes,
                IntPtr templateFile);

    /// <summary>
    /// Using P/Invoke to call original method.
    /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
    /// </summary>
    /// <param name="filename"></param>
    /// <param name="desiredAccess"></param>
    /// <param name="shareMode"></param>
    /// <param name="securityAttributes"></param>
    /// <param name="creationDisposition"></param>
    /// <param name="flagsAndAttributes"></param>
    /// <param name="templateFile"></param>
    /// <returns></returns>
    [DllImport("kernel32.dll",
        CharSet = CharSet.Unicode,
        SetLastError = true, CallingConvention = CallingConvention.StdCall)]
    static extern IntPtr CreateFileW(
        String filename,
        UInt32 desiredAccess,
        UInt32 shareMode,
        IntPtr securityAttributes,
        UInt32 creationDisposition,
        UInt32 flagsAndAttributes,
        IntPtr templateFile);

    /// <summary>
    /// The CreateFile hook function. This will be called instead of the original CreateFile once hooked.
    /// </summary>
    /// <param name="filename"></param>
    /// <param name="desiredAccess"></param>
    /// <param name="shareMode"></param>
    /// <param name="securityAttributes"></param>
    /// <param name="creationDisposition"></param>
    /// <param name="flagsAndAttributes"></param>
    /// <param name="templateFile"></param>
    /// <returns></returns>
    IntPtr CreateFile_Hook(
        String filename,
        UInt32 desiredAccess,
        UInt32 shareMode,
        IntPtr securityAttributes,
        UInt32 creationDisposition,
        UInt32 flagsAndAttributes,
        IntPtr templateFile)
    {
        try
        {
            lock (this._messageQueue)
            {
                if (this._messageQueue.Count < 1000)
                {
                    string mode = string.Empty;
                    switch (creationDisposition)
                    {
                        case 1:
                            mode = "CREATE_NEW";
                            break;
                        case 2:
                            mode = "CREATE_ALWAYS";
                            break;
                        case 3:
                            mode = "OPEN_ALWAYS";
                            break;
                        case 4:
                            mode = "OPEN_EXISTING";
                            break;
                        case 5:
                            mode = "TRUNCATE_EXISTING";
                            break;
                    }

                    // Add message to send to FileMonitor
                    this._messageQueue.Enqueue(
                        string.Format("[{0}:{1}]: CREATE ({2}) \"{3}\"",
                        EasyHook.RemoteHooking.GetCurrentProcessId(), EasyHook.RemoteHooking.GetCurrentThreadId()
                        , mode, filename));
                }
            }
        }
        catch
        {
            // swallow exceptions so that any issues caused by this code do not crash target process
        }

        // now call the original API...
        return CreateFileW(
            filename,
            desiredAccess,
            shareMode,
            securityAttributes,
            creationDisposition,
            flagsAndAttributes,
            templateFile);
    }

    #endregion

    #region ReadFile Hook

    /// <summary>
    /// The ReadFile delegate, this is needed to create a delegate of our hook function <see cref="ReadFile_Hook(IntPtr, IntPtr, uint, out uint, IntPtr)"/>.
    /// </summary>
    /// <param name="hFile"></param>
    /// <param name="lpBuffer"></param>
    /// <param name="nNumberOfBytesToRead"></param>
    /// <param name="lpNumberOfBytesRead"></param>
    /// <param name="lpOverlapped"></param>
    /// <returns></returns>
    [UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = true)]
    delegate bool ReadFile_Delegate(
        IntPtr hFile,
        IntPtr lpBuffer,
        uint nNumberOfBytesToRead,
        out uint lpNumberOfBytesRead,
        IntPtr lpOverlapped);

    /// <summary>
    /// Using P/Invoke to call the orginal function
    /// </summary>
    /// <param name="hFile"></param>
    /// <param name="lpBuffer"></param>
    /// <param name="nNumberOfBytesToRead"></param>
    /// <param name="lpNumberOfBytesRead"></param>
    /// <param name="lpOverlapped"></param>
    /// <returns></returns>
    [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
    static extern bool ReadFile(
        IntPtr hFile, 
        IntPtr lpBuffer,
        uint nNumberOfBytesToRead, 
        out uint lpNumberOfBytesRead, 
        IntPtr lpOverlapped);

    /// <summary>
    /// The ReadFile hook function. This will be called instead of the original ReadFile once hooked.
    /// </summary>
    /// <param name="hFile"></param>
    /// <param name="lpBuffer"></param>
    /// <param name="nNumberOfBytesToRead"></param>
    /// <param name="lpNumberOfBytesRead"></param>
    /// <param name="lpOverlapped"></param>
    /// <returns></returns>
    bool ReadFile_Hook(
        IntPtr hFile,
        IntPtr lpBuffer,
        uint nNumberOfBytesToRead,
        out uint lpNumberOfBytesRead,
        IntPtr lpOverlapped)
    {
        bool result = false;
        lpNumberOfBytesRead = 0;

        // Call original first so we have a value for lpNumberOfBytesRead
        result = ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, out lpNumberOfBytesRead, lpOverlapped);

        try
        {
            lock (this._messageQueue)
            {
                if (this._messageQueue.Count < 1000)
                {
                    // Retrieve filename from the file handle
                    StringBuilder filename = new StringBuilder(255);
                    GetFinalPathNameByHandle(hFile, filename, 255, 0);

                    // Add message to send to FileMonitor
                    this._messageQueue.Enqueue(
                        string.Format("[{0}:{1}]: READ ({2} bytes) \"{3}\"",
                        EasyHook.RemoteHooking.GetCurrentProcessId(), EasyHook.RemoteHooking.GetCurrentThreadId()
                        , lpNumberOfBytesRead, filename));
                }
            }
        }
        catch
        {
            // swallow exceptions so that any issues caused by this code do not crash target process
        }

        return result;
    }

    #endregion

    #region WriteFile Hook

    /// <summary>
    /// The WriteFile delegate, this is needed to create a delegate of our hook function <see cref="WriteFile_Hook(IntPtr, IntPtr, uint, out uint, IntPtr)"/>.
    /// </summary>
    /// <param name="hFile"></param>
    /// <param name="lpBuffer"></param>
    /// <param name="nNumberOfBytesToWrite"></param>
    /// <param name="lpNumberOfBytesWritten"></param>
    /// <param name="lpOverlapped"></param>
    /// <returns></returns>
    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    delegate bool WriteFile_Delegate(
        IntPtr hFile,
        IntPtr lpBuffer,
        uint nNumberOfBytesToWrite,
        out uint lpNumberOfBytesWritten,
        IntPtr lpOverlapped);

    /// <summary>
    /// Using P/Invoke to call original WriteFile method
    /// </summary>
    /// <param name="hFile"></param>
    /// <param name="lpBuffer"></param>
    /// <param name="nNumberOfBytesToWrite"></param>
    /// <param name="lpNumberOfBytesWritten"></param>
    /// <param name="lpOverlapped"></param>
    /// <returns></returns>
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool WriteFile(
        IntPtr hFile,
        IntPtr lpBuffer,
        uint nNumberOfBytesToWrite,
        out uint lpNumberOfBytesWritten,
        IntPtr lpOverlapped);

    /// <summary>
    /// The WriteFile hook function. This will be called instead of the original WriteFile once hooked.
    /// </summary>
    /// <param name="hFile"></param>
    /// <param name="lpBuffer"></param>
    /// <param name="nNumberOfBytesToWrite"></param>
    /// <param name="lpNumberOfBytesWritten"></param>
    /// <param name="lpOverlapped"></param>
    /// <returns></returns>
    bool WriteFile_Hook(
        IntPtr hFile,
        IntPtr lpBuffer,
        uint nNumberOfBytesToWrite,
        out uint lpNumberOfBytesWritten,
        IntPtr lpOverlapped)
    {
        bool result = false;

        // Call original first so we get lpNumberOfBytesWritten
        result = WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, out lpNumberOfBytesWritten, lpOverlapped);

        try
        {
            lock (this._messageQueue)
            {
                if (this._messageQueue.Count < 1000)
                {
                    // Retrieve filename from the file handle
                    StringBuilder filename = new StringBuilder(255);
                    GetFinalPathNameByHandle(hFile, filename, 255, 0);

                    // Add message to send to FileMonitor
                    this._messageQueue.Enqueue(
                        string.Format("[{0}:{1}]: WRITE ({2} bytes) \"{3}\"",
                        EasyHook.RemoteHooking.GetCurrentProcessId(), EasyHook.RemoteHooking.GetCurrentThreadId()
                        , lpNumberOfBytesWritten, filename));
                }
            }
        }
        catch
        {
            // swallow exceptions so that any issues caused by this code do not crash target process
        }

        return result;
    }

    #endregion
}
名称空间文件监视器挂钩
{
公共类InjectionEntryPoint:EasyHook.IEntryPoint
{
/// 
///对FileMonitor中服务器接口的引用
/// 
服务器接口_server=null;
/// 
///访问的所有文件的消息队列
/// 
队列_messageQueue=新队列();
/// 
///EasyHook需要一个与所提供的任何其他参数匹配的构造函数
///在最初的通话中。
/// 
///同一个构造函数上可以存在多个构造函数,前提是每个构造函数都有相应的Run方法(例如)。
/// 
///远程挂钩上下文
///IPC通道的名称
公共注射剂入口点(
EasyHook.RemoteHooking.IContext上下文,
字符串(名称)
{
//使用提供的通道名称连接到服务器对象
_server=EasyHook.RemoteHooking.IpcConnectClient(channelName);
//如果Ping失败,则不会调用Run方法
_Ping();
}
/// 
///我们的逻辑的主要入口点一旦被注入到目标进程中。
///在这里将创建钩子,并将进入一个循环,直到主机进程退出。
///EasyHook要求构造函数具有匹配的运行方法
/// 
///远程挂钩上下文
///IPC通道的名称
公开募捐(
EasyHook.RemoteHooking.IContext上下文,
字符串(名称)
{
//注入现已完成,服务器接口已连接
_已安装server.IsInstalled(EasyHook.RemoteHooking.GetCurrentProcessId());
//安装挂钩
//创建文件https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
var createFileHook=EasyHook.LocalHook.Create(
EasyHook.LocalHook.GetProcAddress(“kernel32.dll”、“CreateFileW”),
新的CreateFile_委托(CreateFile_钩子),
这),;
//读取文件https://msdn.microsoft.com/en-us/library/windows/desktop/aa365467(v=vs.85).aspx
var readFileHook=EasyHook.LocalHook.Create(
EasyHook.LocalHook.GetProcAddress(“kernel32.dll”、“ReadFile”),
新的ReadFile_委托(ReadFile_钩子),
这),;
//写文件https://msdn.microsoft.com/en-us/library/windows/desktop/aa365747(v=vs.85).aspx
var writeFileHook=EasyHook.LocalHook.Create(
EasyHook.LocalHook.GetProcAddress(“kernel32.dll”,“WriteFile”),
新的WriteFile\u委托(WriteFile\u钩子),
这),;
//激活除当前线程外的所有线程上的挂钩
createFileHook.ThreadACL.SetExclusiveACL(新的Int32[]{0});
readFileHook.ThreadACL.SetExclusiveACL(新的Int32[]{0});
writeFileHook.ThreadACL.SetExclusiveACL(新的Int32[]{0});
_ReportMessage(“已安装CreateFile、ReadFile和WriteFile挂钩”);
//唤醒进程(如果使用RemoteHooking.CreateAndInject,则需要)
EasyHook.RemoteHooking.WakeUpProcess();
尝试
{
//循环直到FileMonitor关闭(即IPC失败)
while(true)
{
系统.线程.线程.睡眠(500);
字符串[]排队=空;
锁定(_messageQueue)
{
排队=_messageQueue.ToArray();
_messageQueue.Clear();
}
//将新监视的文件访问发送到FileMonitor
if(排队!=null&&queued.Length>0)
{
_server.ReportMessages(排队);
}
其他的
{
_Ping();
}
}
}
抓住
{
//如果无法访问主机,Ping()或ReportMessages()将引发异常
}
//脱钩
createFileHook.Dispose();
readFileHook.Dispose();
writeFileHook.Dispose();
//完成吊钩的清理工作
EasyHook.LocalHook.Release();
}
/// 
///P/Invoke从文件句柄确定文件名
/// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364962(v=vs.85).aspx
/// 
/// 
/// 
/// 
/// 
/// 
[DllImport(“Kernel32.dll”,SetLastError=true,CharSet=CharSet.Auto)]
静态外部uint GetFinalPathNameByHandle(IntPtr hFile[Marshallas(UnmanagedType.LPTStr)]StringBuilder lpszFilePath、uint cchFilePath、uint dwFlags);
#区域创建文件钩子
/// 
///CreateFile委托,这是创建钩子函数的委托所必需的。
/// 
/// 
/// 
/// 
/// 
/// 
/// 
/// 
/// 
[UnmanagedFunctionPointer(CallingConvention.StdCall,
CharSet=CharSet.Unicode,
SetLastError=true)]
委托IntPtr CreateFile_委托(
字符串文件名,
UInt32期望访问,
UInt32共享模式,
IntPtr安全属性,
UInt32创建位置,
UInt32标志和属性,
IntPtr模板文件);
/// 
///使用P/Invoke