C# 下调试陷阱/调整权限/剥离调试器/调试自己

    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;

    public partial class ForciblyAdjustPrivilege 
    {
        private abstract class NativeMethods
        {
            [DllImport("ntdll.dll", SetLastError = true)]
            public static unsafe extern int RtlAdjustPrivilege(int Privilege, [MarshalAs(UnmanagedType.Bool)]bool Enable, int CurrentThread, bool* Enabled);

            [DllImport("ntdll.dll", SetLastError = true)]
            public static unsafe extern int NtSetInformationThread(IntPtr ThreadHandle, int ThreadInformationClass, int ThreadInformation, int ThreadInformationLength);

            [DllImport("kerenl32.dll", SetLastError = true)]
            public static unsafe extern IntPtr GetCurrentThread();

            [DllImport("kerenl32.dll", SetLastError = true)]
            public static unsafe extern IntPtr GetCurrentProcess();

            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern int GetCurrentProcessId();

            [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool CheckRemoteDebuggerPresent(IntPtr hProcess, [MarshalAs(UnmanagedType.Bool)]ref bool isDebuggerPresent);

            [DllImport("kernel32.dll", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool IsDebuggerPresent();

            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern bool DebugActiveProcess(int dwProcessId);

            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern bool VirtualProtect(IntPtr lpAddress, int dwSize, int flNewProtect, out uint lpflOldProtect);

            public static bool VirtualProtect(IntPtr lpAddress, int dwSize, int flNewProtect)
            {
                uint lpflOldProtect = NativeMethods.NULL;
                return NativeMethods.VirtualProtect(lpAddress, dwSize, NativeMethods.PAGE_EXECUTE_READWRITE, out lpflOldProtect);
            }

            public const int ERROR_SUCCESS = NULL;
            public const int NT_SUCCESS = NULL;
            public const int NULL = 0;
            public const int SE_DEBUG_PRIVILEGE = 20;
            public const string SE_DEBUG_NAME = "SeDebugPrivilege";
            public const int ThreadHideFromDebugger = 0x11;
            public const int PAGE_EXECUTE_READWRITE = 64;
        }

        public static bool AdjustPrivilege() // 提权
        {
            unsafe
            {
                bool success = false;
                if (NativeMethods.ERROR_SUCCESS != NativeMethods.RtlAdjustPrivilege(
                    NativeMethods.SE_DEBUG_PRIVILEGE, true, 0, &success) && !success)
                {
                    throw new Win32Exception("Unable to get se debug privilege.");
                }
                return success;
            }
        }

        public static bool DetachDebugger(IntPtr hThread) // 强制从线程中分离调试器
        {
            return NativeMethods.NT_SUCCESS == NativeMethods.NtSetInformationThread(hThread, NativeMethods.
                ThreadHideFromDebugger, NativeMethods.NULL, 0);
        }

        public static bool DetachDebugger()
        {
            return ForciblyAdjustPrivilege.DetachDebugger(NativeMethods.GetCurrentThread());
        }

        public static bool CheckRemoteDebuggerPresent(IntPtr hProcess) // 效验内核结构PEB内是否存在调试对象
        {
            bool isDebuggerPresent = false;
            NativeMethods.CheckRemoteDebuggerPresent(hProcess, ref isDebuggerPresent);
            return isDebuggerPresent;
        }

        public static bool CheckRemoteDebuggerPresent()
        {
            return ForciblyAdjustPrivilege.CheckRemoteDebuggerPresent(NativeMethods.GetCurrentProcess());
        }

        public static bool IsDebuggerPresent() // 效验是否被调试(可能会被HOOK,需反HOOK)
        {
            return NativeMethods.IsDebuggerPresent();
        }

        public static bool DebugActiveProcess() // 对自己启动调试,抢占用户调试器调试权限(对WINDBG内核调试工具无效)
        {
            return NativeMethods.DebugActiveProcess(NativeMethods.GetCurrentProcessId());
        }

        public static void DebugActiveTrap() // 调试陷阱,通过汇编在代码段CS寄存器中存放一个调试陷阱
        {
            byte[] asm = { 
                                // push        ebp
                                // mov         ebp,esp
                                // sub         esp,0C0h
                                // push        ebx
                                // push        esi
                                // push        edi
                                // lea         edi,[ebp-0C0h]
                                // mov         ecx,30h
                                // mov         eax,0CCCCCCCCh
                                // rep stos    dword ptr es:[edi]
                                 85, 139, 236, 129, 236, 192, 0, 0, 0, 83, 86, 87, 141, 189, 64, 255, 255,
                                 255, 185, 48, 0, 0, 0, 184, 204, 204, 204, 204, 243, 171,
                                // push        ss
                                // pop         ss
                                // pushfd
                                // pop         eax
                                // and         eax,100
                                // je          short 0000000C
                                // popfd
                                 22, 23, 156, 88, 37, 0, 1, 0, 0, 116, 1, 157,
                                // call        dword ptr[ebp+8]
                                // pop         edi
                                // pop         esi
                                // pop         ebx
                                // mov         esp,ebp
                                // pop         ebp
                                // ret
                                 255, 85, 8, 95, 94, 91, 139, 229, 93, 195
                             };
            if (!NativeMethods.VirtualProtect(Marshal.UnsafeAddrOfPinnedArrayElement(asm, 0), asm.Length, NativeMethods.PAGE_EXECUTE_READWRITE))
            {
                throw new Win32Exception("Unable to set the memory protection.");
            }
            ((Action)Marshal.GetDelegateForFunctionPointer(Marshal.UnsafeAddrOfPinnedArrayElement(asm, 0), typeof(Action))).Invoke();
        }
    }