Skip to content
This repository has been archived by the owner on Dec 24, 2023. It is now read-only.

Update sample code #6

Open
TechnikEmpire opened this issue Jan 21, 2019 · 16 comments
Open

Update sample code #6

TechnikEmpire opened this issue Jan 21, 2019 · 16 comments
Assignees
Labels
bug Something isn't working

Comments

@TechnikEmpire
Copy link
Owner

Sandbox code is out of sync with the latest version.

@TechnikEmpire TechnikEmpire added the bug Something isn't working label Jan 21, 2019
@TechnikEmpire TechnikEmpire self-assigned this Jan 21, 2019
@jjxtra
Copy link

jjxtra commented Apr 8, 2019

Trying this new code in the sandbox, getting error 87 every time...

public static void ReadThread()
{
            var packet = new WinDivertBuffer();
            WinDivertAddress addr = new WinDivertAddress();
            uint readLen = 0;
            WinDivertParseResult result;
            Span<byte> packetData = null;
            NativeOverlapped recvOverlapped;
            IntPtr recvEvent = IntPtr.Zero;
            uint recvAsyncIoLen = 0;

            recvOverlapped = new NativeOverlapped();
            recvEvent = Kernel32.CreateEvent(IntPtr.Zero, false, false, IntPtr.Zero);
            recvOverlapped.EventHandle = recvEvent;

            try
            {
                while (!Disposed)
                {
                    packetData = null;
                    readLen = 0;
                    recvAsyncIoLen = 0;
                    addr.Reset();

                    Console.WriteLine("Read");

                    if (!WinDivert.WinDivertRecvEx(winDivertHandle, packet, 0, ref addr, ref readLen, ref recvOverlapped))
                    {
                        var error = Marshal.GetLastWin32Error();

                        // 997 == ERROR_IO_PENDING
                        if (error != 997)
                        {
                            Console.WriteLine(string.Format("Unknown IO error ID {0} while awaiting overlapped result.", error));
                            continue;
                        }

                        while (Kernel32.WaitForSingleObject(recvEvent, 1000) == (uint)WaitForSingleObjectResult.WaitTimeout)
                        {
                        }

                        if (!Kernel32.GetOverlappedResult(winDivertHandle, ref recvOverlapped, ref recvAsyncIoLen, false))
                        {
                            Console.WriteLine("Failed to get overlapped result.");
                            continue;
                        }

                        readLen = recvAsyncIoLen;
                    }

                    Console.WriteLine("Read packet {0}", readLen);

                    result = WinDivert.WinDivertHelperParsePacket(packet, readLen);

                    if (addr.Direction == WinDivertDirection.Inbound)
                    {
                        Console.WriteLine("inbound!");
                    }

                    if (result.IPv4Header != null && result.TcpHeader != null)
                    {
                        Console.WriteLine($"V4 TCP packet {addr.Direction} from {result.IPv4Header->SrcAddr}:{result.TcpHeader->SrcPort} to {result.IPv4Header->DstAddr}:{result.TcpHeader->DstPort}");
                    }
                    else if (result.IPv6Header != null && result.TcpHeader != null)
                    {
                        Console.WriteLine($"V4 TCP packet {addr.Direction} from {result.IPv6Header->SrcAddr}:{result.TcpHeader->SrcPort} to {result.IPv6Header->DstAddr}:{result.TcpHeader->DstPort}");
                    }

                    if (packetData != null)
                    {
                        Console.WriteLine("Packet has {0} byte payload.", packetData.Length);
                    }

                    Console.WriteLine($"{nameof(addr.Direction)} - {addr.Direction}");
                    Console.WriteLine($"{nameof(addr.Impostor)} - {addr.Impostor}");
                    Console.WriteLine($"{nameof(addr.Loopback)} - {addr.Loopback}");
                    Console.WriteLine($"{nameof(addr.IfIdx)} - {addr.IfIdx}");
                    Console.WriteLine($"{nameof(addr.SubIfIdx)} - {addr.SubIfIdx}");
                    Console.WriteLine($"{nameof(addr.Timestamp)} - {addr.Timestamp}");
                    Console.WriteLine($"{nameof(addr.PseudoIPChecksum)} - {addr.PseudoIPChecksum}");
                    Console.WriteLine($"{nameof(addr.PseudoTCPChecksum)} - {addr.PseudoTCPChecksum}");
                    Console.WriteLine($"{nameof(addr.PseudoUDPChecksum)} - {addr.PseudoUDPChecksum}");

                    // Console.WriteLine(WinDivert.WinDivertHelperCalcChecksums(packet, ref addr, WinDivertChecksumHelperParam.All));

                    if (!WinDivert.WinDivertSendEx(winDivertHandle, packet, readLen, 0, ref addr))
                    {
                        Console.WriteLine("Write Err: {0}", Marshal.GetLastWin32Error());
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Fatal error in read thread: {0}", ex);
            }
            finally
            {
                WinDivert.WinDivertClose(winDivertHandle);
                Kernel32.CloseHandle(recvEvent);
            }
}

public static void RunSandbox()
{
            winDivertHandle = WinDivert.WinDivertOpen("inbound and tcp", WinDivertLayer.Network, 0, 
                WinDivertOpenFlags.None);
            WinDivert.WinDivertSetParam(winDivertHandle, WinDivertParam.QueueLen, 16384);
            WinDivert.WinDivertSetParam(winDivertHandle, WinDivertParam.QueueTime, 8000);
            WinDivert.WinDivertSetParam(winDivertHandle, WinDivertParam.QueueSize, 33554432);
            Task.Run(FirewallThread);
}

@TechnikEmpire
Copy link
Owner Author

87 on which line?

@TechnikEmpire
Copy link
Owner Author

87 is invalid param. Right off the bat I don't see you resetting your overlapped event. Error codes are standard win api errors fyi to help you debug.

@jjxtra
Copy link

jjxtra commented Apr 8, 2019

Never mind I am binding against windivert 2.0, I am guessing the params are not an exact match.

@TechnikEmpire
Copy link
Owner Author

TechnikEmpire commented Apr 8, 2019

Windivert doesn't use semver even between minor versions the api is generally not backward compatible. 2.0 might as well be version 9000. A 2.0 update is in progress but the struct are now really ugly and hard to emulate.

@jjxtra
Copy link

jjxtra commented Apr 8, 2019

I tried using the pinvoke binder application on the 2.0 windivert.h file but it crashed, do you know of any other tools that auto-generate the pinvoke?

@jjxtra
Copy link

jjxtra commented Apr 8, 2019

I have 2.0 recv ex working in a fork, will post example code in a bit

@jjxtra
Copy link

jjxtra commented Apr 8, 2019

Well I am having trouble getting send ex working. It gets 997 io pending error but then attempting to read the overlapped data after the send event has signalled always gives error 87...

I have recv ex working. Care to compare code and see if we can figure it out? My branch is here: https://github.com/DigitalRuby/WinDivertSharp/tree/2.0

@jjxtra
Copy link

jjxtra commented Apr 9, 2019

I've got 2.0 working with receive and send with batching now, see the latest commits on my fork.

@TechnikEmpire
Copy link
Owner Author

Yeah I already have all that working but I want to have accurate structs that are modifiable.

@Lemorz56
Copy link

Yeah I already have all that working but I want to have accurate structs that are modifiable.

Sorry for bumping an old issue, did not want to create a new.
I've seen some comments about you making your own driver, is it Open source? Thanks.

@TechnikEmpire
Copy link
Owner Author

@Lemorz56 No problem. My driver is not open source. It doesn't even work like WinDivert anyway, as in, it's not a general purpose driver.

@illumen
Copy link

illumen commented Jul 14, 2021

How would we modify a packet's payload content?

@Lemorz56
Copy link

How would we modify a packet's payload content?

I ended up using the original C++ but im guessing you will need skip sending the one you want to change and then making your own using the old one, and sending that instead.

@TechnikEmpire
Copy link
Owner Author

I'm probably going to archive this repo.

@Lemorz56
Copy link

I'm probably going to archive this repo.

Yeah that's probably for the best

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants