当作为受限用户运行时,为什么我会在DLLMain中获得GPF?

时间:2009-05-13 23:15:34

标签: c++ com activex atl

为什么这个代码在作为受限用户运行时会崩溃,但在以管理员身份运行时却不会崩溃?

extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, 
                               DWORD dwReason, 
                               LPVOID lpReserved)
{
 hInstance;
 m_hInstance=hInstance;
 return _AtlModule.DllMain(dwReason, lpReserved); 
}

代码在返回时崩溃......我不知道为什么。

我得到了:

The instruction at "0x7c90100b" referenced memory at "0x00000034". 
The memory could not be "read".

此外,_AtlModule.DLLMain如下所示:

inline BOOL WINAPI CAtlDllModuleT<T>::DllMain(DWORD dwReason, LPVOID lpReserved) throw()
{
#if !defined(_ATL_NATIVE_INITIALIZATION)
    dwReason; lpReserved;
#pragma warning(push)
#pragma warning(disable:4483)
    using namespace __identifier("<AtlImplementationDetails>");
#pragma warning(pop)
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        ATLASSERT(DllModuleInitialized == false);
    }
    return TRUE;
#else
    return _DllMain(dwReason, lpReserved);
#endif
}

我们正在导入ATL DLL,并尝试静态链接......没有运气。


更新

使用ProcMon,我在这里得到一个缓冲区溢出:

RegQueryValue HKU \ S-1-5-21-448539723-854245398-1957994488-1005 \ Software \ Microsoft \ Windows \ CurrentVersion \ Explorer \ Shell Folders \ Cache BUFFER OVERFLOW 长度:144

这是什么意思?

5 个答案:

答案 0 :(得分:2)

杰森,

你在哪里宣布m_hInstance?它在DllMain之上是静态的吗?只是想了解一些关于代码的更多细节。

答案 1 :(得分:2)

如果出现错误,指出您无法在某个0x0000 ...位置引用内存,则通常意味着您的代码正在尝试引用某个对象的成员变量,但该对象指针指向NULL。在这种情况下,成员变量是0x34字节到对象中。进一步猜测,鉴于它只在受限用户下运行时失败,我会说由于权限不足,某些应该返回指向对象的指针的操作失败。如果返回的指针未被测试为null,则代码将继续运行,直到有人试图读取其中一个成员变量,此时您将崩溃。

我要做的是彻底调试代码并查找可疑的NULL。此外,您可能希望在AppVerifier下使用LuaPriv测试运行您的应用。如果我的猜测是正确的,那么会报告一些API调用失败,在您的代码中显示为返回的NULL。 AppVerifier还应该为您提供堆栈跟踪,这样您就可以轻松找到问题的根源。

答案 2 :(得分:1)

你并没有真正说出“崩溃”的意思,所以很难说清楚。代码没有做任何特别会导致崩溃的事情,因此对ATL模块DllMain的调用可能需要管理员权限并因此失败。

答案 3 :(得分:1)

尝试运行ProcMon utility并查看是否可以发现差异。你必须打开过滤,否则可能会有太多的输出需要通过。

要检查您是否使用ATL DLL(而不是静态库):确保在两种情况下都获得相同版本的DLL。

答案 4 :(得分:0)

看起来我们跟踪了RDCOMClient,它用于在R中运行COM对象。

每个人的答案都有帮助。谢谢。