A modular and blazing fast runtime security framework for the IoT, powered by eBPF.

Overview

Pulsar is a security tool for monitoring the activity of Linux devices at runtime, powered by eBPF.

The Pulsar core modules use eBPF probes to collect events from the kernel in a safe and efficient way. Pulsar events can be categorized in the four main following areas:

  • File I/O: I/O operations on disk and memory.
  • Network: data from the network stack.
  • Processes: processes information, including file execution and file opening.
  • System Activity: device activity, including system calls.

Pulsar is built with a modular design that makes it easy to adapt the core architecture to new use cases, create new modules or write custom rules.

Quickstart

Warning
A kernel 5.5 or higher with BPF and BTF enabled is required. Visit the official Pulsar website for the full requirements and installation options available.

To download and install Pulsar, run the following in your terminal:

curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/Exein-io/pulsar/main/pulsar-install.sh | sh

Launch the pulsar daemon in a terminal with administrator privileges:

pulsard

That's pretty much it. At this point Pulsar is actively monitoring the activity of all the target processes, and checking it against the set of security policies defined in the rules file. You can test this by triggering a threat event, for example running the following command in another terminal:

ln -s /etc/shadow /tmp/secret

In the pulsar terminal you should see something similar to:

[2023-02-07T14:29:09Z  THREAT  /usr/bin/ln (36267)] [rules-engine - { rule_name = "Create sensitive files symlink" }] File Link { source: /tmp/secret, destination: /etc/shadow, hard_link: false }

As you can see Pulsar identifies the previous command as a threat event.

How does it work?

Behind the scenes, when an application performs an operation, it gets intercepted at kernel level by the Pulsar BPF probes, turned into a unique event object and sent to the userspace. There, the Pulsar rule engine processes the event against the set of rules defined in the rules file and, if there is a match, it emits a new event, marked as a threat. Finally a logger module prints threat events to the terminal.

In the example above, the event produced matched the following rule:

- name: Create sensitive files symlink
  type: FileLink
  condition: (payload.destination IN ["/etc/shadow", "/etc/sudoers", "/etc/pam.conf", "/etc/security/pwquality.conf"] OR payload.destination STARTS_WITH "/etc/sudoers.d/" OR payload.destination STARTS_WITH "/etc/pam.d") AND payload.hard_link == "false"

Installation

(Recommended) Using the official installation script

The recommended approach to getting started with Pulsar is by using the official installations script. Follow the guide in the Quickstart section.

Use Pre-built Binaries

Another approach to install Pulsar is by using a pre-built binary. Binaries are available for the latest release. Use pulsar-exec for x86-64 (pulsar-exec-static for a static build) or pulsar-exec-static-aarch64 for AArch64 platform. Using there approach you also need to download and setup the helper scripts to have a more convenient way to start in daemon/cli mode.

Build from source

We do not recommend build Pulsar from source. Building from source is only necessary if you wish to make modifications. If you want to play with the source code check the Developers section of the documentation.

Resources

  • Read the docs: understand how to install and set up Pulsar.
  • Concepts: dive deep into Pulsar architecture and main concepts.
  • Tutorials: learn how to use Pulsar with practical examples.
  • Develop new eBPF modules: build new eBPF probes and integrate them into Pulsar through the modules system;
  • Roadmap: check out the plan for next Pulsar releases;
  • Support: join the Discord server for community support.

Contributing

If you're interested in contributing to Pulsar — thank you!

We have a contributing guide which will help you getting involved in the project. Also check the Developers section of the documentation for more information on Pulsar development.

Community

Join the Pulsar Discord server to chat with developers, maintainers, and the whole community. You can also drop any question about Pulsar on the official GitHub discussions or use the GitHub issues for feature requests and bug reports.

License

Pulsar is licensed under two licenses — Pulsar userspace code is licensed under APACHE-2.0. Pulsar eBPF probes are licensed under GPL-2.0.

