是否有任何简单的方法可以检测,如果传递给函数的参数(const char *参数)是常量文字还是变量?
我正在尝试修复一些代码中的错误,这些代码填充了IsBadWritePtr调用,如果参数是常量字面值,则抛出访问冲突异常。
这是一个可怕的设计愚蠢,但现在我不允许改变尴尬的行为。
答案 0 :(得分:3)
您可以添加一个不同的重载,以便更好地匹配字符串文字。这不是真正的科学,而只是启发式:
void f(const char* p); // potential literal
void f(char *p); // pointer to non-const
另一个想法是利用文字实际上是数组:
template <int N>
void f(const char (&_)[N]); // potential literal
请注意,他们并未完全检测文字与非文字,而是其他一些功能。 const char* p = createANewString(); f(p);
将解析为f(const char*)
,const char x[] = { 'A', 'b', 'c', '\0' };
将解析为模板。它们都不是文字,但您可能不想修改它们。
进行更改后,应该很容易找出调用每个重载的位置。
这一切的前提是主函数不应该将参数作为const char*
,如果它在内部修改它,并且您面临的问题是因为为了向后兼容,您的编译器允许调用使用文字...
答案 1 :(得分:1)
我认为没有办法在不使用某些hackery的情况下检测到这种情况。
由于接口采用const char *
函数的职责是不修改传递的字符串。您需要修改实现,因为它完全不正确。
答案 2 :(得分:0)
VirtualQuery
可用于检测地址是可写,只读还是不可访问。检查返回的State
结构的Protect
和MEMORY_BASIC_INFORMATION
成员,以查看内存是否可访问且是否具有所需的访问权限。
答案 3 :(得分:0)
一种非常骇人听闻的方法涉及检查指针是否在.rdata段中。
在构建后使用dumpbin /headers
来检索.rdata节的偏移量和长度,或者自己解析PE标头。自然,这是特定于工具链的,通常是一个坏主意。另外,如果代码需要与DLL互操作,则必须检查几个可执行文件和几个.rdata段。