|
| 1 | +################################################################################################## |
| 2 | +#Copyright of David Bombal, 2021 # |
| 3 | +#https://www.davidbombal.com # |
| 4 | +#https://www.youtube.com/davidbombal # |
| 5 | +# # |
| 6 | +# Please note that this code can be improved by using functions. It is not programmed to cater # |
| 7 | +# for all situations, but to be used as a learning tool. # |
| 8 | +# # |
| 9 | +# This code is provided for educational purposes only. Do good. Be Ethical. # |
| 10 | +# # |
| 11 | +################################################################################################## |
| 12 | + |
| 13 | +import subprocess |
| 14 | +import winreg |
| 15 | +import re |
| 16 | +import codecs |
| 17 | + |
| 18 | +print("##############################################################") |
| 19 | +print("1) Make sure you run this script with administrator privileges") |
| 20 | +print("2) Make sure that the WiFi adapter is connected to a network") |
| 21 | +print("##############################################################\n") |
| 22 | + |
| 23 | +# MAC Addresses to attempt using. You will select one when the script is used. |
| 24 | +# You can change the names in this list or add names to this list. |
| 25 | +# Make sure you use 12 valid hexadecimal values. |
| 26 | +# If the MAC address change fails try setting the second character to 2 or 6 or A or E, |
| 27 | +# for example: 0A1122334455 or 0A5544332211 |
| 28 | +# If unsure, leave the MAC addresses listed here as is. |
| 29 | +mac_to_change_to = ["0A1122334455", "0E1122334455", "021122334455", "061122334455", "0ADEADBEEF01", "0AFACEB00K01"] |
| 30 | + |
| 31 | +# We create an empty list where we'll store all the MAC addresses. |
| 32 | +mac_addresses = list() |
| 33 | + |
| 34 | +# We start off by creating a regular expression (regex) for MAC addresses. |
| 35 | +macAddRegex = re.compile(r"([A-Za-z0-9]{2}[:-]){5}([A-Za-z0-9]{2})") |
| 36 | + |
| 37 | +# We create a regex for the transport names. It will work in this case. |
| 38 | +# But when you use the .+ or .*, you should consider making it not as greedy. |
| 39 | +transportName = re.compile("({.+})") |
| 40 | + |
| 41 | +# We create regex to pick out the adapter index |
| 42 | +adapterIndex = re.compile("([0-9]+)") |
| 43 | + |
| 44 | +# Python allows us to run system commands by using a function provided by the subprocess module: |
| 45 | +# (subprocess.run(<list of command line arguments goes here>, |
| 46 | +# <specify the second argument if you want to capture the output>)) |
| 47 | +# The script is a parent process and creates a child process which runs the system command, |
| 48 | +# and will only continue once the child process has completed. |
| 49 | +# To save the content that gets sent to the standard output stream (the terminal), |
| 50 | +# we have to specify that we want to capture the output, so we specify the second |
| 51 | +# argument as capture_output = True. This information gets stored in the stdout attribute. |
| 52 | +# The information is stored in bytes and we need to decode it to Unicode before we use it |
| 53 | +# as a String in Python. |
| 54 | +# We use Python to run the getmac command, and then capture the output. |
| 55 | +# We split the output at the newline so that we can work with the individual lines |
| 56 | +# (which will contain the Mac and transport name). |
| 57 | +getmac_output = subprocess.run("getmac", capture_output=True).stdout.decode().split('\n') |
| 58 | + |
| 59 | +# We loop through the output |
| 60 | +for macAdd in getmac_output: |
| 61 | + # We use the regex to find the Mac Addresses. |
| 62 | + macFind = macAddRegex.search(macAdd) |
| 63 | + # We use the regex to find the transport name. |
| 64 | + transportFind = transportName.search(macAdd) |
| 65 | + # If you don't find a Mac Address or Transport name the option won't be listed. |
| 66 | + if macFind == None or transportFind == None: |
| 67 | + continue |
| 68 | + # We append a tuple with the Mac Address and the Transport name to a list. |
| 69 | + mac_addresses.append((macFind.group(0),transportFind.group(0))) |
| 70 | + |
| 71 | +# Create a simple menu to select which Mac Address the user want to update. |
| 72 | +print("Which MAC Address do you want to update?") |
| 73 | +for index, item in enumerate(mac_addresses): |
| 74 | + print(f"{index} - Mac Address: {item[0]} - Transport Name: {item[1]}") |
| 75 | + |
| 76 | +# Prompt the user to select Mac Address they want to update. |
| 77 | +option = input("Select the menu item number corresponding to the MAC that you want to change:") |
| 78 | + |
| 79 | +# Create a simple menu so the user can pick a MAC address to use |
| 80 | +while True: |
| 81 | + print("Which MAC address do you want to use? This will change the Network Card's MAC address.") |
| 82 | + for index, item in enumerate(mac_to_change_to): |
| 83 | + print(f"{index} - Mac Address: {item}") |
| 84 | + |
| 85 | + # Prompt the user to select the MAC address they want to change to. |
| 86 | + update_option = input("Select the menu item number corresponding to the new MAC address that you want to use:") |
| 87 | + # Check to see if the option the user picked is a valid option. |
| 88 | + if int(update_option) >= 0 and int(update_option) < len(mac_to_change_to): |
| 89 | + print(f"Your Mac Address will be changed to: {mac_to_change_to[int(update_option)]}") |
| 90 | + break |
| 91 | + else: |
| 92 | + print("You didn't select a valid option. Please try again!") |
| 93 | + |
| 94 | +# We know the first part of the key, we'll append the folders where we'll search the values |
| 95 | +controller_key_part = r"SYSTEM\ControlSet001\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}" |
| 96 | + |
| 97 | +# We connect to the HKEY_LOCAL_MACHINE registry. If we specify None, |
| 98 | +# it means we connect to local machine's registry. |
| 99 | +with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as hkey: |
| 100 | + # Create a list for the 21 folders. I used a list comprehension. The expression part of the list comprehension |
| 101 | + # makes use of a ternary operator. The transport value for you Mac Address should fall within this range. |
| 102 | + # You could write multiple lines. |
| 103 | + controller_key_folders = [("\\000" + str(item) if item < 10 else "\\00" + str(item)) for item in range(0, 21)] |
| 104 | + # We now iterate through the list of folders we created. |
| 105 | + for key_folder in controller_key_folders: |
| 106 | + # We try to open the key. If we can't we just except and pass. But it shouldn't be a problem. |
| 107 | + try: |
| 108 | + # We have to specify the registry we connected to, the controller key |
| 109 | + # (This is made up of the controller_key_part we know and the folder(key) name we created |
| 110 | + # with the list comprehension). |
| 111 | + with winreg.OpenKey(hkey, controller_key_part + key_folder, 0, winreg.KEY_ALL_ACCESS) as regkey: |
| 112 | + # We will now look at the Values under each key and see if we can find the "NetCfgInstanceId" |
| 113 | + # with the same Transport Id as the one we selected. |
| 114 | + try: |
| 115 | + # Values start at 0 in the registry and we have to count through them. |
| 116 | + # This will continue until we get a WindowsError (Where we will then just pass) |
| 117 | + # then we'll start with the next folder until we find the correct key which contains |
| 118 | + # the value we're looking for. |
| 119 | + count = 0 |
| 120 | + while True: |
| 121 | + # We unpack each individual winreg value into name, value and type. |
| 122 | + name, value, type = winreg.EnumValue(regkey, count) |
| 123 | + # To go to the next value if we didn't find what we're looking for we increment count. |
| 124 | + count = count + 1 |
| 125 | + # We check to see if our "NetCfgInstanceId" is equal to our Transport number for our |
| 126 | + # selected Mac Address. |
| 127 | + if name == "NetCfgInstanceId" and value == mac_addresses[int(option)][1]: |
| 128 | + new_mac_address = mac_to_change_to[int(update_option)] |
| 129 | + winreg.SetValueEx(regkey, "NetworkAddress", 0, winreg.REG_SZ, new_mac_address) |
| 130 | + print("Successly matched Transport Number") |
| 131 | + # get list of adapters and find index of adapter you want to disable. |
| 132 | + break |
| 133 | + except WindowsError: |
| 134 | + pass |
| 135 | + except: |
| 136 | + pass |
| 137 | + |
| 138 | + |
| 139 | +# Code to disable and enable Wireless devicess |
| 140 | +run_disable_enable = input("Do you want to disable and reenable your wireless device(s). Press Y or y to continue:") |
| 141 | +# Changes the input to lowercase and compares to y. If not y the while function which contains the last part will never run. |
| 142 | +if run_disable_enable.lower() == 'y': |
| 143 | + run_last_part = True |
| 144 | +else: |
| 145 | + run_last_part = False |
| 146 | + |
| 147 | +# run_last_part will be set to True or False based on above code. |
| 148 | +while run_last_part: |
| 149 | + |
| 150 | + # Code to disable and enable the network adapters |
| 151 | + # We get a list of all network adapters. You have to ignore errors, as it doesn't like the format the command returns the data in. |
| 152 | + network_adapters = subprocess.run(["wmic", "nic", "get", "name,index"], capture_output=True).stdout.decode('utf-8', errors="ignore").split('\r\r\n') |
| 153 | + for adapter in network_adapters: |
| 154 | + # We get the index for each adapter |
| 155 | + adapter_index_find = adapterIndex.search(adapter.lstrip()) |
| 156 | + # If there is an index and the adapter has wireless in description we are going to disable and enable the adapter |
| 157 | + if adapter_index_find and "Wireless" in adapter: |
| 158 | + disable = subprocess.run(["wmic", "path", "win32_networkadapter", "where", f"index={adapter_index_find.group(0)}", "call", "disable"],capture_output=True) |
| 159 | + # If the return code is 0, it means that we successfully disabled the adapter |
| 160 | + if(disable.returncode == 0): |
| 161 | + print(f"Disabled {adapter.lstrip()}") |
| 162 | + # We now enable the network adapter again. |
| 163 | + enable = subprocess.run(["wmic", "path", f"win32_networkadapter", "where", f"index={adapter_index_find.group(0)}", "call", "enable"],capture_output=True) |
| 164 | + # If the return code is 0, it means that we successfully enabled the adapter |
| 165 | + if (enable.returncode == 0): |
| 166 | + print(f"Enabled {adapter.lstrip()}") |
| 167 | + |
| 168 | + # We run the getmac command again |
| 169 | + getmac_output = subprocess.run("getmac", capture_output=True).stdout.decode() |
| 170 | + # We recreate the Mac Address as ot shows up in getmac XX-XX-XX-XX-XX-XX format from the 12 character string we have. We split the string into strings of length 2 using list comprehensions and then. We use "-".join(list) to recreate the address |
| 171 | + mac_add = "-".join([(mac_to_change_to[int(update_option)][i:i+2]) for i in range(0, len(mac_to_change_to[int(update_option)]), 2)]) |
| 172 | + # We want to check if Mac Address we changed to is in getmac output, if so we have been successful. |
| 173 | + if mac_add in getmac_output: |
| 174 | + print("Mac Address Success") |
| 175 | + # Break out of the While loop. Could also change run_last_part to False. |
| 176 | + break |
0 commit comments