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