Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.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_C#_C++_Hook_Detours_Easyhook - Fatal编程技术网

C# 具有原始函数调用的EasyHook

C# 具有原始函数调用的EasyHook,c#,c++,hook,detours,easyhook,C#,C++,Hook,Detours,Easyhook,我正在开发一个应用程序,它使用EasyHook库向所需进程注入代码,并截获来自特定dll的调用。就我而言 该库是Oracle调用接口OCI.dll。我想截取已执行的sql语句,以便在客户端创建sql查询日志。以前我使用的是微软的detours(2.1版),但它的许可证不允许商业使用,3.0版的成本很高。 我开始使用EasyHook图书馆。我在交付的示例中更改了从kernel32.dll截取函数CreateFileW的代码,并将其调整为与oci.dll中的函数OCIStmtFetch2一起使用 我

我正在开发一个应用程序,它使用EasyHook库向所需进程注入代码,并截获来自特定dll的调用。就我而言 该库是Oracle调用接口OCI.dll。我想截取已执行的sql语句,以便在客户端创建sql查询日志。以前我使用的是微软的detours(2.1版),但它的许可证不允许商业使用,3.0版的成本很高。 我开始使用EasyHook图书馆。我在交付的示例中更改了从kernel32.dll截取函数CreateFileW的代码,并将其调整为与oci.dll中的函数OCIStmtFetch2一起使用

我有头文件或oci库,我知道确切的函数参数和返回类型。根据头文件,签名为:

剑OCISMTFETCH2(OCISMT*stmtp, 错误*errhp, ub4 nrows, ub2方向, ub4滚动偏移, ub4模式)

根据Oracle提供的其他头文件,OCISMT是一种结构,OCIRROR是handle to error函数。ub2和ub4是无符号短(16位)和无符号整数(32位)的类型定义。剑的类型定义为有符号整数(也是32位) 我的EasyHook库注入代码如下所示(一些函数名与示例FileMonInject相同):

