先打印出某個地址,然後阻塞(getchar())進程,查一下進程的 id,然後執行Linux 命令pmap {pid}
查看進程的空間佈局(MAC 使用vmmap {pid}
),將之前打印的地址對應到某一段。
using namespace std;
#define FUCK(x) cout << (#x) << ": " << x << endl<< endl;
#define FUCKK(x, y) cout << (#x) << ": " << x << endl << (#y) << ": " << y << endl<< endl;
#define FUCKKK(x, y, z) cout << (#x) << ": " << x << endl << (#y) << ": " << y << endl << (#z) << ": " << z << endl<< endl;
class A {
void virtual f(){}
};
class B : A{};
void f() {}
int main()
{
B a;
void *vptr = *(void**)&a;
void *vf = **(void***)&a;
int b = 10;
int *p = new int(10);
FUCKK(&b, p)
FUCKK(vptr, vf)
FUCK((void*)f)
getchar();
return 0;
}
可以看到
- &b 是局部變量,對應倒數第 4 個段(stack)權限是可讀可寫
- p是堆變量,對應第六個段,也是可讀可寫
- 虛函數表vptr在第 4 個段,只讀
- 虛函數vf和普通函數f 都在第 2 個段,可讀可執行。