temp_deriv2.cc 1.9 KB

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