KMS激活工具之TunMirror原理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LeoForBest/article/details/86560229

声明:此文仅供技术交流,任何由此产生的法律版权问题概不负责,谢谢。若涉及商业应用,请购买正版!

工作原理

Win8.1及以上版本,会检测请求的KMS服务器是否是在本地运行,因此监听在127.0.0.0/24以及本地网卡上,执行激活会失败
大致有两种绕过方式
1.Hook系统函数
2.安装虚拟网卡,使用tunmirror绕过

本代码反编译自TunMirror.exe并加以修改

  • 导入VPN证书(防止静默安装VPN时候提示是否安装该驱动),安装OpenVPN
  • 设置相应IP地址并启动tunmirror服务
  • tunmirror代理发往对应网段的请求到本地端口

**OpenVPN安装包和证书可以在网上找到, 如KMSPico

TunMirror
在这里插入图片描述

TunTap.cs

using System;
using System.IO;
using System.Threading;
using System.Management;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;


namespace TunMirror
{
    class TunTap
    {
        // Fields
        private static int _bytesRead;
        private static FileStream _tap;
        private static EventWaitHandle _waitObject;
        private static EventWaitHandle _waitObject2;
        private const uint FileAnyAccess = 0;
        private const int FileAttributeSystem = 4;
        private const uint FileDeviceUnknown = 0x22;
        private const int FileFlagOverlapped = 0x40000000;
        private const uint MethodBuffered = 0;

        public string IP;
        public string MASK;

        public TunTap(string ip, string mask)
        {
            IP = ip;
            MASK = mask;
        }


