制限付きユーザーとして実行すると DLLMain で GPF が発生するのはなぜですか?
質問
このコードは、制限付きユーザーとして実行するとクラッシュするのに、マシンの管理者として実行するとクラッシュしないのはなぜですか?
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フォルダーキャッシュバッファーオーバーフロー長:144
これはどういう意味ですか?
解決
0x0000 あたりでメモリを参照できないというエラーが発生した場合...これは通常、コードが何らかのオブジェクトのメンバー変数を参照しようとしているが、オブジェクト ポインタが NULL を指していることを意味します。この場合、メンバー変数はオブジェクト内の 0x34 バイトです。さらに推測すると、制限されたユーザーで実行する場合にのみ失敗することを考えると、オブジェクトへのポインターを返すはずの操作が権限不足のために失敗するのではないかと思います。返されたポインターが null であるかどうかテストされていない場合、コードは誰かがそのメンバー変数の 1 つを読み取ろうとするまで実行を続け、その時点でクラッシュが発生します。
私なら、コードを徹底的にデバッグし、疑わしい NULL を探します。また、次の環境でアプリを実行することもできます。 AppVerifier LuaPriv テストをオンにした状態。私の推測が正しければ、一部の API 呼び出しの失敗が報告され、NULL が返されるとしてコードに明示されることになります。AppVerifier はスタック トレースも提供するため、問題の根本を簡単に見つけることができます。
他のヒント
ジェイソン、
m_hInstance をどこで宣言していますか?DllMain 上では静的ですか?コードについてさらに詳細を取得しようとしています。
「クラッシュ」が何を意味するのかをあまり語らないので、判断するのは困難です。コードは特にクラッシュの原因となるようなことを行っていないため、おそらく ATL モジュールの呼び出しが原因であると考えられます。 DllMain
管理者権限が必要であり、それが原因で失敗します。
を実行してみてください ProcMonユーティリティ 違いを見つけられるかどうかを確認してください。フィルタリングをオンにする必要があります。そうしないと、出力が多すぎて処理できない可能性があります。
(静的ライブラリではなく) ATL DLL を使用している場合は、次の点を確認してください。どちらの場合も、同じバージョンの DLL を取得していることを確認してください。
R 内で COM オブジェクトを実行するために使用される RDCOMClient をトレースしたようです。
皆さんの回答が役に立ちました。ありがとう。