Comments
  • feat: file logging

    feat: file logging

    File logging

    This PR is served for #39.

    Implementation (Optional)

    Following TODO placeholder left in the source code.

    I have

    • [x] run cargo fmt;
    • [x] run cargo clippy;
    • [x] run cargo testand all tests pass;
    • [x] linked to the originating issue (if applicable).
    opened by hnidoaht-101 11
  • [Bug]: Error getting full path of files created and deleted within nested mount points

    [Bug]: Error getting full path of files created and deleted within nested mount points

    Contact Details

    No response

    What happened?

    @MatteoNardi:

    Turns out the issue is not related to the kernel version, but to Archlinux. I reproduced the issue with another Archlinux machine running 5.15, which is the same version of my development Ubuntu 22.04 machine.

    Creating a file with the path /tmp/1/2/3/4/myfile emits an event with path /1/2/3/4/myfile, so I suppose it has something to do with some special behavior of the /tmp folder. For some reason, the kernel struct dentry's chain of d_parent we traverse for building the path, ends prematurely.

    Relevant log output

    #### Kernel/OS
    
    
    [vagrant@archlinux ~]$ uname -a
    Linux archlinux 5.17.1-arch1-1 #1 SMP PREEMPT Mon, 28 Mar 2022 20:55:33 +0000 x86_64 GNU/Linux
    

    Output

    test tests::unlink_file ... FAILED                           
    
    failures:                     
    
    ---- tests::file_name stdout ----                            
    [INFO  bpf_common::trace_pipe] Logging events from /sys/kernel/debug/tracing/trace_pipe                                    
    69581201284 1120 deleted /file_name_1                                                                                      
    69581219467 1120 created /file_name_1                                                                                      
    69581228087 1120 open /tmp/file_name_1 (33345)                                                                             
    
    69581219467 1120 created /file_name_1 (3/4)                                                                                
    - pid: 1120 (OK)              
    - timestamp: 69581190947 - 69581233481 (OK)                                                                                
    - event type: FsEvent :: FileCreated (OK)                                                                                  
    - filename: (FAIL)                                           
      |    found: StringArray { data: "/file_name_1" }                                                                         
      | expected: StringArray { data: "/tmp/file_name_1" }                                                                     
    
    thread 'tests::file_name' panicked at 'No event found matching results', /home/matteo/projects/pulsar-experiments/bpf_common/src/test_runner.rs:155:13   
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace                                              
    
    ---- tests::unlink_file stdout ----                          
    [INFO  bpf_common::trace_pipe] Logging events from /sys/kernel/debug/tracing/trace_pipe                                    
    70211704597 1120 deleted /unlink_file                                                                                      
    
    70211704597 1120 deleted /unlink_file (3/4)                                                                                
    - pid: 1120 (OK)              
    - timestamp: 70211693859 - 70211718252 (OK)                                                                                
    - event type: FsEvent :: FileDeleted (OK)                                                                                  
    - filename: (FAIL)                                           
      |    found: StringArray { data: "/unlink_file" }                                                                         
      | expected: StringArray { data: "/tmp/unlink_file" }                                                                     
    
    thread 'tests::unlink_file' panicked at 'No event found matching results', /home/matteo/projects/pulsar-experiments/bpf_common/src/test_runner.rs:155:13 
    
    
    failures:                     
        tests::file_name                                         
        tests::unlink_file                                       
    

    Code of Conduct

    • [X] I agree to follow this project's Code of Conduct
    bug 
    opened by JuxhinDB 5
  • Readme update / Installer

    Readme update / Installer

    Readme update / Installer

    • Readme revision
    • Introduce the install script
    • Change few doc sections in the source code
    • Fix doc broken links (some structures need to be public to be linked in the doc, but fields and constructors remain private)

    Closes #70

    I have

    • [x] run cargo fmt;
    • [x] run cargo clippy;
    • [x] run cargo testand all tests pass;
    • [x] linked to the originating issue (if applicable).
    opened by banditopazzo 4
  • Feature to only track container processes

    Feature to only track container processes

    Feature

    Since most use-cases are based on container applications, Pulsar should be able to filter and to track only container processes. Pulsar is already able to monitor and track container applications. It would be nice to filter them based on the container ID.

    Possible solution

    Previous Pulsar versions attempted to do this using cgroups. Also Tracee uses cgroups (https://github.com/aquasecurity/tracee/issues/255).


    Original issue author: @hdtrinh

    enhancement good first issue 
    opened by JuxhinDB 4
  • Test suite refactor

    Test suite refactor

    This PR is a tentative refactor of the test suite. Tests are split in a different binary, which can be invoked with sudo by using a xtask.

    Fixes https://github.com/Exein-io/pulsar/issues/3

    opened by MatteoNardi 3
  • [Bug]: failed on debian/bullseye64

    [Bug]: failed on debian/bullseye64

    Contact Details

    No response

    What happened?

    Test pulsar on debian/bullseye64, it failed.

    Relevant log output

    vagrant@bullseye:~$ curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/Exein-io/pulsar/main/pulsar-install.sh | sh
    info: downloading files
    info: installing files
    info: generating configuration
    info: basic rules
    info: cleaning
    info: installation complete
    vagrant@bullseye:~$ uname -a
    Linux bullseye 5.10.0-21-amd64 #1 SMP Debian 5.10.162-1 (2023-01-21) x86_64 GNU/Linux
    vagrant@bullseye:~$ sudo pulsard
    [2023-02-13T11:17:38Z INFO  pulsar::pulsard::daemon] Starting module process-monitor
    [2023-02-13T11:17:38Z INFO  pulsar::pulsard::daemon] Starting module file-system-monitor
    [2023-02-13T11:17:38Z WARN  bpf_common::feature_autodetect::lsm] LSM not supported: eBPF LSM programs disabled
    [2023-02-13T11:17:38Z ERROR pulsar::pulsard::module_manager] Module error in file-system-monitor: failed program load kprobe security_path_mknod
        
        Caused by:
            0: the BPF_PROG_LOAD syscall failed. Verifier output: number of funcs in func_info doesn't match number of subprogs
               verification time 25 usec
               stack depth 0+0
               processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
               
            1: Invalid argument (os error 22)
    [2023-02-13T11:17:38Z INFO  pulsar::pulsard::daemon] Starting module network-monitor
    [2023-02-13T11:17:38Z WARN  bpf_common::feature_autodetect::lsm] LSM not supported: eBPF LSM programs disabled
    [2023-02-13T11:17:38Z INFO  pulsar::pulsard::daemon] Starting module logger
    [2023-02-13T11:17:38Z INFO  pulsar::pulsard::daemon] Starting module rules-engine
    [2023-02-13T11:17:39Z INFO  pulsar::pulsard::daemon] Starting module desktop-notifier
    

    Code of Conduct

    • [X] I agree to follow this project's Code of Conduct
    bug 
    opened by b1tg 2
  • Make sending large eBPF events more memory efficient

    Make sending large eBPF events more memory efficient

    Make sending large eBPF events more memory efficient

    This fixes #73 by removing variable-length fields from the eBPF event payloads and adding them to a dynamic buffer, sent after the event.

    • eBPF buffer management code has been added to bpf-common/include/buffer.bpf.h
    • variable length fields have been replaced by indexes (start + len) of the buffer
      • struct buffer_index is used on the eBPF side
      • struct BufferIndex is used on the Rust side
    • Converting a C type to Event::Payload, now requires also the buffer. The IntoPayload trait was introduced.
    • We use bytes::Bytes for buffer management, this results in less data copying.
      • There's a copy when reading the PerfEvent (unavoidable with aya APIs)
      • There's a copy when converting the C-like struct to event::Payload
        • Ideally we could remove this by using Bytes inside event::Payload
      • We no longer make a copy of big buffers which are processed before being converted to Payload. For example the UDP message buffer, which is used for intercepting DNS, is copied only once, from kernel to user space. Previously it was copied 2 times.

    This was the simplest solution I could envision for #73.

    I have

    • [x] run cargo fmt;
    • [x] run cargo clippy;
    • [x] run cargo testand all tests pass;
    • [x] linked to the originating issue (if applicable).
    opened by MatteoNardi 2
  • Use bpf-helper `bpf_d_path()` when available

    Use bpf-helper `bpf_d_path()` when available

    The bpf-helper bpf_d_path, available since kernel 5.10, would be a better alternative to our path extraction code, as it would remove the MAX_COMPONENTS limitation.

    It only works with BTF enabled eBPF programs (kfuncs would be ok, kprobes would not) and a subset of LSM hooks. See https://github.com/torvalds/linux/blob/76f598ba7d8e2bfb4855b5298caedd5af0c374a8/kernel/trace/bpf_trace.c#L936-L947

    We should research if we can make use of it.

    enhancement 
    opened by MatteoNardi 1
  • Filter process-monitor events using `whitelist` and `targets`

    Filter process-monitor events using `whitelist` and `targets`

    Currently process-monitor monitors all system processes (which is necessary). Setting whitelist, whitelist_children or targets in the configuration affects only the other modules, which generate events only for those specific target processes (which is the desired behaviour).

    We should implement a filter on process-monitor events that makes us able to distinguish only target processes (and children) events. Ultimately, all process should be monitored, but only target process events should be shared over the event bus.

    enhancement feature 
    opened by hdtrinh 1
  • [Bug]: parse_version_signature error on WSL2

    [Bug]: parse_version_signature error on WSL2

    Contact Details

    No response

    What happened?

    parse_version_signature error on WSL2

    Relevant log output

    [2023-02-13T11:10:36Z WARN  bpf_common::program] Error identifying kernel version Invalid version_signature format: 5.15.79.1-microsoft-standard-WSL2. Assuming kernel 5.0.4
    

    Code of Conduct

    • [X] I agree to follow this project's Code of Conduct
    bug 
    opened by b1tg 1
  • Improve LSM support autodetection

    Improve LSM support autodetection

    Improve LSM autodetection by trying to load an example LSM program.

    • [x] split bpf-builder to its own crate because bpf-common would have needed to depend on itself at build-time.
    • [x] added lsm_supported to BpfContext in order to avoid repeating the time-consuming check.
    • [x] add a configuration field to pulsar for forcing the use of kprobes/lsm

    I have

    • [x] run cargo fmt;
    • [x] run cargo clippy;
    • [x] run cargo testand all tests pass;
    • [x] linked to the originating issue (if applicable).
    opened by MatteoNardi 1
  • Get user and group id related events

    Get user and group id related events

    Started to work on #97:

    • Added user and group id on fork event (using bpf_get_current_uid_gid())
    • Added hooks to intercept credentials change:
      • On LSM-supported kernels,task_fix_set*id calls are used
      • On kernel >= 5.10, we fall back on security_task_fix_set*id
      • On older kernels we fall back to commit_creds kprobe
    • Testing on architest virtual machines led me to discover some regression to to previous pull requests. I've fixed them and all tests are passing now.

    To completely fix #97, the only item left is to:

    • update process-tracker with the user id
    • add a mapping in process-tracker from user-id to username
    • put those into header on event generation

    Credential changes syscalls

    A small explanation on credentials-related system calls. User is changed with the setuid syscall, which invokes the LSM task_fix_setuid and calls commit_creds. The same for group changes: setgid leads to a call to task_fix_setgid and commit_creds.

    I have

    • [x] run cargo fmt;
    • [x] run cargo clippy;
    • [x] run cargo testand all tests pass;
    • [x] linked to the originating issue (if applicable).
    opened by MatteoNardi 0
  • Drop `lazy_static` usage and use `OnceCell`

    Drop `lazy_static` usage and use `OnceCell`

    Rust 1.70 now includes OnceCell, which should make our dependency on lazy_static unneeded. We should port our code to it.

    Possible reasons not to it: Rust 1.70 just came out and could take some time before being available on projects sticking to an older version (I'm thinking about Yocto)

    opened by MatteoNardi 0
  • bundle install script in the release

    bundle install script in the release

    Now in the readme we point directly to the install script in the main branch. this can be inconsistent with the files in latest, so it's better to have a dedicated script for every tag

    opened by banditopazzo 0
  • proposal: more ergonomic apis for modules

    proposal: more ergonomic apis for modules

    I find the modules start task function a bit strange, expecially the:

    loop {
        tokio::select! {
        r = shutdown.recv() => return r,
        _ = rx_config.changed() => ...
        msg = receiver.recv() => ...
    }
    

    at the current state, this is an obligated pattern modules should do.

    Another reason is that for developers is simpler to work with objects as it feels more natural.

    My proposal is to have something similar to this for the module trait:

    // module name
    pub struct Name2(pub String);
    
    // module semver
    pub struct Version2(pub i32);
    
    // needed by the upper level to decide if allocate a receiver or not
    pub enum OnEvent<'a> {
        Nothing,
        Do(EventHandler<'a>),
    }
    
    impl<'a> OnEvent<'a> {
        pub fn execute<F: 'a + FnMut() -> Result<(), Box<dyn std::error::Error>>>(f: F) -> Self {
            Self::Do(EventHandler(Box::new(f)))
        }
    }
    
    pub struct EventHandler<'a>(Box<dyn FnMut() -> Result<(), Box<dyn std::error::Error>> + 'a>);
    
    // context similar to the current to send events and errors
    pub struct Cx2 {}
    
    // raw module configuration
    pub struct ModuleConfig2 {}
    
    // event
    #[derive(Debug)]
    pub struct Event2 {}
    
    // module trait
    pub trait Module2: Sized {
        type Config: for<'a> TryFrom<&'a ModuleConfig2>;
    
        fn start(config: &Self::Config, cx: &Cx2) -> (Name2, Version2, Self);
        
        // default for producer only modules
        fn on_event<'a>(
            &'a mut self,
            config: &'a Self::Config,
            event: &'a Event2,
            cx: &'a Cx2,
        ) -> OnEvent<'a> {
            OnEvent::Nothing
        }
    
        fn on_cfg_change(
            &mut self,
            config: &Self::Config,
            cx: &Cx2,
        ) -> Result<(), Box<dyn std::error::Error>> {
            Ok(())
        }
    
        // default normal drop
        fn graceful_stop(self, cx: &Cx2) {}
    }
    

    and move the loop/select block to the upper level into the ModuleManager as it's the same for every module.

    The following lines are previews of how modules should look with new traits:

    mod producer1 {
        use pdk::*;
    
        struct MyProducerModuleConfig {
            file_path: String,
        }
    
        impl TryFrom<&ModuleConfig2> for MyProducerModuleConfig {
            type Error = String;
    
            fn try_from(value: &ModuleConfig2) -> std::result::Result<Self, Self::Error> {
                todo!()
            }
        }
    
        struct MyProducerModule {
            ebpf_probe: i32, // in reality Program type
        }
    
        impl Module2 for MyProducerModule {
            type Config = MyProducerModuleConfig;
    
            fn start(config: &Self::Config, cx: &Cx2) -> (Name2, Version2, Self) {
                let ebpf_probe = 0; // program_start(...)
                (
                    Name2("producer".to_string()),
                    Version2(666),
                    Self { ebpf_probe },
                )
            }
        }
    }
    
    mod consumer1 {
        use pdk::*;
    
        struct MyConsumerModuleConfig {
            file_path: String,
        }
    
        impl TryFrom<&ModuleConfig2> for MyConsumerModuleConfig {
            type Error = String;
    
            fn try_from(value: &ModuleConfig2) -> std::result::Result<Self, Self::Error> {
                todo!()
            }
        }
    
        struct MyConsumerModule {
            file_writer: i32,
        }
    
        impl Module2 for MyConsumerModule {
            type Config = MyConsumerModuleConfig;
    
            fn start(config: &Self::Config, cx: &Cx2) -> (Name2, Version2, Self) {
                let file_writer = 0;
                (
                    Name2("consumer".to_string()),
                    Version2(666),
                    Self { file_writer },
                )
            }
    
            fn on_event<'a>(
                &'a mut self,
                config: &'a Self::Config,
                event: &'a Event2,
                cx: &'a Cx2,
            ) -> OnEvent<'a> {
                OnEvent::execute(move || {
                    // self.file_writer.write(event);
                    todo!()
                })
            }
    
            fn graceful_stop(self, cx: &Cx2) {
                // file_writer.flush()
                // file_writer.close()
            }
        }
    }
    
    mod consumer2 {
        use pdk::*;
    
        struct MyEngineConfig {
            option1: bool,
        }
    
        impl TryFrom<&ModuleConfig2> for MyEngineConfig {
            type Error = String;
    
            fn try_from(value: &ModuleConfig2) -> std::result::Result<Self, Self::Error> {
                todo!()
            }
        }
    
        struct MyEngine {
            engine: i32,
        }
    
        impl Module2 for MyEngine {
            type Config = MyEngineConfig;
    
            fn start(config: &Self::Config, cx: &Cx2) -> (Name2, Version2, Self) {
                let engine = 0; //  = PulsarEngine::new(&config.rules_path, cx.get_sender())?;
                (
                    Name2("consumer2".to_string()),
                    Version2(666),
                    Self { engine },
                )
            }
    
            fn on_cfg_change(&mut self, config: &Self::Config, cx: &Cx2)-> Result<(), Box<dyn std::error::Error>> {
                //  self.engine = PulsarEngine::new(&config.rules_path, ctx.get_sender())?;
                Ok(())
            }
    
            fn on_event<'a>(
                &'a mut self,
                config: &'a Self::Config,
                event: &'a Event2,
                cx: &'a Cx2,
            ) -> OnEvent<'a> {
                OnEvent::execute(move || {
                    // println!("event consumed: {event:?}");
                    // engine.process(&event);
                    Ok(())
                })
            }
        }
    }
    

    Disclaimer: this code is not complete, but it should resemble what we will get in the end, signatures can be polished. it should compile apart from possible errors adapting to this issue.

    Note: maybe the type erasure on the handle function is not needed, even the EventHandler shim with the execute function, but it needs a full test.

    enhancement help wanted 
    opened by banditopazzo 0
  • Clean github workflows

    Clean github workflows

    Github workflow should be cleaned, notable things:

    • use cross even for x86 build in build.yaml for coherency with release workflow
    • improve release workflow using a matrix. steps should be sequential or we need to add a temporary storage where every parallel tasks should store the artifact before the final release creation with file uploads
    good first issue 
    opened by banditopazzo 0
