|
| 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 | +importsubprocess |
| 14 | +importwinreg |
| 15 | +importre |
| 16 | +importcodecs |
| 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 | +formacAddingetmac_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 | +ifmacFind==NoneortransportFind==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 | +forindex,iteminenumerate(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 | +whileTrue: |
| 81 | +print("Which MAC address do you want to use? This will change the Network Card's MAC address.") |
| 82 | +forindex,iteminenumerate(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 | +ifint(update_option)>=0andint(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 | +withwinreg.ConnectRegistry(None,winreg.HKEY_LOCAL_MACHINE)ashkey: |
| 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)ifitem<10else"\\00"+str(item))foriteminrange(0,21)] |
| 104 | +# We now iterate through the list of folders we created. |
| 105 | +forkey_folderincontroller_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 | +withwinreg.OpenKey(hkey,controller_key_part+key_folder,0,winreg.KEY_ALL_ACCESS)asregkey: |
| 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 | +whileTrue: |
| 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 | +ifname=="NetCfgInstanceId"andvalue==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 | +exceptWindowsError: |
| 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 | +ifrun_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 | +whilerun_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 | +foradapterinnetwork_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 | +ifadapter_index_findand"Wireless"inadapter: |
| 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])foriinrange(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 | +ifmac_addingetmac_output: |
| 174 | +print("Mac Address Success") |
| 175 | +# Break out of the While loop. Could also change run_last_part to False. |
| 176 | +break |