筆記是在寫CyberInterceptor時為了UDP發包而寫下的。
獲取物理網卡方法:
1。遍歷 注冊表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards
2。判斷是否為物理網卡
判斷方法1:,有miniport的時候,可以查看miniport->SymbolicLinkName
+0x0c0 SymbolicLinkName : _UNICODE_STRING "\??\PCI#VEN_11AB&DEV_4364&SUBSYS_303A17AA&REV_14#4&38d2602c&0&00E1#{ad498944-762f-11d0-8dcb-00c04fc3358c}\{E8F7C668-870F-4C4C-BAE4-0795A3481D4A}"
如果\??\PCI打頭的則為物理網卡,還有一種的是\??\usb,這種也是網卡,不過是USB無線網卡
判斷方法2:就是遍歷注冊表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards
下的所有位置即是物理網卡,取得GUID,如{4C3B9528-B1D7-40E6-BD83-22A7097EC44D}后,構造成\\.\\來打開設備
然后下發OID_GEN_PHYSICAL_MEDIUM,判斷返回值,如果是NdisPhysicalMediumWirelessLan,即為無線網卡。
windbg //發現一般的網卡不支持OID_GEN_PHYSICAL_MEDIUM,這個OID,DeviceIoControl返回無效參數,現象是網卡的里面是NdisPhysicalMediumUnspecified,所以如果返回無效參數倒也可以認定是一般的網卡。
注:如想查看網卡支持哪些例程,可發送OID:OID_GEN_SUPPORTED_LIST,返回一個ULONG 數組,每個元素表示一個OID
網卡有3種狀態要關心:
1。正常使用
2。是未連接(如網卡沒有成功配置IP啥的,右下角網絡連接圖標打了交叉)
3。是禁用
無論處於哪種狀態,上面搜索物理網卡的方法1都一樣。但方法2肯定就不同了,因為當網卡禁用的時候,驅動下面根本就沒miniport
驅動下最完美搜集網上信息的做法其實是:
首先用方法1搜索注冊表得到物理網卡,得到其GUID,這個GUID也是對應網卡的設備名。
之后ZwOpenFile打開,如果返回不存在,其實可以斷定是網卡被禁用了,或者根本不能使用的。
此時可得到禁用狀態的網卡,接着給設備發OID_GEN_MEDIA_CONNECT_STATUS查詢連接狀態。
判斷返回值NdisMediaStateConnected。是否連接。至此,網卡狀態完美獲取。
注:在HOOK的時候,不同Media 類型的網卡數據,會使用不同的回調接收回調,如有fddi,eth以太類型等。這個可以再發OID_GEN_MEDIA_IN_USE 這個OID獲取Media 類型,這樣就能HOOK相應例程
網卡沒連接上的話,自然就沒法用了。此類網卡略過。
有時候在獲取了網卡這些狀態后,還需要獲取它的屬性,如IP地址,MAC,方法如下:
(以下方法是通過注冊表獲取,可以得到本機IP地址,本機MAC地址,和網關MAC)
得到網卡GUID ={E8F7C668-870F-4C4C-BAE4-0795A3481D4A}后,
組成注冊表路徑 “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{E8F7C668-870F-4C4C-BAE4-0795A3481D4A}”,在里面讀取IP地址,網關IP地址。
(在這個鍵下,EnableDHCP字段區分是否為DHCP,如果開啟DHCP,DhcpIPAddress才是IP地址,DhcpDefaultGateway是網關。
否則就是靜態,這個到IPAddress取IP地址,DefaultGateway取網關地址。)
獲取物理網卡方法:
1。遍歷 注冊表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards
2。判斷是否為物理網卡,可以查看miniport->SymbolicLinkName
+0x0c0 SymbolicLinkName : _UNICODE_STRING "\??\PCI#VEN_11AB&DEV_4364&SUBSYS_303A17AA&REV_14#4&38d2602c&0&00E1#{ad498944-762f-11d0-8dcb-00c04fc3358c}\{E8F7C668-870F-4C4C-BAE4-0795A3481D4A}"
如果\??\PCI打頭的則為物理網卡,還有一種的是\??\usb,這種也是網卡,不過是USB無線網卡
網卡有3種狀態要關心:
1。正常使用
2。是未連接(如網卡沒有成功配置IP啥的,右下角網絡連接圖標打了交叉)
3。是禁用
無論處於哪種狀態,上面搜索物理網卡的方法1都一樣。但方法2肯定就不同了,因為當網卡禁用的時候,驅動下面根本就沒miniport
驅動下最完美搜集網上信息的做法其實是:
首先用方法1搜索注冊表得到物理網卡,得到其GUID,這個GUID也是對應網卡的設備名。
之后ZwOpenFile打開,如果返回不存在,其實可以斷定是網卡被禁用了,或者根本不能使用的。
此時可得到禁用狀態的網卡,接着給設備發OID_GEN_MEDIA_CONNECT_STATUS查詢連接狀態。
判斷返回值NdisMediaStateConnected。是否連接。至此,網卡狀態完美獲取。
注:在HOOK的時候,不同Media 類型的網卡數據,會使用不同的回調接收回調,如有fddi,eth以太類型等。這個可以再發OID_GEN_MEDIA_IN_USE 這個OID獲取Media 類型,這樣就能HOOK相應例程
網卡沒連接上的話,自然就沒法用了。此類網卡略過。
有時候在獲取了網卡這些狀態后,還需要獲取它的屬性,如IP地址,MAC,方法如下:
(以下方法是通過注冊表獲取,可以得到本機IP地址,本機MAC地址,和網關MAC)
得到網卡GUID ={E8F7C668-870F-4C4C-BAE4-0795A3481D4A}后,
組成注冊表路徑 “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{E8F7C668-870F-4C4C-BAE4-0795A3481D4A}”,在里面讀取IP地址,網關IP地址。
(在這個鍵下,EnableDHCP字段區分是否為DHCP,如果開啟DHCP,DhcpIPAddress才是IP地址,DhcpDefaultGateway是網關。
否則就是靜態,這個到IPAddress取IP地址,DefaultGateway取網關地址。)
關於網卡MAC地址,正如上面提到的發送OID_GEN_MEDIA_CONNECT_STATUS查詢網卡狀態方法一樣,使用打開設備對象,然后發OID來查詢:
取得{4C3B9528-B1D7-40E6-BD83-22A7097EC44D}后,構造成\\.\\來打開設備
接着發OID來獲取即可。
nOid = OID_802_3_CURRENT_ADDRESS;
status = ZwDeviceIoControlFile(hDev,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_NDIS_QUERY_GLOBAL_STATS,
&nOid,
sizeof(nOid),
pAIEX->pAI[uCounter].macAddress,
uTmp);
===========================
typedef enum _NDIS_MEDIUM
{
NdisMedium802_3,
NdisMedium802_5,
NdisMediumFddi,
NdisMediumWan,
NdisMediumLocalTalk,
NdisMediumDix, // defined for convenience, not a real medium
NdisMediumArcnetRaw,
NdisMediumArcnet878_2,
NdisMediumAtm,
NdisMediumWirelessWan,
NdisMediumIrda,
NdisMediumBpc,
NdisMediumCoWan,
NdisMedium1394,
NdisMediumInfiniBand,
NdisMediumMax // Not a real medium, defined as an upper-bound
} NDIS_MEDIUM, *PNDIS_MEDIUM;
//
// Physical Medium Type definitions. Used with OID_GEN_PHYSICAL_MEDIUM.
//
typedef enum _NDIS_PHYSICAL_MEDIUM
{
NdisPhysicalMediumUnspecified,
NdisPhysicalMediumWirelessLan,
NdisPhysicalMediumCableModem,
NdisPhysicalMediumPhoneLine,
NdisPhysicalMediumPowerLine,
NdisPhysicalMediumDSL, // includes ADSL and UADSL (G.Lite)
NdisPhysicalMediumFibreChannel,
NdisPhysicalMedium1394,
NdisPhysicalMediumWirelessWan,
NdisPhysicalMediumNative802_11,
NdisPhysicalMediumBluetooth,
NdisPhysicalMediumMax // Not a real physical type, defined as an upper-bound
} NDIS_PHYSICAL_MEDIUM, *PNDIS_PHYSICAL_MEDIUM;
===========================
typedef enum _NDIS_MEDIUM
{
NdisMedium802_3,
NdisMedium802_5,
NdisMediumFddi,
NdisMediumWan,
NdisMediumLocalTalk,
NdisMediumDix, // defined for convenience, not a real medium
NdisMediumArcnetRaw,
NdisMediumArcnet878_2,
NdisMediumAtm,
NdisMediumWirelessWan,
NdisMediumIrda,
NdisMediumBpc,
NdisMediumCoWan,
NdisMedium1394,
NdisMediumInfiniBand,
NdisMediumMax // Not a real medium, defined as an upper-bound
} NDIS_MEDIUM, *PNDIS_MEDIUM;
//
// Physical Medium Type definitions. Used with OID_GEN_PHYSICAL_MEDIUM.
//
typedef enum _NDIS_PHYSICAL_MEDIUM
{
NdisPhysicalMediumUnspecified,
NdisPhysicalMediumWirelessLan,
NdisPhysicalMediumCableModem,
NdisPhysicalMediumPhoneLine,
NdisPhysicalMediumPowerLine,
NdisPhysicalMediumDSL, // includes ADSL and UADSL (G.Lite)
NdisPhysicalMediumFibreChannel,
NdisPhysicalMedium1394,
NdisPhysicalMediumWirelessWan,
NdisPhysicalMediumNative802_11,
NdisPhysicalMediumBluetooth,
NdisPhysicalMediumMax // Not a real physical type, defined as an upper-bound
} NDIS_PHYSICAL_MEDIUM, *PNDIS_PHYSICAL_MEDIUM;