diff --git a/scapy/arch/windows/__init__.py b/scapy/arch/windows/__init__.py
index e92fdcf605e9dd5be14dfcbba69180a844073198..a5fdbfa9640f50f636e86a3bb9bc6156cf00564a 100755
--- a/scapy/arch/windows/__init__.py
+++ b/scapy/arch/windows/__init__.py
@@ -58,7 +58,7 @@ def _exec_query_ps(cmd, fields):
yield l
l=[]
-def _vbs_exec_code(code):
+def _vbs_exec_code(code, split_tag="@"):
if not WINDOWS:
return
tmpfile = tempfile.NamedTemporaryFile(suffix=".vbs", delete=False)
@@ -71,7 +71,9 @@ def _vbs_exec_code(code):
# skip 3 first lines
ps.stdout.readline()
for line in ps.stdout:
- yield line
+ data = line.replace("\n", "").split(split_tag)
+ for l in data:
+ yield l
os.unlink(tmpfile.name)
def _vbs_get_iface_guid(devid):
@@ -92,7 +94,12 @@ _VBS_WMI_FIELDS = {
"Win32_NetworkAdapter": {
"InterfaceIndex": "Index",
"InterfaceDescription": "Description",
- "GUID": "DeviceID",
+ }
+}
+
+_VBS_WMI_REPLACE = {
+ "Win32_NetworkAdapterConfiguration": {
+ "line.IPAddress": "\"{\" & Join( line.IPAddress, \", \" ) & \"}\"",
}
}
@@ -103,16 +110,20 @@ _VBS_WMI_OUTPUT = {
}
def _exec_query_vbs(cmd, fields):
- if not WINDOWS:
- return
"""Execute a query using VBS. Currently Get-WmiObject queries are
supported.
-
"""
if not WINDOWS:
return
- assert len(cmd) == 2 and cmd[0] == "Get-WmiObject"
+ if not(len(cmd) == 2 and cmd[0] == "Get-WmiObject"):
+ return
+
fields = [_VBS_WMI_FIELDS.get(cmd[1], {}).get(fld, fld) for fld in fields]
+ parsed_command = "WScript.Echo " + " & \" @ \" & ".join("line.%s" % fld for fld in fields
+ if fld is not None)
+ # The IPAddress is an array: convert it to a string
+ for key,val in _VBS_WMI_REPLACE.get(cmd[1], {}).items():
+ parsed_command = parsed_command.replace(key, val)
values = _vbs_exec_code("""Set wmi = GetObject("winmgmts:")
Set lines = wmi.InstancesOf("%s")
On Error Resume Next
@@ -120,8 +131,8 @@ Err.clear
For Each line in lines
%s
Next
-""" % (cmd[1], "\n ".join("WScript.Echo line.%s" % fld for fld in fields
- if fld is not None))).__iter__()
+""" % (cmd[1], parsed_command), "@")
+
while True:
yield [None if fld is None else
_VBS_WMI_OUTPUT.get(cmd[1], {}).get(fld, lambda x: x)(
@@ -132,7 +143,6 @@ Next
def exec_query(cmd, fields):
"""Execute a system query using PowerShell if it is available, and
using VBS/cscript as a fallback.
-
"""
if conf.prog.powershell is None:
return _exec_query_vbs(cmd, fields)
@@ -171,8 +181,10 @@ def win_find_exe(filename, installsubdir=None, env="ProgramFiles"):
return path
-def is_new_release():
+def is_new_release(ignoreVBS=False):
release = platform.release()
+ if conf.prog.powershell is None and not ignoreVBS:
+ return False
try:
if float(release) >= 8:
return True
@@ -211,6 +223,9 @@ import platform
def is_interface_valid(iface):
if "guid" in iface and iface["guid"]:
+ # Fix '-' instead of ':'
+ if "mac" in iface:
+ iface["mac"] = iface["mac"].replace("-", ":")
return True
return False
@@ -225,6 +240,7 @@ def get_windows_if_list():
query = exec_query(['Get-NetAdapter'],
['InterfaceDescription', 'InterfaceIndex', 'Name',
'InterfaceGuid', 'MacAddress']) # It is normal that it is in this order
+
else:
query = exec_query(['Get-WmiObject', 'Win32_NetworkAdapter'],
['Name', 'InterfaceIndex', 'InterfaceDescription',
@@ -388,7 +404,7 @@ pcapdnet.open_pcap = lambda iface,*args,**kargs: _orig_open_pcap(pcapname(iface)
_orig_get_if_raw_hwaddr = pcapdnet.get_if_raw_hwaddr
pcapdnet.get_if_raw_hwaddr = lambda iface, *args, **kargs: (
- ARPHDR_ETHER, mac2str(IFACES.dev_from_pcapname(pcapname(iface)).mac.replace('-', ':'))
+ ARPHDR_ETHER, mac2str(IFACES.dev_from_pcapname(pcapname(iface)).mac)
)
get_if_raw_hwaddr = pcapdnet.get_if_raw_hwaddr
diff --git a/test/mock_windows.uts b/test/mock_windows.uts
index 191938d062d629637678960083bd5ed0e41cf691..65acbeb218a69c86d1c597fdc51495a34f836d68 100644
--- a/test/mock_windows.uts
+++ b/test/mock_windows.uts
@@ -147,3 +147,62 @@ emulate_main_input(data)
from ctypes import wintypes
data = ["#AUTOCOMPLETE{scapy.config.conf.vers}", "assert _ == scapy.config.conf.version"]
emulate_main_input(data)
+
+############
+############
++ Windows arch unit tests
+
+= Test PowerShell availability
+from scapy.config import conf
+assert conf.prog.powershell != None
+
+= Test all VBS fallback
+import mock
+from scapy.config import conf
+
+ps_ip = get_ip_from_name(conf.iface.name)
+ps_if_list = get_windows_if_list()
+ps_read_routes = read_routes()
+
+# Turn on VBS mode
+conf.prog.powershell = None
+
+# Test get_ip_from_name
+assert get_ip_from_name(conf.iface.name) == ps_ip
+
+# Test get_windows_if_list
+
+def is_in_if_list(i, list):
+ for j in list:
+ if j["guid"] == i["guid"] and j["name"] == i["name"]:
+ return True
+ return False
+
+vbs_if_list = get_windows_if_list()
+_correct = True
+for i in ps_if_list:
+ if not is_in_if_list(i, vbs_if_list):
+ _correct = False
+ break
+
+assert _correct
+
+# Test read_routes
+
+def is_in_route_list(i, list):
+ for j in list:
+ #Ignore all empty IP
+ if j[4] == '' or i[4] == '':
+ return True
+ if j[2] == i[2] and j[4] == i[4] and j[3].guid == i[3].guid:
+ return True
+ return False
+
+vbs_read_routes = read_routes()
+_correct = True
+for i in ps_read_routes:
+ if not is_in_route_list(i, vbs_read_routes):
+ _correct = False
+ break
+
+assert _correct