field-test.cc 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. #include <stdlib.h>
  6. extern "C" int printf(const char *, ...);
  7. static int counter = 0;
  8. int i = TPID;
  9. struct base
  10. {
  11. virtual void inc() { counter += i; }
  12. };
  13. struct derived: public base
  14. {
  15. virtual void inc() { counter += (10*i); }
  16. };
  17. // We don't use this class. It is just here so that the
  18. // compiler does not devirtualize calls to derived::inc()
  19. struct derived2: public derived
  20. {
  21. virtual void inc() { counter += (20*i); }
  22. };
  23. /*
  24. static base * bp = new base();
  25. static derived * dp = new derived();
  26. static base * dbp = new derived();
  27. */
  28. struct my_struct {
  29. base *bp;
  30. derived *dp;
  31. base *dbp;
  32. };
  33. typedef void * vtptr;
  34. vtptr get_vtptr(void * object_ptr)
  35. {
  36. vtptr * object_vtptr_ptr = (vtptr *)object_ptr;
  37. return *object_vtptr_ptr;
  38. }
  39. void set_vptr(void * object_ptr, vtptr vtp)
  40. {
  41. vtptr * object_vtptr_ptr = (vtptr *)object_ptr;
  42. *object_vtptr_ptr = vtp;
  43. }
  44. // Given 2 pointers to C++ objects (non PODs), exchange the pointers to vtable
  45. void exchange_vtptr(void * object1_ptr, void * object2_ptr)
  46. {
  47. vtptr object1_vtptr = get_vtptr(object1_ptr);
  48. vtptr object2_vtptr = get_vtptr(object2_ptr);
  49. set_vptr(object1_ptr, object2_vtptr);
  50. set_vptr(object2_ptr, object1_vtptr);
  51. }
  52. main()
  53. {
  54. int prev_counter;
  55. struct my_struct *my_obj = (struct my_struct *) malloc (sizeof (struct my_struct));
  56. my_obj->bp = new base();
  57. my_obj->dp = new derived ();
  58. my_obj->dbp = new derived ();
  59. counter = 0;
  60. my_obj->bp->inc();
  61. my_obj->dp->inc();
  62. my_obj->dbp->inc();
  63. assert(counter == (TPID + 10*TPID + 10*TPID));
  64. prev_counter = counter;
  65. printf("before ex bp vptr=%x dp vptr=%x\n", get_vtptr(my_obj->bp), get_vtptr(my_obj->dp));
  66. exchange_vtptr(my_obj->bp, my_obj->dp);
  67. printf("after ex bp vptr=%x dp vptr=%x\n", get_vtptr(my_obj->bp), get_vtptr(my_obj->dp));
  68. my_obj->bp->inc(); // This one should not abort but it is calling the wrong member
  69. assert(counter == (prev_counter + 10*TPID));
  70. printf("Pass first attack! Expected!\n");
  71. printf("TPDI=%d counter %d\n", TPID, counter);
  72. my_obj->dp->inc();
  73. printf("Pass second attack! SHOULD NOT BE HERE!\n");
  74. printf("TPDI=%d counter %d\n", TPID, counter);
  75. exit(1);
  76. }