Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 围绕变量';libName';加载msimg32.dll的loadlibrary和GetProcAddress时已损坏_C++_Com_Visual C++ - Fatal编程技术网

C++ 围绕变量';libName';加载msimg32.dll的loadlibrary和GetProcAddress时已损坏

C++ 围绕变量';libName';加载msimg32.dll的loadlibrary和GetProcAddress时已损坏,c++,com,visual-c++,C++,Com,Visual C++,我正在开发一个像MSN Plus这样的live messenger插件。 我将用proxymsimg32.dll连接到MSN。 与internet中的代理msimg32.dll的其他示例不同,在这些示例中,导出的函数在DLLMain中检索,因为MSDN说调用LoadLibrary在DLLMain中是不安全的。 这通过测试得到确认,在自定义的msimg32.dll的DllMain中加载系统的msimg32.dll将导致访问冲突 我的方法是加载c:\windows\system32\msimg32.

我正在开发一个像MSN Plus这样的live messenger插件。 我将用proxy
msimg32.dll
连接到MSN。 与internet中的代理
msimg32.dll
的其他示例不同,在这些示例中,导出的函数在
DLLMain
中检索,因为MSDN说调用
LoadLibrary
DLLMain
中是不安全的。 这通过测试得到确认,在自定义的
msimg32.dll
DllMain
中加载系统的
msimg32.dll将导致访问冲突

我的方法是加载
c:\windows\system32\msimg32.dll
在一个导出的函数中,我在MSN plus的
msimg32.dll
的disassamble中找到了这种方法。 但是我在函数
GetMsimg32FnAddr
中面临一个严重错误,当
GetMsimg32FnAddr
返回时,变量
libName
已损坏

我的问题是如何避免源代码中的堆栈损坏。 此外,关于代理
msimg32.dll
,我的想法行吗

我的开发环境是: VS2005,win7企业版,32位。 最新版本的Live messenger。 MSN plus的最新版本

VS2005报告:

运行时检查失败#2-变量“libName”周围的堆栈已损坏

GetMsimg32FnAddr
返回

下面是我的proxy
msimg32.dll的源代码

msimgproxy.h

/*****************************************************************************/
#ifndef MSIMGPROXY_H
#define MSIMGPROXY_H
#include <windows.h>
#pragma warning( disable:4273 ) // Silence compiler

//
// Function pointer typedefs for exports we are forwarding              
//
typedef BOOL (WINAPI *PFNTRANSPARENTBLT) (HDC,int,int,int,int,HDC,int,int,int,int,UINT);
typedef VOID (WINAPI *PFNVSETDDRAWFLAG)  (VOID);
typedef BOOL (WINAPI *PFNALPHABLEND)    (HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
typedef BOOL (WINAPI *PFNGRADIENTFILL)  (HDC,PTRIVERTEX,ULONG,PVOID,ULONG,ULONG);
typedef BOOL (WINAPI *PFNDLLINITIALIZE)(HINSTANCE, DWORD, LPVOID);

// Function pointer typedef to injected-DLL initialization
typedef void (*PFNINIT) (void); 

#ifdef __cplusplus
extern "C" 
{
#endif 
    //
    // Function protoypes
    //
    BOOL WINAPI TransparentBlt(HDC, int, int, int, int, HDC, int, int, int, int, UINT);
    BOOL WINAPI AlphaBlend    (HDC, int , int, int, int, HDC, int , int, int, int, BLENDFUNCTION);
    BOOL WINAPI GradientFill  (HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG);
    BOOL WINAPI DllInitialize (HINSTANCE, DWORD, LPVOID);
    VOID WINAPI vSetDdrawflag (VOID);

#ifdef __cplusplus
}
#endif // __CPLUSPLUS
#endif // MSIMGPROXY_H

我建议您查看文档,特别是注意下面的评论:“从DllMain调用LoadLibrary是不安全的”。您应该在第一次使用时按需加载API,并由互斥锁或crit-section保护。那么“第一次使用时按需加载API”如何?这是否意味着我应该在本地msimg32.dll的DLLMain中加载系统msimg32.dll?它确实抛出了访问冲突的异常。我猜这是由相同的DLL名称引起的死锁:msimg32.DLL。因为我有另一个测试用例:在DLLMain中加载除msimg32.dll之外的另一个普通dll,一切正常。在MSDN DLLMain中可以找到以下内容:入口点函数应该只执行简单的初始化或终止任务。它不能调用LoadLibrary或LoadLibraryEx函数(或调用这些函数的函数),因为这可能会在DLL加载顺序中创建依赖项循环。这可能导致在系统执行其初始化代码之前使用DLL。如果您现在从一个API加载msimg32.dll,而不是从DllMain加载msimg32.dll,那么您的做法是正确的。在这一点上,另一个经常出错的事情是调用约定(当然,使用不同平台(即x64和x86)编译的可能性,但若出现这种情况,您的LoadLibrary将失败)。检查您的调用约定,确保它们与DLL所期望的内容相匹配。一种方法是在msimg32.dll中查找没有参数的函数。如果这样的话,你的通话习惯在其他通话中肯定是错误的。检查调用约定a>将msimg32.dll和dll主机(用于测试msimg32.dll的win32项目)的默认调用转换设置为uu stdcall。b>将“bool GetMsimg32FnAddr()”更改为“bool WINAPI GetMsimg32FnAddr()”,同时使用u stdcall。不幸的是,所有这些转换都不起作用。2.更改GetMsimg32FnAddr()中的部分代码找到根本原因。更改:_tcscat_s(libName,MAX_PATH*sizeof(TCHAR),TEXT(\\msimg32.dll));更改为:_tcscat(libName,_T(\\msimg32.dll));已修复!非常感谢。根本原因似乎不是调用约定,而是字符串。
#include "msimgproxy.h"
#include <tchar.h>

PFNTRANSPARENTBLT   pfnTransparentBlt   = NULL;
PFNALPHABLEND       pfnAlphaBlend       = NULL;
PFNDLLINITIALIZE    pfnDllInitialize    = NULL;
PFNGRADIENTFILL     pfnGradientFill     = NULL;
PFNVSETDDRAWFLAG    pfnVSetDdrawFlag    = NULL;
PFNINIT             pfnInit             = NULL;

bool        GetMsimg32FnAddr();
HMODULE     hMsimg32 = NULL;
HMODULE     hPlugDll = NULL;

TCHAR pszInjDllName[] = TEXT("msg_plugin.dll");

/************************************************************************/
/*                                                                      */
/* Proxy DLL Entry point                                                */
/*                                                                      */
/************************************************************************/

BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, 
                      LPVOID lpReserved )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:        
        {
            /*
            if (!GetMsimg32FnAddr())
            {
                OutputDebugString (TEXT("MSIMG32 Proxy: GetMsimg32FnAddr() failed\n"));
                return FALSE;
            }
            */

            OutputDebugString(TEXT("MSIMG32 Proxy: DLL attached\n"));

            // Load injected DLL and execute it's initialization function           
            if (! (hPlugDll = LoadLibrary(pszInjDllName)))
            {
                OutputDebugString (TEXT("MSIMG32 Proxy: Cannot load inject-DLL\n"));
                //return FALSE;
            }

            if (! (pfnInit = (PFNINIT) GetProcAddress (hPlugDll, "Init")))
            {
                OutputDebugString (TEXT("MSIMG32 Proxy: No valid address for executing Init\n"));
                //return FALSE;
            }

            if (pfnInit)
            {
                (*pfnInit)();
            }
            break;
        }

    case DLL_PROCESS_DETACH:
        {
            if (hMsimg32)
                if (FreeLibrary(hMsimg32))
                    OutputDebugString (TEXT("MSIMG32 Proxy: DLL detached.\n"));
            break;
        }
    }
    return TRUE;
}

