打印 wstringstream 时程序崩溃 [英] Program crash on printing wstringstream

查看:28
本文介绍了打印 wstringstream 时程序崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码位于我用来挂钩 CreateWindowExA() 和其他函数的 DLL 中.

The code below is inside of a DLL that I'm using to hook CreateWindowExA() and other functions.

当我使用 std::wstringstream 将变量的值打印到 DebugView.我确认当我评论 std::wstringstream 时它不会崩溃.

The current hooked app is crashing when I use std::wstringstream to print the values of the variables to DebugView. I confirmed that when I comment the std::wstringstream it doesn't crash.

我还可以使用哪些其他选项来打印它们的值,而无需指定每个变量类型,就像您在 wsprintf() 上所做的那样?

What other option can I use to print their values that I don't need to specify each variable type, as you do on wsprintf()?

HWND __stdcall CreateWindowExA_Hook(
    DWORD     dwExStyle,
    LPCSTR    lpClassName,
    LPCSTR    lpWindowName,
    DWORD     dwStyle,
    int       X,
    int       Y,
    int       nWidth,
    int       nHeight,
    HWND      hWndParent,
    HMENU     hMenu,
    HINSTANCE hInstance,
    LPVOID    lpParam
)
{
    std::wstringstream text;
    text << L"dwExStyle: " << dwExStyle << L" lpClassName: " << lpClassName << L" lpWindowName: " << lpWindowName
    << L" dwStyle: " << dwStyle << L" X: " << X << L" Y: " << Y << L" nWidth: " << nWidth << L" nHeight: " << nHeight
    << L" hWndParent: " << hWndParent << L" hMenu" << hMenu << L" hInstance: " << hInstance << L" lpParam: " << lpParam;

    OutputDebugString(L"CreateWindowExA:");
    OutputDebugString(text.str().c_str());
    OutputDebugString(L" ");

    return CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
}

我想知道是否有比这样做更好"的方法:

I wonder if there's any 'better' way than doing this:

std::wstringstream ss;
( dwExStyle ? ss << L"dwExStyle: " << dwExStyle : ss << 0 );
( lpClassName ? ss << L" lpClassName: " << lpClassName : ss << 0 );
( lpWindowName ? ss << L" lpWindowName: " << lpWindowName : ss << 0 );
( dwStyle ? ss << L" dwStyle: " << dwStyle : ss << 0 );
....

OutputDebugString(L"CreateWindowExA:");
OutputDebugString(text.str().c_str());
OutputDebugString(L" ");

推荐答案

使用 wstringstream 打印非字符串 NULL 指针没有问题,它们按原样打印作为数值(即,0x00000000).只有 NULL 字符串指针可能有问题,并且此代码中唯一的字符串指针是 lpClassNamelpWindowName,因此只需检查它们的 NULL 显式,例如:

There is no problem printing non-string NULL pointers with wstringstream, they are printed as-is as numeric values (ie, 0x00000000). Only NULL string pointers could be a problem, and the only string pointers in this code are lpClassName and lpWindowName, so just check them for NULL explicitly, eg:

std::wstringstream text;
text << ...
     << L" lpClassName: " << (lpClassName ? lpClassName : L"")
     << L" lpWindowName: " << (lpWindowName ? lpWindowName : L"")
     << ...;

您不需要将 ?: 用于其他参数值,因为当 0/NULL<时,按原样打印它们是完全安全的/代码>.

You don't need to use ?: for the other parameter values, as they are perfectly safe to print as-is when 0/NULL.

附带说明一下,我还建议在钩子内尽可能少地调用 OutputDebugString(),因此您应该包含您的 L"CreateWindowExA:"wstringstream 文本中的前缀.

On a side note, I would also suggest calling OutputDebugString() as few times as possible inside a hook, so you should include your L"CreateWindowExA:" prefix in your wstringstream text.

试试这个:

HWND __stdcall CreateWindowExA_Hook(
    DWORD     dwExStyle,
    LPCSTR    lpClassName,
    LPCSTR    lpWindowName,
    DWORD     dwStyle,
    int       X,
    int       Y,
    int       nWidth,
    int       nHeight,
    HWND      hWndParent,
    HMENU     hMenu,
    HINSTANCE hInstance,
    LPVOID    lpParam
)
{
    std::wstringstream text;
    text << L"CreateWindowExA:"
         << L" dwExStyle: " << dwExStyle
         << L" lpClassName: " << (!lpClassName ? lpClassName : L"")
         << L" lpWindowName: " << (!lpWindowName ? lpWindowName : L"")
         << L" dwStyle: " << dwStyle
         << L" X: " << X
         << L" Y: " << Y
         << L" nWidth: " << nWidth
         << L" nHeight: " << nHeight
         << L" hWndParent: " << hWndParent
         << L" hMenu" << hMenu
         << L" hInstance: " << hInstance
         << L" lpParam: " << lpParam
         << L"\n \n";

    OutputDebugStringW(text.str().c_str());

    return CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
}

更新:根据 Easyhook 的文档:

UPDATE: per Easyhook's documentation:

注意:EasyHook 以这样一种方式实现钩子蹦床代码,即在钩子处理程序中直接(或间接)调用原始方法将绕过钩子处理程序并调用原始方法.

Note: EasyHook implements the hook trampoline code in such a way that calling the original method directly (or indirectly) while still within the hook handler will bypass the hook handler and call the original method.

这篇关于打印 wstringstream 时程序崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