版权声明:本文为博主原创文章,未经博主允许不得转载。 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
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,并执行激活命令