【问题标题】:strtok_s return incorrect data inside windbgstrtok_s 在 windbg 中返回不正确的数据
【发布时间】:2019-10-12 12:41:59
【问题描述】:

(大家好)我对 strtok_s 有一些问题。我写了这段代码(x64)。

    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>


    BOOL TestMD5(CONST WCHAR* MD5_DATABASE_FILE)
    {
    HANDLE  hFile = INVALID_HANDLE_VALUE;
    DWORD   FileSize = 0;
    DWORD   dwReaded = 0;
    PBYTE   pData = NULL;
    BOOL    bRead = FALSE;
    PCHAR   token_string = NULL;
    PCHAR   context = NULL;
    CONST   PCHAR delimeter = "\r\n";

    hFile = CreateFileW(
        MD5_DATABASE_FILE,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );

    if (hFile == INVALID_HANDLE_VALUE)
    {
        wprintf(L"Can't open md5 database file: ");
        return FALSE;
    }

    FileSize = GetFileSize(hFile, NULL);
    if (FileSize == 0 || FileSize == INVALID_FILE_SIZE)
    {

        CloseHandle(hFile);
        return FALSE;
    }

    pData = (PBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (SIZE_T)FileSize);
    if (pData == NULL)
    {

        CloseHandle(hFile);
        return FALSE;
    }

    bRead = ReadFile(hFile, pData, FileSize, &dwReaded, NULL);
    if (bRead != TRUE || dwReaded != FileSize)
    {

        HeapFree(GetProcessHeap(), 0, pData);
        CloseHandle(hFile);
        return FALSE;
    }


    token_string = (PCHAR)strtok_s(pData, delimeter, &context);
    if (token_string == NULL)
    {

        HeapFree(GetProcessHeap(), 0, pData);
        CloseHandle(hFile);
    return FALSE;
    }

    do {

        printf("%s\n", token_string);

    } while (token_string = (PCHAR)strtok_s(NULL, delimeter, &context));


    HeapFree(GetProcessHeap(), 0, pData);
    CloseHandle(hFile);
    return TRUE;
    }

    int main(void)
    {
    WCHAR* MD5_DATABASE_FILE = L"c:\\md5.txt";

    TestMD5(MD5_DATABASE_FILE);


    }

当我运行 exe 时,这给了我一个不正确的数据。 md5.txt的内容(DC288E0B39EA16B4E9455F82FF265A67:1213:TestDBG + (\r\n)

输出:

D:\repos\TestWindbg\x64\Debug>TestWindbg.exe DC288E0B39EA16B4E9455F82FF265A67:1213:TestDBG 咻咻咻咻咻咻

我在 windbg 中打开 exe,第一次看到 while(token_string) is not NULL。但必须吗?

WinDbg 图片:“https://i.ibb.co/60nHk5S/Untitled.png

什么是问题?感谢阅读

【问题讨论】:

  • 不要使用strtok_s,它不像你想象的那样工作。定义_CRT_SECURE_NO_WARNINGS 并改用strtok
  • 感谢回复。但是微软说 strtok_s 比 strtok 更安全?
  • 您发布的代码不是多线程的,因此自然不会在多个线程中调用strtok(),所以不会有问题
  • user3629249:感谢您的回复。我知道,但我的问题不同,这段代码打印不正确的数据输出。
  • 你确定你发布的代码和你正在调试的代码是一样的吗我看不到屏幕截图中的while循环也避免在条件表达式中赋值不要使用c:\​​它通常是非在winx中可写不要将pbyte转换为pchar memdump在+之后有一个空字符并且只有0x0a而不是0x0d 0x0a可能是strtok在某个地方找到了\r\n你检查了偏移量吗?

标签: c winapi 64-bit windbg strtok


【解决方案1】:

Jeffrey Shao - MSFT:感谢您的回复,但这不是解决方案(但我将代码 PBYTE 更改为 PCHAR)。问题是 strtok_s 是一个字符串函数,因此您必须在 buff 之后添加 NULL 字节。就像 HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(SIZE_T)FileSize + 1) #1 代表 NULL 字符。 HeapAlloc alloc buff size:FileSize and +1 For Null...

感谢 blabb 和 Daniel Sęk:

【讨论】:

    【解决方案2】:

    我只是更改了pDatatoken_string的一些类型。

    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    
    
    BOOL TestMD5(CONST WCHAR* MD5_DATABASE_FILE)
    {
        HANDLE  hFile = INVALID_HANDLE_VALUE;
        DWORD   FileSize = 0;
        DWORD   dwReaded = 0;
        char*   pData = NULL;
        BOOL    bRead = FALSE;
        char*   token_string = NULL;
        PCHAR   context = NULL;
        CONST   PCHAR delimeter = "\r\n";
    
        hFile = CreateFileW(
            MD5_DATABASE_FILE,
            GENERIC_READ,
            FILE_SHARE_READ,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL
        );
    
        if (hFile == INVALID_HANDLE_VALUE)
        {
            wprintf(L"Can't open md5 database file: ");
            return FALSE;
        }
    
        FileSize = GetFileSize(hFile, NULL);
        if (FileSize == 0 || FileSize == INVALID_FILE_SIZE)
        {
    
            CloseHandle(hFile);
            return FALSE;
        }
    
        pData = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(SIZE_T)FileSize + 1);
        if (pData == NULL)
        {
    
            CloseHandle(hFile);
            return FALSE;
        }
    
        bRead = ReadFile(hFile, pData, FileSize, &dwReaded, NULL);
        if (bRead != TRUE || dwReaded != FileSize)
        {
            HeapFree(GetProcessHeap(), 0, pData);
            CloseHandle(hFile);
            return FALSE;
        }
    
    
        token_string = strtok_s(pData, delimeter, &context);
        if (token_string == NULL)
        {
    
            HeapFree(GetProcessHeap(), 0, pData);
            CloseHandle(hFile);
            return FALSE;
        }
    
        do {
    
            printf("%s\n", token_string);
    
        } while (token_string = strtok_s(NULL, delimeter, &context));
    
    
        HeapFree(GetProcessHeap(), 0, pData);
        CloseHandle(hFile);
        return TRUE;
    }
    
    int main(void)
    {
        WCHAR* MD5_DATABASE_FILE = L"c:\\md5.txt";
    
        TestMD5(MD5_DATABASE_FILE);
    
    }
    

    输出: DC288E0B39EA16B4E9455F82FF265A67:1213:TestDBG + (\r\n)

    【讨论】:

      猜你喜欢
      • 2019-11-22
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      • 2016-12-05
      • 1970-01-01
      • 2013-10-30
      • 2020-07-01
      相关资源
      最近更新 更多