【问题标题】:A crash in injected / hooked target application注入/挂钩的目标应用程序崩溃
【发布时间】:2010-07-02 08:49:23
【问题描述】:

我已经将我的 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);
}

那么,谁能指出我做错了什么?

【问题讨论】:

    标签: c++ winapi gdi


    【解决方案1】:

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

    另外,您没有在dwDTFormat 参数中检查DT_MODIFYSTRING。如果存在该标志,则 ::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);
        }
    }
    

    【讨论】:

    • 感谢您的回复,但您最终从一开始就是对的。我忽略了cchText。根据规范,字符串不必以空值结尾。因此 std::wstring(lpchText, cchText) 成功了。
    猜你喜欢
    • 2013-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多