缓冲区溢出问题是众所周知的。因此,我们有幸使用标准库函数,如wcscat_s()。微软的好心人已经创建了类似的安全字符串函数,如StringCbCat()。
但是我有一个问题,我需要为字符串搜索一些内存。标准库函数:
wcsstr( wchar_t* pMem, wchar_t* pStr )
看起来很棒,但...... 有时我的记忆包含垃圾,有时候是字符串当它是垃圾时,我有时会运行已分配的内存页面,[=访问冲突]。我可以写自己的功能是的。但我的问题是,是否有任何“标准”功能来进行安全字符串搜索,例如:
"wcsstr_s( wchar_t* pMem, size_t uiSize, wchar_t* pStr )" ?
感谢名单
[编辑] 感谢Charles Bailey对我的问题的完美回答。感谢其他人的努力。
对于那些怀疑我的场景的理智的人:是的,当然,在我的记忆中永远不会有垃圾是好的。但我可以想象出现这种情况的几种情况。在我的特殊情况下,它是逆向工程,而我正在处理的内存实际上不是“我的记忆”,它属于另一个我无法控制的过程。
(另一个假设场景可能是一个棘手的调试情况,需要跟踪损坏的内存。)
答案 0 :(得分:6)
可能不是您正在寻找的答案,但也许这里最好的解决方案是正确初始化您的字符串和指针。如果你的记忆包含垃圾,为什么不做正确的事情并设置
yourString[0] = '\0';
如果它只是缓冲区的任意位,那么最好使用memcmp之类的东西,并沿着N
个字符滑动内存缓冲区的指针(其中N
是数字您感兴趣的字符减去您正在比较的字符串的长度。这可能不是最有效的实现,但应该是一个我应该考虑的相当强大的方法。
[编辑] 您的问题引起了我的兴趣,足以做一些实验。鉴于您似乎正在寻找更多C风格的答案,这里有一小段代码我想出了详细说明我的memcmp建议:
// SearchingMemoryForStrings.cpp : Defines the entry point for a win32 consol application
// Purpose : Demonstrates a way to search a section of memory for a particular string
//
#include <stdio.h>
#include <string.h>
#define VALUE_NOT_FOUND (-1)
int FindStringInBuffer( const char* pMemBuffer, const size_t& bufferSizeInBytes, const char* pStrToFind )
{
int stringFound = VALUE_NOT_FOUND; // Return value which will be >= 0 if we find the string we're after
const char* pMemToMatch = NULL; // An offset pointer to part of 'pMemBuffer' which we'll feed to memcmp to find 'pStrToFind'
// Set up some constants we'll use while searching
size_t lenOfStrToFind = strlen( pStrToFind );
size_t lastSearchablePosition = bufferSizeInBytes - lenOfStrToFind;
// Search the memory buffer, shifting one character at a time for 'pStrToFind'
for( size_t i = 0; i <= lastSearchablePosition; i++ ) {
pMemToMatch = &pMemBuffer[i];
if( memcmp(pMemToMatch, pStrToFind, lenOfStrToFind) == 0 ) {
// We found the string we're looking for
stringFound = i;
break;
}
}
return stringFound;
}
void ReportResult( int returnVal, const char* stringToFind )
{
if( returnVal == VALUE_NOT_FOUND ) {
// Fail!
printf("Error, failed to find '%s' - search function returned %d\n", stringToFind, returnVal );
}
else {
// Win!
printf("Success, found '%s' at index %d\n", stringToFind, returnVal );
}
}
void FindAndReport( const char* pMemBuffer, const size_t& bufferSizeInBytes, const char* pStrToFind )
{
int result = FindStringInBuffer( pMemBuffer, bufferSizeInBytes, pStrToFind );
ReportResult( result, pStrToFind );
}
int main( int argc, char* argv[] )
{
const int SIZE_OF_BUFFER = 1024; // Some aribitrary buffer size
char some_memory[SIZE_OF_BUFFER]; // The buffer of randomly assigned memory to look for our string
const char* stringToFind = "This test should pass";
const char* stringYouWontFind = "This test should fail";
FindAndReport( some_memory, SIZE_OF_BUFFER, stringYouWontFind ); // Should fail gracefully
// Set the end of the buffer to the string we're looking for
memcpy( &some_memory[SIZE_OF_BUFFER-strlen(stringToFind)], stringToFind, strlen(stringToFind) );
FindAndReport( some_memory, SIZE_OF_BUFFER, stringToFind ); // Should succeed this time and report an index of 1003
// Try adding at some arbitrary position
memcpy( &some_memory[100], stringToFind, strlen(stringToFind) );
FindAndReport( some_memory, SIZE_OF_BUFFER, stringToFind ); // Should still succeed but report the offset as 100
FindAndReport( some_memory, SIZE_OF_BUFFER, stringYouWontFind ); // Should still fail
return 0;
}
在Visual Studio 2008下编译为Win32控制台应用程序的代码片段。给我以下内容:
Error, failed to find 'This test should fail' - search function returned -1
Success, found 'This test should pass' at index 1003
Success, found 'This test should pass' at index 100
Error, failed to find 'This test should fail' - search function returned -1
FindStringInBuffer
功能是你想要的,如果你需要处理宽字符,你需要做一些转换,但这至少应该给你一些你可以继续的想法。如果你想出一个wchar版本,我会有兴趣看看解决方案是什么样的(我自己没有处理过它们)。
答案 1 :(得分:2)
唉,仍然没有我知道的标准“安全”字符串库。 BSD对此有着强烈的意见,但据我所知,它不在glibc或Microsofts libc中。我不知道对此有任何“好”选择,除了自己动手。
作为参考,Microsoft安全字符串库列在 http://msdn.microsoft.com/en-us/library/wd3wzwts(VS.80).aspx,并在 http://msdn.microsoft.com/en-us/library/bb288454.aspx更详细地提供(包含迁移指南)。
答案 2 :(得分:2)
假设您的pStr
空终止且uiSize
是wchar_t
的可读内存pMem
的数量:
wchar_t* pSubStr = std::search( pMem, pMem + uiSize, pStr, pStr + std::wcslen( pStr ) );
// Optionally, change to the 'conventional' strstr return value
if( pSubStr == pMem + uiSize)
pSubStr = 0;