使用系统;
使用System.Collections.Generic;
使用系统线程;
使用System.Runtime.InteropServices;
使用简易工具;
命名空间FileMonInject
{
公共类Main:EasyHook.IEntryPoint
{
FileMon.FileMonInterface接口;
LocalHook-CreateFileHook;
堆栈队列=新堆栈();
公用干管(
RemoteHooking.IContext InContext,
字符串(名称)
{
//连接到主机。。。
接口=RemoteHooking.IpcConnectClient(InChannelName);
接口Ping();
}
不安全的公共无效运行(
RemoteHooking.IContext InContext,
字符串(名称)
{
//安装挂钩。。。
尝试
{
CreateFileHook=LocalHook.Create(
LocalHook.GetProcAddress(“oci.dll”、“ocistftfetch2”),
新的DOCIStmtFetch2(DOCIStmtFetch2_钩住),
这),;
CreateFileHook.ThreadACL.SetExclusiveACL(新的Int32[]{0});
}
捕获(例外情况)
{
接口.ReportException(exterfo);
返回;
}
已安装接口(RemoteHooking.GetCurrentProcessId());
RemoteHooking.WakeUpProcess();
//等待主机进程终止。。。
尝试
{
while(true)
{
睡眠(500);
//传输新监视的文件访问。。。
如果(Queue.Count>0)
{
String[]Package=null;
锁(队列)
{
Package=Queue.ToArray();
Queue.Clear();
}
OnOCIStmtFetch2(RemoteHooking.GetCurrentProcessId(),包);
}
其他的
接口Ping();
}
}
抓住
{
}
}
[UnmanagedFunctionPointer(CallingConvention.StdCall,
CharSet=CharSet.Ansi,
SetLastError=true)]
不安全的委托int DOCIStmtFetch2(
void*stmtp,
无效*errhp,
UInt32 nrows,
UInt16方向,
UInt32卷轴,
UInt32模式);
/只需使用p-调用实现从C ^获得本地API访问(此步骤对于C++ .NET来说不是必需的)
[DllImport(“oci.dll”,CharSet=CharSet.Ansi,SetLastError=true,CallingConvention=CallingConvention.StdCall)]
//[返回:Marshallas(UnmanagedType.I4)]
不安全的静态外部程序Int32 OCISMTFETCH2(
void*stmtp,
无效*errhp,
UInt32 nrows,
UInt16方向,
UInt32卷轴,
UInt32模式);
//这就是我们拦截所有文件访问的地方!
不安全的静态Int32 DOCIStmtFetch2_已挂起(
void*stmtp,
无效*errhp,
UInt32 nrows,
UInt16方向,
UInt32卷轴,
UInt32模式)
{
尝试
{
Main This=(Main)HookRuntimeInfo.Callback;
This.Queue.Push(“[”+RemoteHooking.GetCurrentProcessId()+”:”+
RemoteHooking.GetCurrentThreadId()+“]:\”+nrows+“\”);
}
捕获(异常ee)
{
}
//调用原始API。。。
int E=OCISSTFTFETCH2(
stmtp,
呃,,
nrows,
方向,
纸卷
模式);
返回E;
}
}
}
正如你所看到的,我用UInt32映射了ub4,用UInt16映射了ub2,用Int32映射了剑。第一次我对指针使用IntPtr(两个第一个参数),但代码没有正常工作。注入dll截获函数调用非常完美,我可以在原始函数之前运行代码,我可以调用原始函数并返回预期值,但当执行返回E时,目标应用程序会导致内存冲突异常并退出。正如您在代码中看到的,然后我尝试使用void*指针和unsafe关键字来启用C#中的指针,得到了相同的结果。与使用Detours库的代码相比,我可以使用调试器检查的参数和指针值对于这两种情况都是相同的
using System;
using System.Collections.Generic;
using System.Threading;
using System.Runtime.InteropServices;
using EasyHook;

namespace FileMonInject
{
    public class Main : EasyHook.IEntryPoint
    {
        FileMon.FileMonInterface Interface;
        LocalHook CreateFileHook;
        Stack<String> Queue = new Stack<String>();
        public Main(
            RemoteHooking.IContext InContext,
            String InChannelName)
        {
            // connect to host...
            Interface = RemoteHooking.IpcConnectClient<FileMon.FileMonInterface>(InChannelName);
            Interface.Ping();
        }
        unsafe public void Run(
            RemoteHooking.IContext InContext,
            String InChannelName)
        {
            // install hook...
            try
            {
                CreateFileHook = LocalHook.Create(
                    LocalHook.GetProcAddress("oci.dll", "OCIStmtFetch2"),
                    new DOCIStmtFetch2(DOCIStmtFetch2_Hooked),
                    this);
                CreateFileHook.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...
                    if (Queue.Count > 0)
                    {
                        String[] Package = null;

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

                            Queue.Clear();
                        }
                        Interface.OnOCIStmtFetch2(RemoteHooking.GetCurrentProcessId(), Package);
                    }
                    else
                        Interface.Ping();
                }
            }
            catch
            {
            }
        }

        [UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Ansi,
            SetLastError = true)]
        unsafe delegate int DOCIStmtFetch2(
            void* stmtp,
            void* errhp,
            UInt32 nrows,
            UInt16 orientation,
            UInt32 scroll,
            UInt32 mode);


        // just use a P-Invoke implementation to get native API access from C# (this step is not         necessary for C++.NET)
        [DllImport("oci.dll", CharSet = CharSet.Ansi, SetLastError = true, CallingConvention =    CallingConvention.StdCall)]
       // [return: MarshalAs(UnmanagedType.I4)]
         unsafe static extern Int32 OCIStmtFetch2(
            void* stmtp,
            void* errhp,
            UInt32 nrows,
            UInt16 orientation,
            UInt32 scroll, 
            UInt32 mode);

        // this is where we are intercepting all file accesses!
        unsafe static Int32 DOCIStmtFetch2_Hooked(
            void* stmtp,
            void* errhp,
            UInt32 nrows,
            UInt16 orientation,
            UInt32 scroll, 
            UInt32 mode)
        {

            try
            {
                Main This = (Main)HookRuntimeInfo.Callback;
                    This.Queue.Push("[" + RemoteHooking.GetCurrentProcessId() + ":" +
                        RemoteHooking.GetCurrentThreadId() + "]: \"" + nrows + "\"");
            }
            catch (Exception ee)
            {
            }
            // call original API...
            int E = OCIStmtFetch2(
                  stmtp,
                  errhp,
                  nrows,
                  orientation,
                  scroll,
                  mode);

          return E;
        }
    }
}