是否有任何简单的方法可以检测传递给函数的参数(const char *argument)是常量文字还是变量?
我正在尝试修复一些代码中的错误,这些代码充满了 IsBadWritePtr 调用,如果参数是常量文字,则会引发访问冲突异常。
这是一个可怕的设计愚蠢,但现在我不允许改变尴尬的行为。
是否有任何简单的方法可以检测传递给函数的参数(const char *argument)是常量文字还是变量?
我正在尝试修复一些代码中的错误,这些代码充满了 IsBadWritePtr 调用,如果参数是常量文字,则会引发访问冲突异常。
这是一个可怕的设计愚蠢,但现在我不允许改变尴尬的行为。
您可以添加一个更适合字符串文字的不同重载。这不是真正的科学,而只是启发式:
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
请注意,它们并没有完全检测到literal与not literal,而是检测到其他一些特性。const char* p = createANewString(); f(p);
将解析为f(const char*)
,const char x[] = { 'A', 'b', 'c', '\0' };
并将解析为模板。它们都不是literals,但您可能也不想修改。
一旦进行了更改,就应该很容易找出每个重载的调用位置。
这一切的前提是主函数不应该像const char*
在内部修改它一样接受参数,并且您面临的问题是因为为了向后兼容,您的编译器允许调用一个函数,该函数需要一个指向非带有文字的 const...
我不认为有一种方法可以在不使用一些黑客的情况下检测到这一点。
由于接口承担const char *
了函数的责任,因此无论如何都不修改传递的字符串。您需要修改实现,因为它根本不正确。
VirtualQuery
可用于检测地址是可写、只读还是不可访问。检查返回结构的State
和Protect
成员MEMORY_BASIC_INFORMATION
以查看内存是否可访问以及是否具有您需要的访问权限。
一种非常骇人听闻的方法是检查指针是否在 .rdata 段中。
在构建之后使用dumpbin /headers
来检索 .rdata 部分的偏移量和长度,或者自己解析 PE 标头。自然,这是特定于工具链的,通常是个坏主意。此外,如果代码需要与 DLL 互操作,您必须检查几个可执行文件和几个 .rdata 段。