20

Windows Defender API を使用して、C# からファイルのオンデマンド スキャンを実行するコードを作成しています。

        [DllImport(@"C:\Program Files\Windows Defender\MpClient.dll")]
        public static extern int WDStatus(out bool pfEnabled);

        [DllImport(@"C:\Program Files\Windows Defender\MpClient.dll")]
        public static extern int MpManagerOpen(uint dwReserved, out IntPtr phMpHandle);

        [DllImport(@"C:\Program Files\Windows Defender\MpClient.dll")]
        public static extern int MpScanStart(IntPtr hMpHandle, uint ScanType, uint dwScanOptions, IntPtr pScanResources, IntPtr pCallbackInfo, out IntPtr phScanHandle);

        [DllImport(@"C:\Program Files\Windows Defender\MpClient.dll")]
        public static extern int MpHandleClose(IntPtr hMpHandle);

        private void DoDefenderScan_Click(object sender, EventArgs e)
        {
            try
            {
                bool pfEnabled;
                int result = WDStatus(out pfEnabled); //Returns the defender status - It's working properly.
                ErrorHandler.ThrowOnFailure(result, VSConstants.S_OK);

                IntPtr phMpHandle;
                uint dwReserved = 0;

                IntPtr phScanHandle;

                MpManagerOpen(dwReserved, out phMpHandle); //Opens Defender and returns the handle in phMpHandle. 

                tagMPRESOURCE_INFO mpResourceInfo = new tagMPRESOURCE_INFO();
                mpResourceInfo.Path = "eicar.com";
                mpResourceInfo.Scheme = "file";
                mpResourceInfo.Class = IntPtr.Zero;

                tagMPRESOURCE_INFO[] pResourceList = new tagMPRESOURCE_INFO[1];
                pResourceList.SetValue(mpResourceInfo, 0);

                tagMPSCAN_RESOURCES scanResource = new tagMPSCAN_RESOURCES();
                scanResource.dwResourceCount = 1;
                scanResource.pResourceList = pResourceList;
                IntPtr resourcePointer = StructToPtr(scanResource);

                result = MpScanStart(phMpHandle, 3, 0, resourcePointer, IntPtr.Zero, out phScanHandle); **//Getting Access violation exception here**.

                MpHandleClose(phMpHandle);
                MpHandleClose(phScanHandle);
                Marshal.FreeHGlobal(resourcePointer);
            }
            catch (Exception)
            { }
        }

そして、構造はここで定義されます。

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct tagMPSCAN_RESOURCES
    {
        public uint dwResourceCount;

        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
        public tagMPRESOURCE_INFO[] pResourceList;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct tagMPRESOURCE_INFO
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public String Scheme;

        [MarshalAs(UnmanagedType.LPWStr)]
        public String Path;

         public IntPtr Class;
    }

    public class MPRESOURCE_CLASS
    {
        public uint Value;
    }

    private static IntPtr StructToPtr(object obj)
    {
        var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
        Marshal.StructureToPtr(obj, ptr, false);
        return ptr;
    }

コードは、次の Web サイトで入手可能なドキュメントに基づいて記述されています。

https://msdn.microsoft.com/en-us/library/vs/alm/dn920144(v=vs.85).aspx

この例外が発生しています

保護されたメモリを読み書きしようとしました。これは多くの場合、他のメモリが破損していることを示しています。

result = MpScanStart(phMpHandle, 3, 0, resourcePointer, IntPtr.Zero, out phScanHandle); **//Getting Access violation exception here**.

何が問題なのですか?構造体のフォーマットは正しいですか?

PS - MPRESOURCE_CLASS に関する情報は msdn で入手できません。

このコード行が正しいかどうかはわかりません。

 mpResourceInfo.Class = IntPtr.Zero;

アップデート:

クイック スキャンは、次のコードで正常に動作します。

result = MpScanStart(phMpHandle, 1, 0, IntPtr.Zero, IntPtr.Zero, out phScanHandle);

Defender は、イベント ビューア [アプリケーションとサービス ログ - Microsoft-Windows-Windows Defender/Operational] に次のように記録します。

Windows Defender スキャンが開始されました。
スキャン ID:{CDC2AC0D-7648-4313-851C-4D8B7B5EB5CD}
スキャン タイプ:アンチスパイウェア
スキャン パラメータ:クイック スキャン

4

3 に答える 3

3

Antimalware Scan Interfaceを使用して、ファイルのマルウェアをチェックすることができます。

AMSI (Antimalware Scan Interface) は、アプリケーションやサービスをマシン上の任意のマルウェア対策製品と統合できるようにする汎用インターフェイス標準です。ユーザーとそのデータ、アプリケーション、およびワークロードに対して強化されたマルウェア保護を提供します。

Windows 10 以降で利用できます。

于 2016-12-23T13:37:42.260 に答える
3

私は問題について検索してきましたが、考えられる原因の1つとしてこれを読みました:

「デバッグ ビルドにはデバッグを支援する追加のメタデータが含まれているため、デバッグ ビルドとリリース ビルドの違いがよく見られます。」

ここ: https://social.msdn.microsoft.com/Forums/vstudio/en-US/4f48c152-68cd-45ec-a11e-baa7de7f79c3/attempted-to-read-or-write-protected-memory?forum=csharpgeneral

また、「.NET でアクセス違反の例外をキャッチすることは可能ですか?」に対するこの回答を確認する必要があります。MSDN マガジンの破損した状態の例外の処理に関する記事で説明されている詳細については、
...

だから、その答えと記事によると、私は試してみます:

最初に、すべてのアンマネージ コードの署名と COM 相互運用サンクをダブル チェックして、それらが正しいことを確認します。

2番目にこの例外をバイパスするようにVisual Studioデバッガーを設定します。ツールメニュー->オプション->デバッグ->一般->このオプション「モジュールの読み込み時にJIT最適化を抑制する」のチェックを外します

3 回目の Try-Catch 例外

(注: .Net 4 を使用している場合は、App.config で、タグ内でランタイムを変更して legacyCorruptedStateExceptionsPolicy enabled="true" を含めます。

<runtime>
    <legacyCorruptedStateExceptionsPolicy enabled="true"/>
</runtime>

)

さらに、ここでは、一部の .net フレームワーク バージョン (最新のコメントは、回答のコメントの 1 つで 4.6.1 を指しています) にこの例外に関連するバグがあり、解決策は過去にフレームワークをアップグレードしていたことを発見しました。 . また、私が読んだその答えの1つで:

こんにちは 2 つの理由が考えられます。

1. アンマネージ コードがあり、マネージ コードから呼び出しています。このコードの実行を妨げています。これらのコマンドを実行して、PC を再起動してみてください

コマンド: netsh winsock リセット

cmd.exe を開き、コマンド「netsh winsock reset catalog」を実行します

これらのアプローチのいくつかが問題の解決に役立つかどうかを知りたい.

これが役立つことを本当に願っています。

KR、

ファン

于 2016-12-22T14:49:58.400 に答える