Releases(v0.6.0)
Owner
Exein.io
Security of Things
Exein.io
Fox Ear is a Linux process behavior trace tool powered by eBPF

Fox Ear Fox Ear is a Linux process behavior trace tool powered by eBPF. Banner image by Birger Strahl on Unsplash. Features Log process and its subpro

Rui Li 77 Dec 5, 2022
Rust implementation of the Edge IoT framework

A Rust-based implementation of Edge-rs for the Raspberry Pi Pico Getting started For more details see the following article on getting started for get

Jim Hodapp 4 Apr 14, 2022
A Rust library for managing eBPF programs.

oxidebpf oxidebpf is a permissive licensed Rust library for managing eBPF programs. Motivation The motivation behind oxidebpf is to create a permissiv

Red Canary 92 Jan 1, 2023
🐝🦀🔥 An ebpf based CPU profiler written in Rust

profile-bee ?? ?? ?? Profile Bee is an eBPF based CPU profiler written in Rust for performance and efficiency. Aya is used for building the BPF progra

Joshua Koo 5 Dec 16, 2022
Blazing fast linter for JavaScript and TypeScript written in Rust

deno_lint A Rust crate for writing fast JavaScript and TypeScript linters. This crate powers deno lint, but is not Deno specific and can be used to wr

Deno Land 1.3k Dec 29, 2022
Command palette-style Git client for blazing-fast commits.

