Practice 1 (Understanding Local Stack)
In the following code, the main function calls add() function, which takes two integers. The add()function calculates the sum of the two integers and display it. When the function add() is called, the function (thread) is allocated with a local stack memory.
Your task is to find the contents of the local stack from the bottom of the stack. Modify the following code to display the contents of add()'s local stack, and find out the return address, to which the program control will return when add() exits.
#include <iostream>
#include <string>
using namespace std;
void add(int, int);
int main(){
add(1, 2);
return 0;
}
void add(int a, int b) {
int c = a + b;
cout << "Sum is : " << c << endl;
}
Sample Output
Sum is :3
---------------------
address | long var
---------------------
c003f914| 00000003 <---- local variable c
c003f918| 00000002
c003f91c| 00000001
c003f920| 00000000
c003f924| 00000000
c003f928| c003f948 <---- ebp
c003f92c| 00041b01 <---- return address
c003f930| 00000001 <---- 1st argument
c003f934| 00000002 <---- 2nd argument
c003f938| c003f960
c003f93c| 00000001
c003f940| 00000002
c003f944| 00000000
c003f948| c003f964
c003f94c| 00041ac5
-----------------------------------------
Note: You might want to turn off runtime checking on your code. Go to Project -> <ProjectName> Properties -> Configuration Properties -> C/C++ -> Basic Runtime Checks and turn it to Default.
Practice 2 (Understanding Local Stack)
Now, add the following code (or your own) to the above code.
void boo(){
cout << endl << "Boo!" << endl;
}
Then, when main() calls add() function, just before add() function exit, jump to boo() function to display "Boo!". However, do not explicitly call boo() function from add() function.
You should achieve this by replacing add() function's return address with the function pointer of boo().
Note: You might want to turn off runtime checking on your code. Go to Configuration Properties -> C/C++ -> Basic Runtime Checks and turn it to Default.
Practice 3 (Understanding Local Stack)
Modify you Practice3 code so that it runs correctly as a both 32 bit and 64 bit application.
Practice 4 (adv) (Understanding vtable)
Now, consider the following code. The main() function creates instances of MyClass and NewClass, and calls add() function.
Your task is to find out the contents of "virtual function table" (vtable) of both MyClass and NewClass objects, and call one of these virtual functions at the end of add() function by manipulating the return address of the add() function.
Note: In VC++ implementation, a vtable pointer is named __vfptr. However, this pointer may not be assessible directly from your code. Another way of obtaining it is via the first 4 or 8 bytes of an object.
struct MyClass {
virtual void myVfunc() {
cout << "MyClass::myVfunc()" << endl;
}
};
struct NewClass : public MyClass {
virtual void myVfunc() {
cout << "NewClass::myVfunc()" << endl;
}
};
void add(int a, int b) {
int c = a + b;
cout << "Sum is : " << c << endl;
}
int main() {
MyClass foo;
NewClass bar;
add(1, 2);
return 0;
}