none
帮忙看看这段HOOK代码是什么意思 RRS feed

  • 问题

  • 这是我在网上看到的C# HOOKAPI 例子。

    类:

    using System;
    using System.Collections;
    using System.Runtime.InteropServices;
    
    public class APIHOOK
    {
        #region Api声明
        [DllImport("Kernel32.dll", EntryPoint = "GetModuleHandleA", CharSet = CharSet.Ansi)]
        static extern IntPtr GetModuleHandle(
            string lpModuleName
            );
        [DllImport("Kernel32.dll")]
        static extern bool VirtualProtect(
            IntPtr lpAddress,
            int dwSize,
            int flNewProtect,
            ref int lpflOldProtect
            );
        [DllImport("Kernel32.dll", EntryPoint = "lstrcpynA", CharSet = CharSet.Ansi)]
        static extern IntPtr lstrcpyn(
            byte[] lpString1,
            byte[] lpString2,
            int iMaxLength
            );
        [DllImport("Kernel32.dll")]
        static extern IntPtr GetProcAddress(
            IntPtr hModule,
            string lpProcName
            );
        [DllImport("Kernel32.dll")]
        static extern bool FreeLibrary(
            IntPtr hModule
            );
        #endregion
        #region 常量定义表
        const int PAGE_EXECUTE_READWRITE = 0x40;
        #endregion
        #region 变量表
        IntPtr ProcAddress;
        int lpflOldProtect = 0;
        byte[] OldEntry = new byte[5];
        byte[] NewEntry = new byte[5];
        IntPtr OldAddress;
        #endregion
        public APIHOOK() { }
        public APIHOOK(string ModuleName, string ProcName, IntPtr lpAddress)
        {
            Install(ModuleName, ProcName, lpAddress);
        }
        public bool Install(string ModuleName, string ProcName, IntPtr lpAddress)
        {
            IntPtr hModule = GetModuleHandle(ModuleName); //取模块句柄  
            if (hModule == IntPtr.Zero) return false;
            ProcAddress = GetProcAddress(hModule, ProcName); //取入口地址  
            if (ProcAddress == IntPtr.Zero) return false;
            if (!VirtualProtect(ProcAddress, 5, PAGE_EXECUTE_READWRITE, ref lpflOldProtect)) return false; //修改内存属性  
            Marshal.Copy(ProcAddress, OldEntry, 0, 5); //读取前5字节  
            NewEntry = AddBytes(new byte[1] { 233 }, BitConverter.GetBytes((Int32)((Int32)lpAddress - (Int32)ProcAddress - 5))); //计算新入口跳转  
            Marshal.Copy(NewEntry, 0, ProcAddress, 5); //写入前5字节  
            OldEntry = AddBytes(OldEntry, new byte[5] { 233, 0, 0, 0, 0 });
            OldAddress = lstrcpyn(OldEntry, OldEntry, 0); //取变量指针  
            Marshal.Copy(BitConverter.GetBytes((double)((Int32)ProcAddress - (Int32)OldAddress - 5)), 0, OldAddress + 6, 4); //保存JMP  
            FreeLibrary(hModule); //释放模块句柄  
            return true;
        }
        public void Suspend()
        {
            Marshal.Copy(OldEntry, 0, ProcAddress, 5);
        }
        public void Continue()
        {
            Marshal.Copy(NewEntry, 0, ProcAddress, 5);
        }
        public bool Uninstall()
        {
            if (ProcAddress == IntPtr.Zero) return false;
            Marshal.Copy(OldEntry, 0, ProcAddress, 5);
            ProcAddress = IntPtr.Zero;
            return true;
        }
        static byte[] AddBytes(byte[] a, byte[] b)
        {
            ArrayList retArray = new ArrayList();
            for (int i = 0; i < a.Length; i++)
            {
                retArray.Add(a[i]);
            }
            for (int i = 0; i < b.Length; i++)
            {
                retArray.Add(b[i]);
            }
            return (byte[])retArray.ToArray(typeof(byte));
        }
    }
    


    引用:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            delegate int SendCallbackd(int s, IntPtr buf, int len, int flag);
            SendCallbackd sendCallback;
            public Form1()
            {
                sendCallback = new SendCallbackd(sendProc);
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                send_Hook.Install("ws2_32.dll", "send", Marshal.GetFunctionPointerForDelegate(sendCallback));  
            }
            int sendProc(int s, IntPtr buf, int len, int flag)
            {
                byte[] buffer = new byte[len];
                Marshal.Copy(buf, buffer, 0, len); //读封包数据  
                send_Hook.Suspend(); //暂停拦截,转交系统调用  
                int ret = send(s, buffer, len, flag); //发送数据,此处可进行拦截  
                send_Hook.Continue(); //恢复HOOK  
                return ret;
            }  
        }
    }
    
    


    引用的程序有错误,我修改了下。不过还是不知道send这个方法是哪个对象的。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            APIHOOK send_Hook;
            delegate int SendCallbackd(int s, IntPtr buf, int len, int flag);
            SendCallbackd sendCallback;
            public Form1()
            {
                sendCallback = new SendCallbackd(sendProc);
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
               send_Hook = new APIHOOK();
                send_Hook.Install("ws2_32.dll", "send", Marshal.GetFunctionPointerForDelegate(sendCallback));  
            }
            int sendProc(int s, IntPtr buf, int len, int flag)
            {
                byte[] buffer = new byte[len];
                Marshal.Copy(buf, buffer, 0, len); //读封包数据  
                send_Hook.Suspend(); //暂停拦截,转交系统调用  
                int ret = send(s, buffer, len, flag); //发送数据,此处可进行拦截  
                send_Hook.Continue(); //恢复HOOK  
                return ret;
            }  
        }
    }
    
    


    2011年10月22日 4:01

答案

全部回复

  • 你好 saxiao

    欢迎到MSDN讨论这个问题。

    从您的提问中我不是很清楚您指的是哪个send

    一下是我的猜测,如果不正确,请纠正,本人虚心求教。

    send 指的是进程的名字。

    ProcAddress = GetProcAddress(hModule, ProcName); //取入口地址
    这段代码就是执行以进程名字找到该进程。

    然后sendProc这个方法应该是得到send 进程的消息钩子。

    希望对您有所帮助。

     


    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年10月24日 7:09
    版主
  • 谢谢您回答我的问题,我说的send 是最后一段代码里的,编译的时候提示找不到这个方法呀

      int ret = send(s, buffer, len, flag); //发送数据,此处可进行拦截  
    2011年10月26日 0:25
  • 从给出的代码来看,send 这个方法并没有对应的定义。

    也没有相应的签名与send方法对应。

    所以建议您可以联系一下编写上面那段代码的程序员,或者贴出相关的链接和代码在这,我们在深入的讨论下。

    谢谢您的支持。


    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年10月26日 1:38
    版主
  • 从给出的代码来看,send 这个方法并没有对应的定义。

    也没有相应的签名与send方法对应。

    所以建议您可以联系一下编写上面那段代码的程序员,或者贴出相关的链接和代码在这,我们在深入的讨论下。

    谢谢您的支持。


    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    原文在这里: http://blog.csdn.net/angeljanne87/article/details/6181811
    2011年10月29日 4:01
  • 原文中有声明send方法:

     [DllImport("ws2_32.dll")]  
     static extern int send(int s, byte[] buf, int len, int flag);  
    
    

    加上这个声明试试看。

    这里是MSND的官方说明: http://msdn.microsoft.com/zh-cn/library/ms740149(v=VS.85).aspx 

    希望能帮助您。


    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年10月31日 1:30
    版主