在某些情况下,攻击者可以通过修改内存甚至函数指针来执行任意代码。为了减少这类攻击的影 响,函数指针应该在运行时进行加密,并在执行程序时才进行解密。
对于考虑对函数指针进行加密的情况,示例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, 那么将会返回非法的指针并且会导致程序崩溃。但是,与给攻击者提供执行任意代码的能力相比,这种情况的安全风险更低。