コード例 #1
0
ファイル: AntiDebugger.cs プロジェクト: yicong1352013/antinet
        private static void InitializeManaged()
        {
            void *        clrModuleHandle;
            StringBuilder stringBuilder;

            byte[] clrFile;

            if (_isManagedInitialized)
            {
                return;
            }
            switch (Environment.Version.Major)
            {
            case 2:
                _pIsDebuggerAttached = (byte *)typeof(Debugger).GetMethod("IsDebuggerAttached", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer();
                // 和.NET 4.x不一样,这个Debugger.IsAttached的get属性调用了IsDebuggerAttached(),而不是直通CLR内部。
                clrModuleHandle = GetModuleHandle("mscorwks.dll");
                break;

            case 4:
                _pIsDebuggerAttached = (byte *)typeof(Debugger).GetMethod("get_IsAttached").MethodHandle.GetFunctionPointer();
                // Debugger.IsAttached的get属性是一个有[MethodImpl(MethodImplOptions.InternalCall)]特性的方法,意思是实现在CLR内部,而且没有任何stub,直接指向CLR内部。
                // 通过x64dbg调试,可以知道Debugger.get_IsAttached()对应clr!DebugDebugger::IsDebuggerAttached()。
                clrModuleHandle = GetModuleHandle("clr.dll");
                break;

            default:
                throw new NotSupportedException();
            }
            _isDebuggerAttached = (IsDebuggerAttachedDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)_pIsDebuggerAttached, typeof(IsDebuggerAttachedDelegate));
            if (clrModuleHandle == null)
            {
                throw new InvalidOperationException();
            }
            stringBuilder = new StringBuilder((int)MAX_PATH);
            if (!GetModuleFileName(clrModuleHandle, stringBuilder, MAX_PATH))
            {
                throw new InvalidOperationException();
            }
            clrFile = File.ReadAllBytes(stringBuilder.ToString());
            // 读取CLR模块文件内容
            fixed(byte *pPEImage = clrFile)
            {
                PEInfo     peInfo;
                uint       isDebuggerAttachedRva;
                uint       isDebuggerAttachedFoa;
                byte *     pCodeStart;
                byte *     pCodeCurrent;
                ldasm_data ldasmData;
                bool       is64Bit;

                byte[] opcodes;

                peInfo = new PEInfo(pPEImage);
                isDebuggerAttachedRva = (uint)(_pIsDebuggerAttached - (byte *)clrModuleHandle);
                isDebuggerAttachedFoa = peInfo.ToFOA(isDebuggerAttachedRva);
                pCodeStart            = pPEImage + isDebuggerAttachedFoa;
                pCodeCurrent          = pCodeStart;
                is64Bit = sizeof(void *) == 8;
                opcodes = new byte[0x200];
                // 分配远大于实际函数大小的内存
                while (true)
                {
                    uint length;

                    length = Ldasm.ldasm(pCodeCurrent, &ldasmData, is64Bit);
                    if ((ldasmData.flags & Ldasm.F_INVALID) != 0)
                    {
                        throw new NotSupportedException();
                    }
                    CopyOpcode(&ldasmData, pCodeCurrent, opcodes, (uint)(pCodeCurrent - pCodeStart));
                    if (*pCodeCurrent == 0xC3)
                    {
                        // 找到了第一个ret指令
                        pCodeCurrent += length;
                        break;
                    }
                    pCodeCurrent += length;
                }
                // 复制Opcode直到出现第一个ret
                _isDebuggerAttachedLength = (uint)(pCodeCurrent - pCodeStart);

                fixed(byte *pOpcodes = opcodes)
                _isDebuggerAttachedCrc32 = DynamicCrc32.Compute(pOpcodes, _isDebuggerAttachedLength);
            }

            _isManagedInitialized = true;
        }