?? About Commit Commit is the world's simplest Git client. Open it with a keyboard shortcut, write your commit, and you're done! Commit will automatic

Miguel Piedrafita 190 Aug 18, 2023
Functional testing framework for AVR binaries, powered by simavr.

Functional testing framework for AVR binaries, powered by simavr. tl;dr get your microcontroller's firmware black-box-tested in seconds!

Patryk Wychowaniec 14 Nov 16, 2022
A 3dprinter/cnc firmware framework powered by rust embassy

Printhor: The highly reliable but not necessarily functional 3D printer firmware If you are using this product or like the project, please ★ this repo

Carlos Barrales 26 Nov 15, 2023
microtemplate - A fast, microscopic helper crate for runtime string interpolation.

microtemplate A fast, microscopic helper crate for runtime string interpolation. Design Goals Very lightweight: I want microtemplate to do exactly one

_iPhoenix_ 13 Jan 31, 2022
Ultralight, security-first service mesh for Kubernetes. Main repo for Linkerd 2.x.

Linkerd ?? Welcome to Linkerd! ?? Linkerd is an ultralight, security-first service mesh for Kubernetes. Linkerd adds critical security, observability,

Linkerd 9.2k Jan 1, 2023
supply-chain security for Rust

cargo-vet Note: cargo-vet is under heavy development and not quite ready for general use. Feel free to give it a try you're feeling adventerous — feed

