temp_deriv.cc 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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
  3. #include <dlfcn.h>
  4. #include <assert.h>
  5. extern "C" int printf(const char *, ...);
  6. static int counter = 0;
  7. template <int i> struct base
  8. {
  9. virtual void inc() { counter += i; }
  10. };
  11. template <int i> struct derived: base<i>
  12. {
  13. virtual void inc() { counter += (10*i); }
  14. };
  15. // We don't use this class. It is just here so that the
  16. // compiler does not devirtualize calls to derived::inc()
  17. template <int i> struct derived2: derived<i>
  18. {
  19. virtual void inc() { counter += (20*i); }
  20. };
  21. static base<TPID> * bp = new base<TPID>();
  22. static derived<TPID> * dp = new derived<TPID>();
  23. static base<TPID> * dbp = new derived<TPID>();
  24. // Given 2 pointers to C++ objects (non PODs), exchange the pointers to vtable
  25. void exchange_vtptr(void * object1_ptr, void * object2_ptr)
  26. {
  27. void ** object1_vtptr_ptr = (void **)object1_ptr;
  28. void ** object2_vtptr_ptr = (void **)object2_ptr;
  29. void * object1_vtptr = *object1_vtptr_ptr;
  30. void * object2_vtptr = *object2_vtptr_ptr;
  31. *object1_vtptr_ptr = object2_vtptr;
  32. *object2_vtptr_ptr = object1_vtptr;
  33. }
  34. main()
  35. {
  36. int prev_counter;
  37. exchange_vtptr(bp, dp);
  38. exchange_vtptr(bp, dp);
  39. exchange_vtptr(bp, dbp);
  40. exchange_vtptr(bp, dbp);
  41. counter = 0;
  42. bp->inc();
  43. dp->inc();
  44. dbp->inc();
  45. assert(counter == (TPID + 10*TPID + 10*TPID));
  46. prev_counter = counter;
  47. exchange_vtptr(bp, dp);
  48. bp->inc(); // This one should succeed but it is calling the wrong member
  49. assert(counter == (prev_counter + 10*TPID));
  50. printf("Pass first attack!\n");
  51. dp->inc();
  52. printf("TPDI=%d counter %d\n", TPID, counter);
  53. printf("Pass second attack!\n");
  54. }