在某些情況下,攻擊者可以通過修改內存甚至函數指針來執行任意代碼。為了減少這類攻擊的影 響,函數指針應該在運行時進行加密,并在執行程序時才進行解密。
對于考慮對函數指針進行加密的情況,示例1給出了不規范用法(C/C++ ??語言)示例。示例2給 出了規范用法(C/C++ ??語言)示例。
示例1:int(*log ?fn)(const ???char ???*,..)= ???printf;/*..*/log ?fn("foo");
這個不規范的代碼示例將 printf()函 數 賦 給 log fn 函數指針,并且它能夠分配在棧的數據段里。
如果允許攻擊者修改 log fn 函數指針,則將出現可攻擊點,例如緩沖區溢出或者內存任意寫入。
攻擊者可能用本地的任意函數覆蓋 printf的 值 。
示例2(Windows):#include<Windows.h)void ??* ??log ?fn ??=EncodePointer(printf);/*.. ?*/int(*fn)(const fn("foo");Microsoftchar ????,.)=(int(*)(const ?????????????????char ????,.))DecodePointer(log ?fn);
Windows提供了EncodePointer()和DecodePointer()函數對指針進行加密和解密,確保只對給定的程序調用。
注意,DecodePointer()沒有返回成功或者失敗。如果攻擊者能夠重寫指針包括 log fn, 那么將會返回非法的指針并且會導致程序崩潰。但是,與給攻擊者提供執行任意代碼的能力相比,這種情況的安全風險更低。