This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ping] Port of VTV for Cygwin and MinGW


Ping for https://gcc.gnu.org/ml/gcc-patches/2014-08/msg02559.html

Also added Caroline Tice, as libvtv maintainer, to cc and attached
virtual_func_test_min_UAF.cpp, which I forgot in the original mail.

Patrick

On 28.08.2014 13:03, Patrick Wollgast wrote:
> This patch contains a port of VTV -fvtable-verify=std for Cygwin and MinGW.
> 
> Since weak symbols on Windows and Linux are implemented differently, and
> VTV should have the possibility to be switched on and off, the structure
> of the feature had to be modified.
> On Linux libstdc++ contains the weak stub functions of VTV. For Cygwin
> and MinGW they have been removed, due to the difference of weak symbols.
> On Linux and on Windows libstdc++ itself gets build with
> -fvtable-verify=std. Since libvtv gets build after libstdc++, and
> libstdc++ doesn't contain the stub functions any more, 'undefined
> reference' errors are thrown during linking of libstdc++. To prevent
> these errors during the linking process a libvtv-0.dll gets build from
> the stub functions before libstdc++-6.dll is linked.
> At the end of the build process two VTV dlls have been build. One is
> called libvtv-0.dll, containing the real functions, the other is called
> libvtv_stubs-0.dll, containing the stub functions. Depending on whether
> libvtv-0.dll is first found in the dll search path or
> libvtv_stubs-0.dll, renamed to libvtv-0.dll, the real functions or the
> stub functions are used.
> 
> Testing:
> The test builds were configured the following way:
> Linux 64bit (from patched and unpatched trunk):
> /path/to/configure --prefix=/prefix/gcc-vtv-bin-64
> --enable-libstdcxx-threads --enable-vtable-verify=yes
> MinGW 32bit cross compiled:
> /path/to/configure --target=i686-w64-mingw32
> --prefix=/prefix/mingw-vtv-bin-32 --with-gnu-ld --with-gnu-as
> --enable-fully-dynamic-string --disable-multilib
> --enable-libstdcxx-threads --enable-vtable-verify=yes
> MinGW 64bit cross compiled:
> /path/to/configure --target=x86_64-w64-mingw32
> --prefix=/prefix/mingw-vtv-bin-64 --with-gnu-ld --with-gnu-as
> --enable-fully-dynamic-string --disable-multilib
> --enable-libstdcxx-threads --enable-vtable-verify=yes
> Cygwin 64bit:
> /path/to/configure --enable-languages=c,c++ --enable-libstdcxx-threads
> --enable-vtable-verify=yes
> 
> At Linux the patched and unpatched version resulted in the same number
> of passed tests with 'make check-target-libvtv'.
> 
> Since MinGW was cross compiled the test cases couldn't be built and run
> with 'make check-target-libvtv'. Therefore they were built with the
> attached makefiles and tested afterwards on Windows 7 64bit. Some test
> cases contain Linux specific parts and weren't tested. See the makefiles
> for further information. Additionally virtual_func_test_min_UAF.cpp was
> also built and tested. All built tests passed.
> 
> Cygwin was just tested on gcc 4.9.0, because the current trunk isn't
> building for me. Even the clean trunk without the patch attached to this
> mail. On Cygwin with gcc 4.9.0 VTV worked.
> 
> Besides the test cases Botan was also built and tested (gcc 4.9.0) with
> MinGW 32bit and VTV.
> 
> regards
> 

-- 
Beste GrÃÃe,
Patrick
#include<iostream>
#include<stdio.h>

/*
 * Demonstrates an use after free c++ internally by deleting an object
 * and resetting its vtable pointing to legitimate functions
 */

// set pointer size and integer size dependent on architechture
#if __x86_64__
    /* 64-bit */
    const char* arch = "x86_64";
    int ptrSize = 8;
    typedef long long myInt;    // 8 byte
#else
    /* 32-bit */
    const char* arch = "x86";
    int ptrSize = 4;
    typedef int myInt;          // 4 byte
#endif
//

using namespace std;


// BASE CLASS
class Addition{
    protected:
        // member variables
        int s1,s2;
    public:
        // virtual member function will be implemented in derived class
        virtual int add(int a,int b){
        };
        int i;
};
//

// inherit new class
class Add: public Addition{
    public:
        // constructor:
        /*
        Add(int a, int b){
            s1 = a;
            s2 = b;
        };
        */
        void setvals(int a, int b){
            s1 = a;
            s2 = b;
        }
        // implement virtual function
        virtual int TRIGGER(){
            cout<<s1 + s2<<"\n";
        };
        int j;
};
//

// use this function in vtable which will be injected
void inject(){
    printf("%s\n","I've been executed");
}

int main(){

    printf("We're on a %s architecture\n\n",arch);

    // create object of inherited class
    //Add* A = new Add(4,5);
    Add* A = new Add;       //heap allocation happens here
    A->setvals(4,5);


    // add attributes
    A->i = 6;
    A->j = 7;

    // get vtable address
    myInt vtablePTR = NULL;
    vtablePTR = *((myInt*)A);

    printf("vtable: %.16x\n", vtablePTR);
    //function 1
    printf("%.16x : %.16x\n", vtablePTR, *((myInt*)vtablePTR));
    //function 2
    printf("%.16x : %.16x\n", vtablePTR + ptrSize, *((myInt*)(vtablePTR + ptrSize)));

    // call instantiated virtual function (legitimate)
    A->TRIGGER();

    // FREE OBJECT !
    delete A;
    //A = NULL;     // this prevents use after free

    // get objects address as it is still valid
    myInt* ObjPTR = (myInt*)A;

    // let object point to old vtable (inject old vtable)
    *ObjPTR = vtablePTR;

    // NOT legitimate
    A->TRIGGER();

    myInt vtable_func = (myInt)inject;

    // create new vtable
    myInt vtable_new[2] = {vtable_func, vtable_func};

    // let object point to new vtable (inject new vtable)
    *ObjPTR = (myInt)vtable_new;

    // USE AFTER FREE (execute injected function in vtable)
    A->TRIGGER();

    __asm__(
        "nop;"
        "nop;"
        "nop;"
    );


   // USE AFTER FREE with data members
    printf("%i %i\n", A->i, A->j);

}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]