c# - 조직에서 - 윈도우10 바이러스 및 위협 방지 오류




C#[AccessViolation 예외]에서 Windows Defender 바이러스 백신 검색 (2)

우리는 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;
    }

이 코드는에서 제공되는 설명서를 기반으로 작성되었습니다.

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 - msdn에서 MPRESOURCE_CLASS에 대한 정보를 사용할 수 없습니다.

이 코드 줄이 맞는지 확실하지 않습니다.

 mpResourceInfo.Class = IntPtr.Zero;

최신 정보:

빠른 검사가이 코드로 잘 작동합니다.

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

Defender는 이벤트 뷰어에 로그인합니다. [응용 프로그램 및 서비스 로그 - Microsoft-Windows-Windows Defender / Operational] as

Windows Defender 검사가 시작되었습니다.
스캔 ID : {CDC2AC0D-7648-4313-851C-4D8B7B5EB5CD}
검사 유형 : AntiSpyware
스캔 매개 변수 : 빠른 스캔


나는 문제에 대해 조사해 왔으며 이것을 가능한 원인 중 하나로 읽었다.

"디버그 빌드에는 디버깅을 돕기 위해 추가 메타 데이터가 포함되어 있기 때문에 디버그 빌드와 릴리스 빌드의 차이점을 자주 볼 수 있습니다."

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

또한 이 대답 을 확인해야합니다 ".NET에서 액세스 위반 예외를 catch 할 수 있습니까?" MSDN 매거진의 손상된 주 예외 처리 문서에서 설명하는 자세한 내용
...

그래서, 그 답변과 기사에 따르면 나는 시도했다.

모든 관리되지 않는 코드가 올바른지 확인하기 위해 첫 번째 Double 서명과 COM interop 썽크를 확인합니다.

두 번째 Visual Studio 디버거에서이 예외를 무시하도록 설정 : 도구 메뉴 -> 옵션 -> 디버깅 -> 일반 ->이 옵션 선택 취소 "모듈로드시 JIT 최적화 무시"

세 번째 try-catch 예외

(참고 : .Net 4를 App.config에서 사용하는 경우 태그 수정 시간 내에 legacyCorruptedStateExceptionsPolicy enabled = "true"를 포함하도록 수정하십시오.

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

)

또한, here 에서는 일부 .net 프레임 워크 버전 (답변의 의견 중 하나 인 4.6.1에 대한 최신 주석 포인트)에이 예외와 관련된 버그가 있으며 해결책은 이전에 프레임 워크를 업그레이드하고 있음을 발견했습니다. . 또한, 그 대답 중 하나에서 나는 읽었습니다 :

안녕 가능성은 두 가지가 있습니다.

1. 우리는 관리되지 않는 코드를 가지고 있으며 관리되는 코드에서 호출하고 있습니다. 이 코드를 실행할 수 없습니다. 이 명령을 실행하고 PC를 다시 시작하십시오.

cmd : netsh winsock 재설정

cmd.exe를 열고 "netsh winsock reset catalog"명령을 실행합니다. 2. 안티 바이러스는 관리되지 않는 코드를 유해한 것으로 간주하고이 코드를 실행하여 안티 바이러스를 비활성화 한 다음 확인합니다

이 접근법 중 일부가 문제를 해결하는 데 도움이되는지 알고 싶습니다.

나는 이것이 정말로 도움이되기를 정말로 바랍니다.

KR,

후안


나는 여기서 문제를 확인할 수 없었다. 그래서 나는 Antimalware Scan Interface (AMSI)를 Windows 10부터 사용할 수있게되었습니다.

midhunlalg.blogspot.in/2016/12/… 샘플 C # 코드를 작성했습니다.
내가 찾은 한 가지는 AMSI가 API에 전달 된 파일을 확인하기 위해 Windows 수비수 / 모든 바이러스 백신을 켜야한다는 것입니다. 그러나 MpClient.dll 을 통해 검색을 실행하면 수비수가 꺼져 있어도 수비수가 검색됩니다.

또한 프로젝트가 x64 플랫폼을 대상으로하고 있는지 확인하십시오.

public enum AMSI_RESULT
    {
        AMSI_RESULT_CLEAN = 0,
        AMSI_RESULT_NOT_DETECTED = 1,
        AMSI_RESULT_DETECTED = 32768
    }

[DllImport("Amsi.dll", EntryPoint = "AmsiInitialize", CallingConvention = CallingConvention.StdCall)]
public static extern int AmsiInitialize([MarshalAs(UnmanagedType.LPWStr)]string appName, out IntPtr amsiContext);

[DllImport("Amsi.dll", EntryPoint = "AmsiUninitialize", CallingConvention = CallingConvention.StdCall)]
public static extern void AmsiUninitialize(IntPtr amsiContext);

[DllImport("Amsi.dll", EntryPoint = "AmsiOpenSession", CallingConvention = CallingConvention.StdCall)]
public static extern int AmsiOpenSession(IntPtr amsiContext, out IntPtr session);

[DllImport("Amsi.dll", EntryPoint = "AmsiCloseSession", CallingConvention = CallingConvention.StdCall)]
public static extern void AmsiCloseSession(IntPtr amsiContext, IntPtr session);

[DllImport("Amsi.dll", EntryPoint = "AmsiScanString", CallingConvention = CallingConvention.StdCall)]
public static extern int AmsiScanString(IntPtr amsiContext, [InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)]string @string, [InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)]string contentName, IntPtr session, out AMSI_RESULT result);
[DllImport("Amsi.dll", EntryPoint = "AmsiScanBuffer", CallingConvention = CallingConvention.StdCall)]
public static extern int AmsiScanBuffer(IntPtr amsiContext, [In] [MarshalAs(UnmanagedType.LPArray)] byte[] buffer, ulong length, [In()] [MarshalAs(UnmanagedType.LPWStr)] string contentName, IntPtr session, out AMSI_RESULT result);

//This method apparently exists on MSDN but not in AMSI.dll (version 4.9.10586.0)
[DllImport("Amsi.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern bool AmsiResultIsMalware(AMSI_RESULT result);

private void CallAntimalwareScanInterface()
{
    IntPtr amsiContext;
    IntPtr session;
    AMSI_RESULT result = 0;
    int returnValue;

    returnValue = AmsiInitialize("VirusScanAPI", out amsiContext); //appName is the name of the application consuming the Amsi.dll. Here my project name is VirusScanAPI.   
    returnValue = AmsiOpenSession(amsiContext, out session);
    returnValue = AmsiScanString(amsiContext, @"X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*", "EICAR", session, out result); //I've used EICAR test string.   
    AmsiCloseSession(amsiContext, session);
    AmsiUninitialize(amsiContext);
}




windows-defender