本文介绍了打印 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 以这样一种方式实现钩子蹦床代码,即在钩子处理程序中直接(或间接)调用原始方法将绕过钩子处理程序并调用原始方法.

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

1403页,肝出来的..

09-08 08:58