        // Methods
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CreateFile(string filename, [MarshalAs(UnmanagedType.U4)] FileAccess fileaccess, [MarshalAs(UnmanagedType.U4)] FileShare fileshare, int securityattributes, [MarshalAs(UnmanagedType.U4)] FileMode creationdisposition, int flags, IntPtr template);
        private static uint CtlCode(uint deviceType, uint function, uint method, uint access)
        {
            return ((((deviceType << 0x10) | (access << 14)) | (function << 2)) | method);
        }

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
        private static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer, uint nOutBufferSize, out int lpBytesReturned, IntPtr lpOverlapped);
        private static string GetDeviceGuid()
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(@"root\CIMV2", "SELECT GUID FROM Win32_NetworkAdapter WHERE ServiceName = 'tap0901'");
            foreach (ManagementObject obj2 in searcher.Get())
            {
                if (obj2["GUID"].ToString() != string.Empty)
                {
                    return obj2["GUID"].ToString();
                }
            }
            return string.Empty;
        }

        private static uint TapControlCode(uint request, uint method)
        {
            return CtlCode(0x22, request, method, 0);
        }

        public static Int32 IPInfoToInt32(string s)
        {
            Regex regex = new Regex(@"\d+\.\d+\.\d+\.\d+");
            if (!regex.IsMatch(s))
            {
                Console.WriteLine(String.Format("{0}格式有误", s));
                Environment.Exit(1);
            }
            string[] sList = s.Split('.');
            Int32 ret = 0;
            try
            {
                for (int i = 0; i < 4; i++)
                {
                    Int32 j = System.Convert.ToInt32(sList[i]);
                    if (j > 255) { throw new FormatException(); }
                    ret += j * (int)Math.Pow(256, i);
                }
            }
            catch (FormatException)
            {
                Console.WriteLine(String.Format("{0}格式有误", s));
                Environment.Exit(1);
            }
            return ret;
        }

        [STAThread]
        public void ThreadLoop()
        {
            int num;
            string deviceGuid = GetDeviceGuid();
            IntPtr hDevice = CreateFile(@"\\.\Global\" + deviceGuid + ".tap", FileAccess.ReadWrite, FileShare.ReadWrite, 0, FileMode.Open, 0x40000004, IntPtr.Zero);
            IntPtr ptr = Marshal.AllocHGlobal(4);
            Marshal.WriteInt32(ptr, 1);
            // TAP_IOCTL_CONFIG_POINT_TO_POINT = TAP_CONTROL_CODE(5, 0)
            // TAP_IOCTL_SET_MEDIA_STATUS = TAP_CONTROL_CODE(6, 0)
            // TAP_IOCTL_CONFIG_TUN = TAP_CONTROL_CODE(10, 0)
            // #define TAP_WIN_IOCTL_GET_MAC               TAP_WIN_CONTROL_CODE (1, METHOD_BUFFERED)
            // #define TAP_WIN_IOCTL_GET_VERSION           TAP_WIN_CONTROL_CODE (2, METHOD_BUFFERED)
            // #define TAP_WIN_IOCTL_GET_MTU               TAP_WIN_CONTROL_CODE (3, METHOD_BUFFERED)
            // #define TAP_WIN_IOCTL_GET_INFO              TAP_WIN_CONTROL_CODE (4, METHOD_BUFFERED)
            // #define TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT TAP_WIN_CONTROL_CODE (5, METHOD_BUFFERED)
            // #define TAP_WIN_IOCTL_SET_MEDIA_STATUS      TAP_WIN_CONTROL_CODE (6, METHOD_BUFFERED)
            // #define TAP_WIN_IOCTL_CONFIG_DHCP_MASQ      TAP_WIN_CONTROL_CODE (7, METHOD_BUFFERED)
            // #define TAP_WIN_IOCTL_GET_LOG_LINE          TAP_WIN_CONTROL_CODE (8, METHOD_BUFFERED)
            // #define TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT   TAP_WIN_CONTROL_CODE (9, METHOD_BUFFERED)
            // #define TAP_WIN_IOCTL_CONFIG_TUN            TAP_WIN_CONTROL_CODE (10, METHOD_BUFFERED)
            // https://gist.github.com/glacjay/586892
            // https://bbs.csdn.net/topics/392438702
            DeviceIoControl(hDevice, TapControlCode(6, 0), ptr, 4, ptr, 4, out num, IntPtr.Zero);
            IntPtr ptr3 = Marshal.AllocHGlobal(12);
            Int32 ip = IPInfoToInt32(IP);
            Int32 mask = IPInfoToInt32(MASK);
            Marshal.WriteInt32(ptr3, 0, ip);
            Marshal.WriteInt32(ptr3, 4, ip & mask);
            Marshal.WriteInt32(ptr3, 8, mask);
            DeviceIoControl(hDevice, TapControlCode(10, 0), ptr3, 12, ptr3, 12, out num, IntPtr.Zero);
            // _tap = new FileStream(hDevice, FileAccess.ReadWrite, true, 0x2710, true);
            _tap = new FileStream(new SafeFileHandle(hDevice, true), FileAccess.ReadWrite, 0x2710, true);
            byte[] buffer = new byte[0x2710];
            object state = 0;
            _waitObject = new EventWaitHandle(false, EventResetMode.AutoReset);
            object obj3 = 0;
            _waitObject2 = new EventWaitHandle(false, EventResetMode.AutoReset);
            AsyncCallback callback = new AsyncCallback(TunTap.ReadDataCallback);
            AsyncCallback callback2 = new AsyncCallback(TunTap.WriteDataCallback);
            while (Thread.CurrentThread.IsAlive)
            {
                _tap.BeginRead(buffer, 0, 0x2710, callback, state);
                _waitObject.WaitOne();
                string src = String.Format("{0}.{1}.{2}.{3}", buffer[12], buffer[13], buffer[14], buffer[15]);
                string dst = String.Format("{0}.{1}.{2}.{3}", buffer[16], buffer[17], buffer[18], buffer[19]);
                string srcPort = String.Format("{0}", Convert.ToInt32(buffer[20]) * 256 + Convert.ToInt32(buffer[21]));
                string dstPort = String.Format("{0}", Convert.ToInt32(buffer[22]) * 256 + Convert.ToInt32(buffer[23]));
                for (int i = 0; i < 4; i++)
                {
                    byte num3 = buffer[12 + i];
                    buffer[12 + i] = buffer[0x10 + i];
                    buffer[0x10 + i] = num3;
                }
                Console.WriteLine(String.Format("数据帧{0}:{1} -> {2}:{3} 转换为 {4}:{5} -> {6}:{7} 共 {8} 字节", src, srcPort, dst, dstPort, dst, srcPort, src, dstPort, _bytesRead));
                _tap.BeginWrite(buffer, 0, _bytesRead, callback2, obj3);
                _waitObject2.WaitOne();
            }
        }

        public static void ReadDataCallback(IAsyncResult asyncResult)
        {
            try
            {
                _bytesRead = _tap.EndRead(asyncResult);
            }
            catch { }
            _waitObject.Set();
        }

        public static void WriteDataCallback(IAsyncResult asyncResult)
        {
            try
            {
                _tap.EndWrite(asyncResult);
            }
            catch { }
            _waitObject2.Set();
        }
    }
}

Program.cs

using System;
using System.Threading;
using System.Diagnostics;
using System.Management;

