4

I managed to write a semiworking EasyHook example that hooks recv function. I wrote a form, added a WebBrowser component, and started the application. The problem is, I get the HTTP packets, but if there's a socket, it seems that recv stops "hooking". The problem is, with an external application, Spystudio, I can get them hooking recv. So, what am I missing?

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 : I've no doubt about recv, here it is what apimonitor tells me:

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

So, can somebody help me?

VahidN
  • 18,457
  • 8
  • 73
  • 117
kaharas
  • 597
  • 2
  • 17
  • 39

3 Answers3

4

Problem Solved. The line that created trouble was

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

I changed it to

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

and now everything works just fine. Thanks everybody :)

kaharas
  • 597
  • 2
  • 17
  • 39
  • 3
    From the docs: *"SetExclusiveACL() sets an exclusive ACL. This means all threads that are enumerated through InACL are **NOT** intercepted while all others are."*. Also: *"A thread ID of **zero** will automatically be replaced by the current thread ID"*. So ``SetExclusiveACL(new Int32[] { 0 });`` was actually excluding your thread from receiving updates about the hook. The method ``SetInclusiveACL()`` does exactly the opposite: makes your thread be the only one to be able to intercept the hook, so that's why it worked. Passing an empty array to ``SetExclusiveACL()`` would also work. – Lucio Paiva Apr 26 '14 at 20:12
  • 1
    By the way, it is not mentioned anywhere in the EasyHook docs: *ACL* stands for [*Access Control List*](http://en.wikipedia.org/wiki/Access_control_list). – Lucio Paiva Apr 26 '14 at 20:15
2

There are a lot of different functions used with sockets. Maybe the plugin is not using the function named recv. Off the top of my head I can think of recvfrom, recvmsg, WSARecv, WSARecvFrom, WSARecvMsg, ReadFile, ReadFileEx.

Then, the plugin could be doing requests with overlapped I/O (possibly complicated by completion routines or completion ports), in which case the data isn't stored during the e.g. ReadFile function call but at some later time. Hooking those would be considerably more challenging.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • I thinked it too, but then why hooking the same function with spystudio get access to those packets, hooking ONLY recv? – kaharas Jan 03 '11 at 23:42
  • Is it documented somewhere that SpyStudio hooks only `recv`? They could be giving one name to a whole group of hooks to make it more user-friendly. – Ben Voigt Jan 03 '11 at 23:46
  • this may be possible, but if I hook all the functions you mentioned except recv, I don't get any packet. If I hook recv, suddenly I start seeing packets. So, either I missed to test some function, or the packets are really received throught recv. The real problem is, a LocalHook is enought to catch the plugin recv calls, or I have to set a global recv hook? – kaharas Jan 04 '11 at 16:03
  • Another little thing, I looked into api monitor a little more, and I found out I can intercept all the recv calls of ws2_32.dll made by wininet.dll module, but not the ones made from flash10l.ocx ... can somebody explain it to me? – kaharas Jan 28 '11 at 21:49
2

I wrote a tool dumping http using sharppcs in c#. It uses the winpcap-driver. I think it is more reliable tan apihooks.

HTTPSaver (with sources)
SharpPcap
Winpcap

Zotta
  • 2,513
  • 1
  • 21
  • 27
  • I can't use packet sniffing, because the program I am writing must be redistributable, and not every network card can be put in promiscous mode ( mine for instance ). I HAVE TO use api hooking :) – kaharas Jan 28 '11 at 18:08
  • @kaharas, promiscuous mode is only required to capture packets that's unrelated to your machine. I believe all network cards support capturing packages sent/received by that card. – sisve Jan 28 '11 at 19:48
  • Probably I'm dumb ... but I couldn't find a way to make Wireshark work, he kept saying that the card needed promiscous mode. The same happened when I tried to write a "local sniffer" using the java winpcap wrapper. – kaharas Jan 28 '11 at 19:59
  • It is true that id depends on the card. Especially onboard-cards tend to not work. – Zotta Jan 28 '11 at 20:30
  • "If the interface is not running in promiscuous mode, it won't see any traffic that isn't intended to be seen by your machine. It will see broadcast packets, and multicast packets sent to a multicast MAC address the interface is set up to receive." http://www.wireshark.org/faq.html – sisve Jan 29 '11 at 05:16
  • However, that wont help scenarios where winpcap doesn't support some network cards at all. – sisve Jan 29 '11 at 05:16