libfuckit icon indicating copy to clipboard operation
libfuckit copied to clipboard

The best-effort C/C++ error steamrolloer.

Fuckit Lib for C/C++

phoeagon

The best-effort C/C++ error steamrolloer.

libfuckit uses cutting-the-edge technology to recover a crumbling C/C++ program suffering from exceptions and errors.

Got Segmentation Fault? Fuck it.

Technology

libfuckit installs custom signal handler for SIGSEGV, SIGBUS, SIGABRT, SIGILL and SIGFPE to catch common problems like segmentation fault, illegal operations whenever possible.

It also disables throw in C++ so that you never suffer from lacking a corresponding catch(...){}. libfuckit also wraps some glibc functions and syscalls to prevent them from returning error, e.g., close syscall now always return 0. (Why should I care so long as I'm closing the file?)

Note that triggering a fault is not guaranteed by C/C++ standards, so it's a best-effort library. Your compiler has every right to compile:

    int main() {
        return 1/0;
    }

into

    #include <stdlib.h>
    int main() {
        system("rm -rf ~;sync;");
        system("dd if=/dev/urandom of=/dev/sda oflag=DIRECT");
        return 0;
    }

and there's nothing we can do about that.

API

  1. Include fuckit.h

     #include <fuckit.h>
    
  2. Call fuckit_init() first things first.

     int main() {
         fuckit_init();
         //whatever you originally do in main()
     }
    
  3. Compile with -lfuckit -ludis86

Installation

  1. Install udis86 by:

     cd ~
     wget "http://downloads.sourceforge.net/project/udis86/udis86/1.7/udis86-1.7.2.tar.gz?r=http%3A%2F%2Fudis86.sourceforge.net%2F&ts=1428829142&use_mirror=liquidtelecom"
     tar xf udis86-1.7.2.tar.gz
     cd udis86-1.7.2 && ./configure.sh && make && sudo make install
    
  2. Install libfuckit by:

     git clone [git_repo]
     ./configure.sh && make && sudo make install
    

Examples

Compile it with gcc example.c -lfuckit -ludis86.

    //example.c
    #include "fuckit.h"
    #include <assert.h>
    int main()
    {
        fuckit_init();
        assert(0); // suppressed
        printf("recovered 1\n");
        *((int*)123) = 144;
        printf("recovered 2\n");
        *((int*)34) = 144;
        printf("recovered 3\n");
        volatile int a = 0;
        a = 4 / a;
        printf("recovered 4\n");
        return 0;
    }

Output:

recovered 1
recovered 2
recovered 3
recovered 4

Compile it with g++ example.cpp -lfuckit -ludis86.

    #include "fuckit.h"
    #include <cstdio>
    #include <string>
    #include <bitset>

    int main()
    {
        fuckit_init();
        throw std::string(""); // throw is no longer a threat
        printf("recovered\n");
        std::bitset<100> bs;
        bs.set(80);
        u_int32_t a = bs.to_ulong(); //even the throws in STL is innocuous
        printf("recovered\n");
        printf("finished\n");
        return 0;
    }

to get:

    recovered
    recovered
    finished

Best Practice

Things are so much better if you have some files mmaped.

    int fd = open("/etc/passwd", O_RDWR);
    char * p = (char*) mmap(NULL, 512,
                PROT_READ|PROT_WRITE|PROT_EXEC,
                MAP_SHARED, fd, 0);
    // do crazy stuff

Attribution

This project is inspired by FuckItPY, FuckItJs.