Coder Social home page Coder Social logo

Comments (10)

Rubensei avatar Rubensei commented on June 12, 2024 1

Released 0.10.0 of the sys crate and 0.6.0 of the wrapper crate with static feature

from windivert-rust.

Rubensei avatar Rubensei commented on June 12, 2024

Currently it's not possible, a dll is the final object when compiling for dynamic linking. Static linking requires a different compilation process that produces a different object (a .lib different from the one currently being generated when vendoring, which is an import library file)

I'm currently working in a static feature that overrides the vendored one and builds the library for static linking. It's taking some time since I don't know too much about msvc and mingw toolchains and compiler/linker arguments, specially since statically compiling mingw it's not officially supported by WinDivert.

Related to the vendored feature not being enabled by default, you still need to provide the .sys file. It's not really possible to make it seamless to use in any case, and at that point I think it makes more sense to manually opt in instead of having it as the default behavior. I should add top level documentation about it in both crates though.

Build scripts should not make changes outside OUT_DIR. For development cargo run can properly run the binary using either WINDIVERT_PATH or the vendored compile output. For release it's possible to use WINDIVERT_DLL_OUTPUT to copy the files to a known path and automate the rest.

from windivert-rust.

ShayBox avatar ShayBox commented on June 12, 2024

I realized after I tried it that the sys file was needed and that the driver has to be signed anyway, so vendored is really only useful to get the library to compile without manually setting up the required files, maybe vendored can additionally download the signed files and extract the sys, or use all the files from the archive instead of compiling which would make it completely autonomous.

I'm looking forward to the static feature, would that still require the sys file as-well? if so, maybe that previous suggestion would be a separate feature instead of being bundled into vendored so it works with static and vendored, if it gets added.

Library build scripts shouldn't but considering WinDivert has no standard install / install location at all and the files are required to be with the binary, the functionality makes sense to have for ease of use as an example file/script to include in your own project, but the above script needs refining.

from windivert-rust.

Rubensei avatar Rubensei commented on June 12, 2024

Downloading in build scripts it's generally a bad practice that might break builds with no apparent reason (outdated/broken link, link updated to point to another incompatible version, isolated build environments with no internet connection or connection issues in general, etc)

Bundling the files with the library also has its cons, being the main one that it makes it harder for the user of the library to replace the used version with a compatible new one. It's something I might be open to add once I give it a good though and research a bit how it might impact the library usage and version management.

The driver sys file will be required even if statically linking, furthermore it will make it mandatory for the sys file to be in the same folder as the binary, since windivert dll library code only searches for the driver in the same folder the library itself is located.

from windivert-rust.

ShayBox avatar ShayBox commented on June 12, 2024

For now I'm just gonna use my fork which replaces the WINDIVERT_DLL_OUTPUT env with a relative OUT_DIR path (just so I don't have to figure out a way to set an env or set it globally, not ideal) and switch to static if/when that comes out, and I'll move the downloading code from my build.rs to runtime and only have to download the sys file.

If there's a way to prevent the binary from crashing without the DLL file immediately then the downloading of the DLL file could also be handled in runtime (maybe with a download manager?) but for now, it crashes before any execution without the DLL, but not the sys file.

from windivert-rust.

Rubensei avatar Rubensei commented on June 12, 2024

For now I'm just gonna use my fork...

I've just uploaded the WIP changes to feature/static-link, you can add the dependency via git instead of crates.io. It should work with msvc compiler, the gnu part needs more work.

... just so I don't have to figure out a way to set an env or set it globally ...

Most IDE allow for setting env vars for the current project quite easily. Special mention to vscode that allows to set it up for both the terminal and rust-analyzer

If there's a way to prevent the binary from crashing without the DLL file immediately then the downloading of the DLL file could also be handled in runtime

Although the sys file it's only required at runtime, the dll it's required for linking in the build process so it's neither possible nor something I'd consider adding, not even for the sys file.

from windivert-rust.

ShayBox avatar ShayBox commented on June 12, 2024

Special mention to vscode that allows to set it up for both the terminal and rust-analyzer

