为什么C编译器没有一个选项(我说的是选项,有时候你不想这样做)来转换这样的代码:
C编译器对于局部变量和全局变量的内存布局信息是否足够丰富,能否在编译时或运行时插入代码,建立一个内存位置和长度的数据库,并对于任何使用strcpy、memcpy、memset等函数或者类似于*ch1 = * ch2这样赋值操作的代码进行检查,确保内存访问不越界?我认为这种方法可能无法完全覆盖所有情况,并且会带来一定的性能损失,但这个功能可以通过开关或针对代码的某些行或片段进行重新编译来解决。这有点像valgrind,但更好,因为它利用了编译器的帮助,而不仅仅依靠二进制文件并只检查堆栈。
甚至可以将checkPtr API提供给开发人员,以便自己编写strcpy等函数。
char a1[8];
int main( int argc, char *argv[] )
{
char a2[16];
char *p = (char *)malloc( 24 );
int argv1_len = strlen( argv[1] );
memcpy( a1, argv[1], argv1_len );
memcpy( a2, argv[1], argv1_len );
memcpy( p, argv[1], argv1_len );
return 0;
}
转换为:
char a1[8];
addAddr( a1, sizeof( a1 ) ); // build database of addresses and their lengths
int main( int argc, char *argv[] )
{
char a2[16];
addAddr( a2, sizeof( a2 ) );
char *p = (char *)malloc( 24 );
int argv1_len = strlen( argv[1] );
addAddr( p, 24 );
ptrCheck( a1, argv1_len ); // exit if argv1_len > size of a1
memcpy( a1, argv[1], argv1_len );
ptrCheck( a2, argv1_len );
memcpy( a2, argv[1], argv1_len );
ptrCheck( p, argv1_len );
memcpy( p, argv[1], argv1_len );
ptrCheck( p+5, argv1_len );
memcpy( p+5, argv[1], argv1_len );
return 0;
}
C编译器对于局部变量和全局变量的内存布局信息是否足够丰富,能否在编译时或运行时插入代码,建立一个内存位置和长度的数据库,并对于任何使用strcpy、memcpy、memset等函数或者类似于*ch1 = * ch2这样赋值操作的代码进行检查,确保内存访问不越界?我认为这种方法可能无法完全覆盖所有情况,并且会带来一定的性能损失,但这个功能可以通过开关或针对代码的某些行或片段进行重新编译来解决。这有点像valgrind,但更好,因为它利用了编译器的帮助,而不仅仅依靠二进制文件并只检查堆栈。
甚至可以将checkPtr API提供给开发人员,以便自己编写strcpy等函数。
char *mystrcpy( char *dst, const char *src )
{
if ( checkPtr( dst, strlen( src ) ) )
{ /* do something custom */ }
return strcpy( dst, src );
}