Mozilla 289 Dec 23, 2022
Extensions for x64dbg written in Rust: Telescope and Unicorn powered disassembly

This is the library that extends x64dbg with new features: Telescope. It's basically recursive dereferencerer of memory view which looks at the pointe

null 18 Sep 11, 2022
TaurApp is a WhatsApp desktop client powered by Tauri and Rust.

TaurApp TaurApp is a WhatsApp desktop client powered by Tauri and Rust. TaurApp is an experimental client and is initially created to test out Tauri i

Eray Erdin (&mut self) 22 Mar 19, 2023
An asynchronous IO utilities crate powered by tokio.

An asynchronous IO utilities crate powered by tokio.

Harry 2 Aug 18, 2022
Web-wrapped Supabase desktop app for macOS, Windows & Linux powered by Tauri

Supabase Desktop App What is it? It's a cross-platform web-wrapped Supabase desktop app powered by Tauri. You can install it on your macOS, Windows (u

Abiel Zulio M 12 Jan 25, 2023
A GPT-powered daily newsletter bot, written in Rust

AI Newsie 1. Introduction Meet AI Newsie - your personalized GPT-powered bot that delivers daily newsletters tailored to your interests. The bot is po

null 5 May 7, 2023
Runtime dependency injection in Rust

This library provides an easy to use dependency injection container with a focus on ergonomics and configurability at the cost of runtime performance. For a more performance-oriented container, look for a compile-time dependency injection library.

TehPers 16 Nov 28, 2022
ImGUI runtime inspector

igri is a runtime inspector powered by imgui-rs

toyboot4e 2 Oct 30, 2021
Rust Kubernetes runtime helpers. Based on kube-rs.

kubert Rust Kubernetes runtime helpers. Based on kube-rs. Features clap command-line interface support; A basic admin server with /ready and /live pro

Oliver Gould 63 Dec 17, 2022