C++ 无法使::WideChartMultiByte工作

C++ 无法使::WideChartMultiByte工作,c++,detours,C++,Detours,我有一个DLL用于注入。这是通过CBT钩注入的。现在,当需要的时候 进程是通过CBT遇到的,我用自己的方法绕过了WinAPI的ExtTextOut。ExtTextOut的规格是: BOOL ExtTextOutW(HDC hdc, INT x, INT y, UINT flags, const RE

我有一个DLL用于注入。这是通过CBT钩注入的。现在,当需要的时候 进程是通过CBT遇到的,我用自己的方法绕过了WinAPI的ExtTextOut。ExtTextOut的规格是:


BOOL ExtTextOutW(HDC         hdc,
                 INT         x,
                 INT         y,
                 UINT        flags,
                 const RECT* lprect,
                 LPCWSTR     str,
                 UINT        count,
                 const INT*  lpDx)
在我迂回的ExtTextOut中,我尝试使用以下代码将str(LPCWSTR)转换为多字节:


BOOL Mine_ExtTextOutW(HDC         hdc,
                      INT         x,
                      INT         y,
                      UINT        flags,
                      const RECT* lprect,
                      LPCWSTR     str,
                      UINT        count,
                      const INT*  lpDx)
{
        BOOL rv = Real_ExtTextOutW(hdc, x, y, flags, lprect, str, count, lpDx);

        HANDLE h = ::WindowFromDC(hdc);

        if (!h || !str)
                return ev;

        CHAR *buffer = (CHAR *)::LocalAlloc(count + 1);

        int l = ::WideCharToMultiByte(CP_APC, 0, str, count, buffer, count, NULL, NULL);

        if (l > -1) {
                buffer[l] = '\0';

                g_pClient->SendViaIPC(buffer);
        }

        ::LocalFree(buffer);

        return rv;
}

不幸的是,这不起作用。WideChartMultiByte挂起注入的进程。为什么?

我不知道为什么它会挂起您的进程,我觉得它应该可以正常工作。你确定是WC2MB呼叫引起的吗?一些可能性:

  • 为什么要使用LocalAlloc?在堆栈上使用缓冲区还不够吗
  • 也许是“SendViaIPC”被吊死了
  • 要转换的字符串有多大?也许缓冲区的大小不够
  • WC2MB的返回值是多少?如果函数未成功,则返回0


    LocalAlloc的返回值是多少?可能分配返回null表示分配内存失败?然后,您将为缓冲区传递NULL,但为计数传递大于0的数字,这可能会导致崩溃。

    您的代码看起来有点奇怪,是否编译

    LocalAlloc应该有两个参数,您是指CP_ACP吗。无论如何,我会:

    • 询问WideCharToMultiByte以获得正确的大小,以防将来更改代码页
    • 检查>0(故障由0表示,而不是-1)
    • 使用std字符串只是为了确保没有任何内存泄漏、异常等
    比如说:

    int nMultiByteSize = ::WideCharToMultiByte( CP_ACP, NULL, str, count, NULL, 0, NULL, NULL );
    if ( nMultiByteSize > 0 )
    {
        std:string strMulti;
        strMulti.resize( nMultiByteSize );
    
        if ( ::WideCharToMultiByte( CP_ACP, NULL, str, count, &strMulti[0], (int)strMulti.size(), NULL, NULL ) > 0)
        {
            g_pClient->SendViaIPC(strMulti.c_str());
        }
    }
    

    如果在堆栈上实现缓冲区,则会崩溃。此外,字符串大小不一(最多8192个)。此外,该进程可以同时发送数百个ExtTextOuts,因此堆栈可能会突然终止。这不是问题所在。如果我用废话填充缓冲区并删除WideChartMultiByte,一切都正常(没有崩溃)。@nhaa123我看到堆栈上的char缓冲区也发生了同样的崩溃。