我已经将DLL注入到目标应用程序中,在该应用程序中挂钩了一些WINAPI函数
也一样其中之一是DrawTextExW。我正在尝试将所有的“ l”字母替换为“!”之前
它打印出来。我的解决方案可以正常工作几秒钟,但随后目标应用程序崩溃。我真的不明白为什么。

功能如下:

编辑-工作解决方案:

int WINAPI DetouredDrawTextExW(__in    HDC hdc,
                               __inout LPWSTR lpchText,
                               __in    int cchText,
                               __inout LPRECT lprc,
                               __in    UINT dwDTFormat,
                               __in    LPDRAWTEXTPARAMS lpDTParams)
{
    std::wstring s_wc(lpchText, cchText);

    std::replace(s_wc.begin(), s_wc.end(), L'l', L'!');

    return ::DrawTextExW(hdc, const_cast<wchar_t *>(s_wc.c_str()),
        s_wc.length(), lprc, dwDTFormat, lpDTParams);
}


因此,有人可以向我指出我做错了什么吗?

最佳答案

我看到您忽略了cchText,会不会收到一个以cchText为正值的非NULL终止字符串,从而导致将字符串末尾读入无效内存?但是,该错误将在s_wc的构造函数中显示为Win32异常。

另外,您无需在DT_MODIFYSTRING参数中检查dwDTFormat。如果存在该标志,则:: DrawTextExW()可能会覆盖无效的内存。这将在:: DrawTextExW()中显示为Win32异常,或者在s_wc析构函数中显示为C ++异常。

编辑

这是未经编译,未经测试的代码,我相信这些代码符合::DrawTextExW()的约定

int WINAPI DetouredDrawTextExW(__in    HDC hdc,
                               __inout LPWSTR lpchText,
                               __in    int cchText,
                               __inout LPRECT lprc,
                               __in    UINT dwDTFormat,
                               __in    LPDRAWTEXTPARAMS lpDTParams)
{
    std::vector<wchar_t> v_wc;
    int strSize = cchText == -1 ? wcslen(lpchText) : cchText;
    v_wc.resize(strSize + 4);
    std::copy(lpchText, lpchText + strSize, &v_wc.front());
    std::replace(v_wc.begin(), v_wc.end() - 4, L'l', L'!');

    int result = ::DrawTextExW(hdc, &v_wc.front(),
        strSize, lprc, dwDTFormat, lpDTParams);
    if (dwDTFormat & DT_MODIFYSTRING)
    {
      std::copy(&v_wc.front(), &v_wc.front() + v_wc.size(), lpchText);
    }
}

10-08 14:21