// 
// Get original MSIMG32.DLL functions virtual addresses
//////////////////////////////////////////////////////////////////////////
bool GetMsimg32FnAddr()
{
    TCHAR libName[MAX_PATH];
    GetSystemDirectory (libName, MAX_PATH);
    _tcscat_s (libName, MAX_PATH*sizeof(TCHAR), TEXT("\\msimg32.dll"));
    hMsimg32 = LoadLibrary (libName);

    if (!hMsimg32)
        return false;

    if ( (pfnVSetDdrawFlag = (PFNVSETDDRAWFLAG) GetProcAddress(hMsimg32, "vSetDdrawflag")) == NULL)
        return false;

    if ( (pfnAlphaBlend = (PFNALPHABLEND) GetProcAddress(hMsimg32, "AlphaBlend")) == NULL)
        return false;

    if ( (pfnDllInitialize = (PFNDLLINITIALIZE) GetProcAddress(hMsimg32, "DllInitialize")) == NULL)
        return false;

    if ( (pfnGradientFill = (PFNGRADIENTFILL) GetProcAddress(hMsimg32, "GradientFill")) == NULL)
        return false;

    if ( (pfnTransparentBlt = (PFNTRANSPARENTBLT) GetProcAddress(hMsimg32, "TransparentBlt")) == NULL)
        return false;

    return true;
}

//
// Exported function definition
//////////////////////////////////////////////////////////////////////////
BOOL WINAPI TransparentBlt(HDC p1, int p2, int p3, int p4, int p5, HDC p6, int p7, int p8, 
                                   int p9, int p10, UINT p11)
{   
    return pfnTransparentBlt (p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11);
}

BOOL WINAPI AlphaBlend(HDC p1, int p2, int p3, int p4, int p5, HDC p6, int p7 , int p8,
                               int p9, int p10, BLENDFUNCTION dw)
{
    return pfnAlphaBlend (p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,dw);
}

BOOL WINAPI GradientFill (HDC p1, PTRIVERTEX p2, ULONG p3, PVOID p4, ULONG p5, ULONG p6)
{
    return pfnGradientFill (p1, p2, p3, p4, p5, p6);
}

BOOL WINAPI DllInitialize (HINSTANCE d1,DWORD d2, LPVOID d3)
{
    if (pfnDllInitialize == NULL)
    {
        GetMsimg32FnAddr();
    }

    return pfnDllInitialize (d1, d2, d3);
}

VOID WINAPI vSetDdrawflag (VOID)
{
    (*pfnVSetDdrawFlag)();
}