I wasn't aware you could do that, only that you could set them via tasks, very useful!

The feature works for me, though without the sys file the error no longer says the SYS missing error, just Error: The system cannot find the path specified. (os error 3) which may not be as helpful.

EDIT: Nevermind, this was an unrelated issue, I needed to delete HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinDivert

This is exactly what I needed 😄 Thank you

from windivert-rust.

Rubensei avatar Rubensei commented on June 12, 2024

I'll keep this open until I finish the work on the static feature.

When there is a crash and the service does not properly stop, you can use sc stop WinDivert from an elevated command line to do it manually.

I still cannot decide whether or not I should add a Drop implementation that closes the handle since it is a fallible function and any error in drop has to be silently ignored.

from windivert-rust.

ShayBox avatar ShayBox commented on June 12, 2024

I found that somewhere else but the windivert service doesn't exist for me

EDIT: Using uninstall can cause the driver to break and require a reboot to work again for some reason, I just let my program crash and it always works again the next time I start it without uninstalling as long as the sys file is in the same location

from windivert-rust.

ShayBox avatar ShayBox commented on June 12, 2024

(Unrelated to static linking)
You wouldn't happen to have an example or library that could help parse HTTP packets, or a resource/video on how to do that, I'm having trouble using httparse/http_types to parse packets, I'm trying to sniff http/https json data requests/responses.

use smoltcp::wire::{IpProtocol, IpVersion, Ipv4Packet, TcpPacket};
use windivert::prelude::*;

fn main() {
    let filters = [
        "ip",
        "tcp",
        "tcp.PayloadLength > 1",
        "(tcp.DstPort == 80 || tcp.DstPort == 443)",
    ];

    let filter = filters.join(" && ");
    let priority = 0;
    let flags = WinDivertFlags::new().set_sniff();

    let windivert = match WinDivert::network(&filter, priority, flags) {
        Ok(windivert) => Ok(windivert),
        Err(error) => match &error {
            WinDivertError::Open(WinDivertOpenError::MissingSYS) => {
                download_and_extract_driver().expect("Failed to get driver");
                WinDivert::network(&filter, priority, flags)
            }
            _ => Err(error),
        },
    }
    .expect("Failed to initialize WinDivert<NetworkLayer>");

    loop {
        // ? I don't know what to set max as for buffer or packet count...
        const MAX: usize = u8::MAX as usize;

        let mut buffer = [0; MAX];
        while let Ok(packets) = windivert.recv_ex(Some(&mut buffer), MAX) {
            for packet in packets {
                // Theoretically these filters shouldn't be printing anything
                // Because WinDivert is pre-filtering the same things
                let payload = packet.data;
                let Ok(ip_version) = IpVersion::of_packet(&payload) else {
                    eprintln!("Failed to parse IpVersion");
                    continue;
                };
                if ip_version != IpVersion::Ipv4 {
                    eprintln!("Filtered out non-ipv4 version: {ip_version}");
                    continue;
                }

                let Ok(ipv4_packet) = Ipv4Packet::new_checked(&payload) else {
                    eprintln!("Failed to parse Ipv4Packet");
                    continue;
                };

                let protocol = ipv4_packet.next_header();
                if protocol != IpProtocol::Tcp {
                    eprintln!("Filtered out non-tcp protocol: {protocol}");
                    continue;
                }

                let payload = ipv4_packet.payload();
                let Ok(tcp_packet) = TcpPacket::new_checked(payload) else {
                    eprintln!("Failed to parse TcpPacket");
                    continue;
                };

                let payload = tcp_packet.payload();
                let payload_length = payload.len();
                if payload_length <= 1 {
                    eprintln!("Filtered out empty tcp payload: {payload_length}");
                    continue;
                }

                let destination_port = tcp_packet.dst_port();
                if ![80, 443].contains(&destination_port) {
                    eprintln!("Filtered out non-http destination port: {destination_port}");
                    continue;
                }

                println!("Payload: {payload:?}");
                // TODO: Parse HTTP?
            }
        }
    }
}

from windivert-rust.

Related Issues (8)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.