功能:
把指定名称网卡
的mac地址修改成指定值
。
使用方法:
调用set_mac函数,传入参数,1. 网卡名字
和2.要修改成的mac地址
即可。
例如:
set_mac("以太网", "005056C00008")
思路:
- 如何修改mac地址?
修改注册表中相应的值,然后重启网卡。细节见set_mac函数。 - 如何修改注册表的值?
调用修改注册表值的powershell命令。细节见set_mac函数。 - 如何根据网卡名称找到网卡对应的注册表项?
调用powershell命令,然后查询结果。细节见set_mac函数。 - 如何重启网卡?
先调用关闭网卡powershll命令,再调用开启网卡的powershell命令。细节见set_mac函数。 - 如何调用powershell命令?
通过subprocess标准库中的subprocess.run函数来调用。细节见exec_powershell_sync函数。
根据这个思路,很容易写出其他语言版本的修改mac地址的代码。
代码:
import subprocess
import sys
import json
import uuid
class LOG_LEVEL:
ERROR = 3
WARN = 2
INFO = 1
DEBUG = 0
CUR_LOG_LEVEL = LOG_LEVEL.DEBUG
def log(message: str, level: int):
if CUR_LOG_LEVEL <= level:
if level >= LOG_LEVEL.WARN:
print(message, file=sys.stderr)
else:
print(message)
def exec_powershell_sync(command: str, capture: bool = True) -> {}:
ps_ret = subprocess.run(
["powershell", command],
capture_output=capture, text=True)
# log(ps_ret.stdout, LOG_LEVEL.DEBUG)
log("execute command: %s ..." % command, LOG_LEVEL.DEBUG)
log(ps_ret.stderr, LOG_LEVEL.ERROR)
res = dict()
res["success"] = 0 == ps_ret.returncode
res["stderr"] = ps_ret.stderr
if not res["success"]:
exit()
res["stdout"] = ps_ret.stdout
res["obj"] = dict()
for line in ps_ret.stdout.splitlines():
if ':' not in line:
continue
res["obj"][line.split(":")[0].strip()] = line.split(":")[1].strip()
return res
def set_mac(adapter_name: str, mac: str) -> bool:
ret_lines = exec_powershell_sync("netsh i i show in")["stdout"].splitlines()
interface_index = ""
for line in ret_lines[3:]:
if adapter_name == " ".join(line.split()[4:]):
interface_index = line.split()[0]
break
if "" == interface_index:
log("failed to find net adapter named %s" % adapter_name, LOG_LEVEL.ERROR)
exit()
device_id = int(
exec_powershell_sync("wmic nic where interfaceindex=%s get deviceid" % interface_index)["stdout"].splitlines()[
2])
regist_path = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{" \
"4d36e972-e325-11ce-bfc1-08002be10318}\\" + ("%04u" % device_id)
exec_powershell_sync("reg add \"%s\" /v NetworkAddress /t REG_SZ /d %s /f" % (regist_path, mac))
exec_powershell_sync("netsh interface set interface name=\"%s\" admin=disable" % adapter_name)
exec_powershell_sync("netsh interface set interface name=\"%s\" admin=enable" % adapter_name)