Skip to main content
added 584 characters in body
Source Link
Guntram Blohm
  • 13k
  • 2
  • 22
  • 33

So,so (assuming pointers and integers are all 4 bytes), the vtable is at offset 0, a at 4, b at 8 and c at 12.

The entries at offset 0 and 4 (again, assuming 4 byte integers/pointers) are the parameterless constructor and destructor function of the class. The, the rest is a mix of variables and methods in the order they appear in the class definition. Of course, this is horribly inefficient, because the compiler has to initialize every class method whenever an object is instantiated, instead of just setting one pointer to the vtable.

TL;DR: In most cases, the vtable pointer is the first element of the class structure, but you really need to know which compiler was used and which conventions this compiler has.

Another thing - you talk about a "vtable overflow" in your original post. Your "normal" exploit doesn't overflow a vtable; the vtables are pre-initialized when your program starts, and (normally) never ever change. To write an exploit, you would either:

  1. use a buffer overflow to modify a function pointer in a vtable, so the next time the class method gets called, your code is executed instead
  2. use a buffer overflow to modify the vtable pointer of a class instance, so the next time this class instance executes a method, your vtable is used instead of the other one.

As vtables normally don't change, and may even be placed in a read-only memory segment by the compiler, your normal exploit ignores 1. and uses 2.

So, (assuming pointers and integers are all 4 bytes), the vtable is at offset 0, a at 4, b at 8 and c at 12.

The entries at offset 0 and 4 (again, assuming 4 byte integers/pointers) are the parameterless constructor and destructor function of the class. The rest is a mix of variables and methods in the order they appear in the class definition. Of course, this is horribly inefficient, because the compiler has to initialize every class method whenever an object is instantiated, instead of just setting one pointer to the vtable.

TL;DR: In most cases, the vtable pointer is the first element of the class structure, but you really need to know which compiler was used and which conventions this compiler has.

so (assuming pointers and integers are all 4 bytes), the vtable is at offset 0, a at 4, b at 8 and c at 12.

The entries at offset 0 and 4 (again, assuming 4 byte integers/pointers) are the parameterless constructor and destructor function of the class, the rest is a mix of variables and methods in the order they appear in the class definition. Of course, this is horribly inefficient, because the compiler has to initialize every class method whenever an object is instantiated, instead of just setting one pointer to the vtable.

TL;DR: In most cases, the vtable pointer is the first element of the class structure, but you really need to know which compiler was used and which conventions this compiler has.

Another thing - you talk about a "vtable overflow" in your original post. Your "normal" exploit doesn't overflow a vtable; the vtables are pre-initialized when your program starts, and (normally) never ever change. To write an exploit, you would either:

  1. use a buffer overflow to modify a function pointer in a vtable, so the next time the class method gets called, your code is executed instead
  2. use a buffer overflow to modify the vtable pointer of a class instance, so the next time this class instance executes a method, your vtable is used instead of the other one.

As vtables normally don't change, and may even be placed in a read-only memory segment by the compiler, your normal exploit ignores 1. and uses 2.

A few cosmetic changes (nothing that worth mentionning)
Source Link
perror
  • 19.2k
  • 29
  • 87
  • 150

soSo, (assuming pointers and integers are all 4 bytes), the vtable is at offset 0, a at 4, b at 8 and c at 12.

The entries at offset 0 and 4 (again, assuming 4 byte integers/pointers) are the parameterless constructor and destructor function of the class, the. The rest is a mix of variables and methods in the order they appear in the class definition. Of course, this is horribly inefficient, because the compiler has to initialize every class method whenever an object is instantiated, instead of just setting one pointer to the vtable.

so (assuming pointers and integers are all 4 bytes), the vtable is at offset 0, a at 4, b at 8 and c at 12.

The entries at offset 0 and 4 (again, assuming 4 byte integers/pointers) are the parameterless constructor and destructor function of the class, the rest is a mix of variables and methods in the order they appear in the class definition. Of course, this is horribly inefficient, because the compiler has to initialize every class method whenever an object is instantiated, instead of just setting one pointer to the vtable.

So, (assuming pointers and integers are all 4 bytes), the vtable is at offset 0, a at 4, b at 8 and c at 12.

The entries at offset 0 and 4 (again, assuming 4 byte integers/pointers) are the parameterless constructor and destructor function of the class. The rest is a mix of variables and methods in the order they appear in the class definition. Of course, this is horribly inefficient, because the compiler has to initialize every class method whenever an object is instantiated, instead of just setting one pointer to the vtable.

Source Link
Guntram Blohm
  • 13k
  • 2
  • 22
  • 33

This is compiler dependent - the compiler may place the vtable wherever it wants to, as long as it does it consistently. However, in most cases, the vtable pointer is the first element (at offset 0) of the generated structure.

class test {
    int a;
    int b;
    test()          { ...; }
    ~test()         { ...; }
    void somefunc() { ...; }
    int c;
}

would use this memory layout for the class:

+----------------+               +--------------+
|  vtable        | ------------> | test         |
+----------------+               +--------------+
|  a             |               | ~test        |
+----------------+               +--------------+
|  b             |               | somefunc     |
+----------------+               +--------------+
|  c             |
+----------------+

so (assuming pointers and integers are all 4 bytes), the vtable is at offset 0, a at 4, b at 8 and c at 12.

Note that not all compilers use this convention. For example, the Watcom C++ 386 compiler didn't use a vtable at all, but mixed the function pointers with data. (I know this case because i once disassembled a game that was compiled with Watcom 20 years ago. Not that i expect you to ever see this kind of layout in a modern compiler, just to provide an example that it can be different):

+----------------+
|  test          |
+----------------+
|  ~test         |
+----------------+
|  a             |
+----------------+
|  b             |
+----------------+
|  somefunc      |
+----------------+
|  c             |
+----------------+

The entries at offset 0 and 4 (again, assuming 4 byte integers/pointers) are the parameterless constructor and destructor function of the class, the rest is a mix of variables and methods in the order they appear in the class definition. Of course, this is horribly inefficient, because the compiler has to initialize every class method whenever an object is instantiated, instead of just setting one pointer to the vtable.

TL;DR: In most cases, the vtable pointer is the first element of the class structure, but you really need to know which compiler was used and which conventions this compiler has.