1 // Compile with /home/llozano/local2/proj/vtable/gcc-root/usr/local/bin/g++ -m32 -fvtable-verify=std -fpic -rdynamic -Wl,-R,/home/llozano/local2/proj/vtable/gcc-root/usr/local/lib32:./lib32 -I/home/llozano/local2/proj/vtable/vt2/gcc-4_6-mobile-vtable-security//libstdc++-v3/libsupc++ temp_deriv.cc -O0 -ldl -lpthread -Wl,--whole-archive,-lvtv_init,--no-whole-archive,-z,relro -DTPID=0 -g
2 // Look at assembly with: objdump -drl a.out
7 extern "C" int printf(const char *, ...);
9 static int counter
= 0;
11 template <int i
> struct base
13 virtual void inc() { counter
+= i
; }
16 template <int i
> struct derived
: base
<i
>
18 virtual void inc() { counter
+= (10*i
); }
21 // We don't use this class. It is just here so that the
22 // compiler does not devirtualize calls to derived::inc()
23 template <int i
> struct derived2
: derived
<i
>
25 virtual void inc() { counter
+= (20*i
); }
28 static base
<TPID
> * bp
= new base
<TPID
>();
29 static derived
<TPID
> * dp
= new derived
<TPID
>();
30 static base
<TPID
> * dbp
= new derived
<TPID
>();
32 // Given 2 pointers to C++ objects (non PODs), exchange the pointers to vtable
33 void exchange_vtptr(void * object1_ptr
, void * object2_ptr
)
35 void ** object1_vtptr_ptr
= (void **)object1_ptr
;
36 void ** object2_vtptr_ptr
= (void **)object2_ptr
;
37 void * object1_vtptr
= *object1_vtptr_ptr
;
38 void * object2_vtptr
= *object2_vtptr_ptr
;
39 *object1_vtptr_ptr
= object2_vtptr
;
40 *object2_vtptr_ptr
= object1_vtptr
;
47 exchange_vtptr(bp
, dp
);
48 exchange_vtptr(bp
, dp
);
49 exchange_vtptr(bp
, dbp
);
50 exchange_vtptr(bp
, dbp
);
56 assert(counter
== (TPID
+ 10*TPID
+ 10*TPID
));
58 prev_counter
= counter
;
59 exchange_vtptr(bp
, dp
);
60 bp
->inc(); // This one should succeed but it is calling the wrong member
61 assert(counter
== (prev_counter
+ 10*TPID
));
62 printf("Pass first attack!\n");
64 printf("TPDI=%d counter %d\n", TPID
, counter
);
65 printf("Pass second attack!\n");