【问题标题】:EasyHook recv doesn't "hook" all packetsEasyHook recv 不会“挂钩”所有数据包
【发布时间】:2011-06-03 02:59:41
【问题描述】:

我设法编写了一个半工作的 EasyHook 示例来挂钩 recv 函数。我编写了一个表单,添加了一个 WebBrowser 组件,然后启动了应用程序。问题是,我得到了 HTTP 数据包,但如果有一个套接字,recv 似乎停止“挂钩”。 问题是,使用外部应用程序 Spystudio,我可以让它们连接 recv。那么,我错过了什么?

using System;
using System.Collections.Generic;
using System.Data;
using System.Runtime.InteropServices;
using System.Threading;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels.Ipc;
using EasyHook;

namespace flashing
{
    public partial class Form1 : Form,EasyHook.IEntryPoint
    {
        public LocalHook CreateRecvHook;

        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("Ws2_32.dll")]
        static extern int recv(
                    IntPtr socketHandle,
                    IntPtr buf,
                    int count,
                    int socketFlags
            );


        [UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Unicode,
            SetLastError = true)]


        delegate int Drecv(
                    IntPtr socketHandle,
                    IntPtr buf,
                    int count,
                    int socketFlags
            );


        static int recv_Hooked(
                    IntPtr socketHandle,
                    IntPtr buf,
                    int count,
                    int socketFlags)
        {
            int bytesCount = recv(socketHandle, buf, count, socketFlags);
            if (bytesCount > 0)
            {
                byte[] newBuffer = new byte[bytesCount];
                Marshal.Copy(buf, newBuffer, 0, bytesCount);
                string s = System.Text.ASCIIEncoding.ASCII.GetString(newBuffer);
                TextWriter tw = new StreamWriter("log.txt");
                tw.Write(s);
                tw.Close();
                Debug.WriteLine("Hooked:>" + s);
            }
            return bytesCount;
        }


        private void bottonHook_Click(object sender, EventArgs e)
        {
            try
            {
                CreateRecvHook = LocalHook.Create(
                    LocalHook.GetProcAddress("Ws2_32.dll", "recv"),
                    new Drecv(recv_Hooked),
                    this);

                CreateRecvHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
            }
            catch (Exception ExtInfo)
            {
                Debug.WriteLine("Error creating the Hook");
                return;
            }
            RemoteHooking.WakeUpProcess();
        }

        private void buttonLoader_Click(object sender, EventArgs e)
        {
            axShockwaveFlash1.LoadMovie(0, "test.swf");
        }
    }    
}

edit :我对 recv 毫无疑问,这是 apimonitor 告诉我的:

# TID Module API Return Error
5 2696 Flash10l.ocx recv ( 1992, 0x07080000, 65536, 0 ) 1

那么,有人可以帮帮我吗?

【问题讨论】:

    标签: c# easyhook


    【解决方案1】:

    套接字有很多不同的功能。可能插件没有使用名为recv 的函数。我脑海中浮现出recvfromrecvmsgWSARecvWSARecvFromWSARecvMsgReadFileReadFileEx

    然后,插件可能会使用重叠的 I/O 进行请求(可能会因完成例程或完成端口而变得复杂),在这种情况下,数据不会在例如ReadFile 函数调用,但在稍后的某个时间。钩住这些将更具挑战性。

    【讨论】:

    • 我也是这么想的,但是为什么用 spystudio 挂钩相同的功能可以访问这些数据包,只挂钩 recv?
    • 是否记录了 SpyStudio 仅挂钩 recv 的地方?他们可能会为一组钩子取一个名字,以使其更加用户友好。
    • 这可能是可能的,但如果我钩住你提到的所有功能,除了recv,我没有收到任何数据包。如果我钩住recv,突然我开始看到数据包。所以,要么我错过了测试某些功能,要么数据包真的是通过recv接收的。真正的问题是,LocalHook 足以捕获插件 recv 调用,还是我必须设置一个全局 recv 挂钩?
    • 另外一个小东西,我又查看了api monitor一点,发现我可以拦截wininet.dll模块对ws2_32.dll的recv调用,但不能拦截flash10l的recv调用.ocx ...有人可以向我解释一下吗?
    【解决方案2】:

    我在 c# 中使用 Sharppcs 编写了一个转储 http 的工具。它使用 winpcap 驱动程序。我认为它是更可靠的 tan apihooks。

    HTTPSaver (with sources)
    SharpPcap
    Winpcap

    【讨论】:

    • 我不能使用数据包嗅探,因为我正在编写的程序必须是可再分发的,并且不是每个网卡都可以置于混杂模式(例如我的)。我必须使用 api hooking :)
    • @kaharas,混杂模式只需要捕获与您的机器无关的数据包。我相信所有网卡都支持捕获该卡发送/接收的包。
    • 可能我很笨……但我找不到让 Wireshark 工作的方法,他一直说卡需要混杂模式。当我尝试使用 java winpcap 包装器编写“本地嗅探器”时发生了同样的情况。
    • 确实id依赖卡。尤其是板载卡往往不起作用。
    • "如果接口没有在混杂模式下运行,它不会看到任何不打算被您的机器看到的流量。它将看到广播数据包和多播数据包发送到接口设置为接收的多播 MAC 地址。” wireshark.org/faq.html
    【解决方案3】:

    问题已解决。造成麻烦的线路是

    CreateRecvHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
    

    我改成

    CreateRecvHook.ThreadACL.SetInclusiveACL(new Int32[] { 0 });
    

    现在一切正常。 谢谢大家:)

    【讨论】:

    • 来自文档:“SetExclusiveACL() 设置一个独占 ACL。这意味着通过 InACL 枚举的所有线程都被拦截,而所有其他线程都被拦截。”。另外:的线程 ID 将自动替换为当前线程 ID”。所以SetExclusiveACL(new Int32[] { 0 }); 实际上将您的线程排除在接收有关钩子的更新之外。 SetInclusiveACL() 方法正好相反:使你的线程成为唯一能够拦截钩子的线程,这就是它起作用的原因。将空数组传递给SetExclusiveACL() 也可以。
    • 顺便说一句,EasyHook 文档中没有提到它:ACL 代表Access Control List
    猜你喜欢
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    相关资源
    最近更新 更多