namespace TunMirror
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "Leo's TunMirror";
            Console.ForegroundColor = ConsoleColor.Green;
            if(args.Length != 0 && args.Length != 2 && !(args.Length == 1 && args[0] == "/u"))
            {
                Console.WriteLine(@"用法: 

TunMirror.exe 不带任何参数
    执行安装并设置默认IP地址: 10.3.0.1  子网掩码: 255.255.255.0

TunMirror.exe  IP地址 子网掩码
    EX: TunMirror.exe   192.168.1.1 255.255.255.0
    执行安装,并根据参数设置VPN网卡地址

TunMirror.exe   /u
    如果检测到安装了openvpn虚拟网卡,则卸载!

");
                Console.ReadKey();
                Environment.Exit(0);
            }

            if(args.Length == 1 && args[0] == "/u")
            {
                UninstallVPN();
                Environment.Exit(0);
            }

            TunTap tun;

            if(args.Length == 2)
            {
                tun = new TunTap(args[0], args[1]);
            }
            else
            {
                tun = new TunTap("10.3.0.1", "255.255.255.0");
            }
            // 安装VPN, 并设置IP
            bool bInstalled = IsVPNInstalled();
            if(!bInstalled)
            {
                InstallCert();
            }
            InstallVPN(tun.IP, tun.MASK, bInstalled);

            // 启动线程
            Console.WriteLine("正在启动TunMirror服务....\n");
            Thread th = new Thread(tun.ThreadLoop);
            th.Start();
            Console.WriteLine("TunMirror服务已启动...\n");
            Console.ForegroundColor = ConsoleColor.Yellow;
        }

        public static bool IsVPNInstalled()
        {
            ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection objMCC = objMC.GetInstances();
            foreach (ManagementObject objMO in objMCC)
            {
                if (((string)objMO["Description"]).Contains("TAP-Windows"))
                {
                    return true;
                }
            }
            return false;
        }

        public static void InstallCert()
        {
            ProcessStartInfo procInfo = new ProcessStartInfo
            {
                FileName = "certutil",
                Arguments = "-addstore -f \"TrustedPublisher\" \"" + Environment.CurrentDirectory + "\\TrustTAP.cer\"",
                WorkingDirectory = Environment.CurrentDirectory,
                CreateNoWindow = true,
                WindowStyle = ProcessWindowStyle.Hidden
            };
            Process ps = new Process { StartInfo = procInfo };
            Console.WriteLine("正在安装证书:");
            Console.WriteLine(procInfo.FileName + " " + procInfo.Arguments + "\n");
            try
            {
                ps.Start();
                ps.WaitForExit();
            }
            catch { }
        }

        public static void UninstallVPN()
        {
            ProcessStartInfo procInfo = new ProcessStartInfo
            {
                FileName = Environment.GetEnvironmentVariable("SystemDrive") + "\\Program Files\\TAP-Windows\\Uninstall.exe",
                Arguments = "/S",
                WorkingDirectory = Environment.GetEnvironmentVariable("SystemDrive") + "\\Program Files\\TAP-Windows",
            };
            Console.WriteLine("正在卸载VPN...");
            Process ps = new Process { StartInfo = procInfo };
            try
            {
                ps.Start();
                ps.WaitForExit();
            }
            catch { }
        }

        public static void InstallVPN(string ip, string mask, bool bInstall)
        {
            if (bInstall) { goto SETIP; }
            ProcessStartInfo procInfo = new ProcessStartInfo
            {
                FileName = Environment.CurrentDirectory + "\\tap.exe",
                Arguments = "/S",
                WorkingDirectory = Environment.CurrentDirectory,
            };
            Process ps = new Process { StartInfo = procInfo };
            Console.WriteLine("正在安装OpenVPN虚拟网卡...\n");
            try
            {
                ps.Start();
                ps.WaitForExit();
            }
            catch { }
            Thread.Sleep(4000);
            // set ip
            SETIP:
            Console.WriteLine("正在为虚拟网卡设置IP地址...\n");
            ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection objMCC = objMC.GetInstances();
            foreach (ManagementObject objMO in objMCC)
            {
                if (((string)objMO["Description"]).Contains("TAP-Windows"))
                {
                    ManagementBaseObject newIP = objMO.GetMethodParameters("EnableStatic");
                    newIP["IPAddress"] = new string[] { ip };
                    newIP["SubnetMask"] = new string[] { mask };
                    objMO.InvokeMethod("EnableStatic", newIP, null);
                    objMO.InvokeMethod("EnableStatic", newIP, null);
                    break;
                }
            }
            Thread.Sleep(4000);
        }

    }
}

示例

虚拟网卡设置为10.3.0.1
在这里插入图片描述

启动TunMirror,并执行激活命令

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/LeoForBest/article/details/86560229