当前位置: 移动技术网 > 科技>操作系统>windows > 使用C++对物理网卡/虚拟网卡进行识别(包含内外网筛选)

使用C++对物理网卡/虚拟网卡进行识别(包含内外网筛选)

2018年08月27日  | 移动技术网科技  | 我要评论

ca4159,河南省卫生厅网站,大乳人体艺术

简介

在socket编程的时候,我们需要实时获取我们所需要的ip地址。例如在编写后门的时候,我们可能需要获得有效的外网ip或内网ip;有时候我们可能需要判断我们获取的是否是虚拟机网卡,这时候就需要对每一张网卡上的特征进行识别。以下笔者总结了一些常用的处理方法供大家参考。


参考资料:1.
              2.

c++代码样例

1. 头文件(包含特征处理函数)

/////////////////////////////////////////
//
// filename : netinfoproc.h
// creator : peterz
// date : 2018-6-21 23:50
// comment : 网卡信息筛选
// editor : visual studio 2017
//
/////////////////////////////////////////

#pragma once

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <strsafe.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <cstring>

#pragma comment(lib,"iphlpapi.lib")

using namespace std;

#define reg_error -2
#define no_pci -1
#define is_pci 0


/**
 * @brief 查看字符串中是否有指定特征串
 * @param source 指向源字符串的指针
 * @param target 指向目标字符串的指针
 */
bool isinstring(lpcstr source, lpcstr target)
{
    if (source == null && target == null)
    {
        return false;
    }
    const size_t targetlength = strlen(target);
    const size_t sourcelength = strlen(source);

    if (sourcelength >= targetlength)
    {
        for (int i = 0; i < strlen(source); i++)
        {
            if (i + targetlength > sourcelength)
            {
                return false;
            }
            for (int j = 0; j < targetlength; j++)
            {
                if (*(source + i + j) != *(target + j))
                {
                    break;
                }
                if (j == targetlength - 1)
                {
                    return true;
                }
            }
        }
    }
    return false;
}

/**
 * @brief 获取注册表数据
 * @param hroot 根键
 * @param szsubkey 子键
 * @param szvaluename 数据项名
 * @param szreginfo 数据
 */
bool getreginfo(hkey hroot, lpctstr szsubkey, lpctstr szvaluename, lpstr szreginfo)
{
    hkey hkey;
    dword dwtype = reg_sz;
    dword dwlendata = strlen(szreginfo);
    long lres = regcreatekeyex(hroot, szsubkey, 0, null, reg_option_non_volatile, key_all_access, null, &hkey, null);
    if (lres != error_success)
    {
        if (lres == 5)
        {
            printf("please use administrator privilege !\n");
        }
        else
        {
            printf("get register info error! error code is ");
            printf("%ld\n", lres);
        }
        regclosekey(hkey);
        regclosekey(hroot);
        return false;
    }
    regqueryvalueex(hkey, szvaluename, 0, &dwtype, null, &dwlendata);
    lres = regqueryvalueex(hkey, szvaluename, 0, &dwtype, (lpbyte)szreginfo, &dwlendata);
    if (lres != error_success)
    {
        regclosekey(hkey);
        regclosekey(hroot);
        return false;
    }
    regclosekey(hkey);
    regclosekey(hroot);
    return true;
}

/**
 * @brief 验证注册信息是否是pci物理网卡(需要以管理员权限运行程序)
 * @param pipadapterinfo 指向网卡数据的指针
 */
int ispcinetcard(const pip_adapter_info pipadapterinfo)
{
    //通过注册表特征去除非物理网卡
    char szregsubkey[255] = "system\\currentcontrolset\\control\\network\\{4d36e972-e325-11ce-bfc1-08002be10318}\\";
    char sznetcardreginfo[255] = "\0";
    stringcchcat(szregsubkey, sizeof(szregsubkey), pipadapterinfo->adaptername);
    stringcchcat(szregsubkey, sizeof(szregsubkey), "\\connection");
    if (!getreginfo(hkey_local_machine, szregsubkey, "pnpinstanceid", sznetcardreginfo))
    {
        return reg_error;
    }
    if (strncmp(sznetcardreginfo, "pci", 3) == 0) return is_pci;
    else return no_pci;

}


/**
 * @brief 验证是否是虚拟网卡
 * @param pipadapterinfo 指向网卡数据的指针
 */
bool isvirtualnetcard(const pip_adapter_info pipadapterinfo)
{
    //去除有特征名的虚拟网卡
    if (isinstring(strlwr(pipadapterinfo->description), "virtual")) return true;
    //去除有mac的虚拟网卡 vmware
    if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x05 && pipadapterinfo->address[2] == 0x69) return true;
    //去除有mac的虚拟网卡 vmware
    if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x0c && pipadapterinfo->address[2] == 0x29) return true;
    //去除有mac的虚拟网卡 vmware
    if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x50 && pipadapterinfo->address[2] == 0x56) return true;
    //去除有mac的虚拟网卡 vmware
    if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x1c && pipadapterinfo->address[2] == 0x14) return true;
    //去除有mac的虚拟网卡 parallels
    if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x1c && pipadapterinfo->address[2] == 0x42) return true;
    //去除有mac的虚拟网卡 microsoft virtual pc
    if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x03 && pipadapterinfo->address[2] == 0xff) return true;
    //去除有mac的虚拟网卡 virtual iron
    if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x0f && pipadapterinfo->address[2] == 0x4b) return true;
    //去除有mac的虚拟网卡 red hat xen , oracle vm , xen source, novell xen
    if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x16 && pipadapterinfo->address[2] == 0x3e) return true;
    //去除有mac的虚拟网卡 virtualbox
    if (pipadapterinfo->address[0] == 0x08 && pipadapterinfo->address[1] == 0x00 && pipadapterinfo->address[2] == 0x27) return true;
    return false;
}


/**
 * @brief 验证是否是0.0.0.0不可用ip
 * @param pipadapterinfo 指向网卡数据的指针
 */
bool isinvalidip(const pip_adapter_info pipadapterinfo)
{
    ip_addr_string *pipaddrstring = &(pipadapterinfo->ipaddresslist);
    do
    {
        if (!strcmp(pipaddrstring->ipaddress.string, "0.0.0.0"))
        {
            return false;
        }
        if ((pipaddrstring = pipaddrstring->next) == null)
        {
            return true;
        }
    } while (pipaddrstring);
    return true;
}

/**
* @brief 验证是否是内网ip
* @param pipadapterinfo 指向网卡数据的指针
*/
bool isintranetip(const pip_adapter_info pipadapterinfo)
{
    ip_addr_string *pipaddrstring = &(pipadapterinfo->ipaddresslist);
    do
    {
        if (strncmp(pipaddrstring->ipaddress.string, "10", 2) == 0 || (strncmp(pipaddrstring->ipaddress.string, "172.16", 6) > 0 && strncmp(pipaddrstring->ipaddress.string, "172.31", 6) < 0) || strncmp(pipaddrstring->ipaddress.string, "192.168", 7) == 0)
        {
            return true;
        }
        if ((pipaddrstring = pipaddrstring->next) == null)
        {
            return false;
        }
    } while (pipaddrstring);
    return true;
}

2. cpp文件(代码应用演示)

/////////////////////////////////////////
//
// filename : netcardver.cpp
// creator : peterz
// date : 2018-6-21 23:50
// comment : 网卡信息筛选
// editor : visual studio 2017
//
/////////////////////////////////////////

#include "netinfoproc.h"

void output1(pip_adapter_info pipadapterinfo); //结果输出1(正常结果)
void output2(pip_adapter_info pipadapterinfo); //结果输出2(删除虚拟网卡的结果)
void output3(pip_adapter_info pipadapterinfo); //结果输出3(去除非pci物理网卡) >>需要以管理员权限运行程序<<
void output4(pip_adapter_info pipadapterinfo); //结果输出4(筛选内网网卡)

//主函数
int main(void)
{
    pip_adapter_info pipadapterinfo = (pip_adapter_info)malloc(sizeof(ip_adapter_info));
    unsigned long stsize = sizeof(ip_adapter_info);
    int nrel = getadaptersinfo(pipadapterinfo, &stsize);
    if (error_buffer_overflow == nrel/*getadaptersinfo参数传递的内存空间不足*/)
    {
        //free(pipadapterinfo);
        pipadapterinfo = (pip_adapter_info)realloc(pipadapterinfo, stsize);
        nrel = getadaptersinfo(pipadapterinfo, &stsize);
    }
    if (error_success == nrel)
    {
        printf(">>>>>>>>> 正常结果 <<<<<<<<<<<\n\n");
        output1(pipadapterinfo);
        printf("\n\n>>>>>>>>> 删除虚拟网卡的结果 <<<<<<<<<\n\n");
        output2(pipadapterinfo);
        printf("\n\n>>>>>>>>> 去除非pci物理网卡的结果 <<<<<<<<<\n\n");
        output3(pipadapterinfo);
        printf("\n\n>>>>>>>>> 筛选内网网卡的结果 <<<<<<<<<\n\n");
        output4(pipadapterinfo);
    }
    if (pipadapterinfo)
    {
        free(pipadapterinfo);
    }
    system("pause");
    return 0;
}

//结果输出1(正常结果)
void output1(pip_adapter_info pipadapterinfo)
{
    //可能有多网卡,因此通过循环去判断
    while (pipadapterinfo)
    {
        //输出信息
        cout << "网卡名称:" << pipadapterinfo->adaptername << endl;
        cout << "网卡描述:" << pipadapterinfo->description << endl;
        cout << "网卡mac地址:" << pipadapterinfo->address;
        for (uint i = 0; i < pipadapterinfo->addresslength; i++)
        {
            if (i == pipadapterinfo->addresslength - 1)
            {
                printf("%02x\n", pipadapterinfo->address[i]);
            }
            else
            {
                printf("%02x-", pipadapterinfo->address[i]);
            }
        }
        cout << "网卡ip地址如下:" << endl;
        ip_addr_string *pipaddrstring = &(pipadapterinfo->ipaddresslist);
        //可能网卡有多ip,因此通过循环去判断
        do
        {
            cout << pipaddrstring->ipaddress.string << endl;
            pipaddrstring = pipaddrstring->next;
        } while (pipaddrstring);
        pipadapterinfo = pipadapterinfo->next;
        cout << "*****************************************************" << endl;
    }
    return;
}

//结果输出2(删除虚拟网卡的结果)
void output2(pip_adapter_info pipadapterinfo)
{
    //可能有多网卡,因此通过循环去判断
    while (pipadapterinfo)
    {
        //去除虚拟网卡ip
        if (isvirtualnetcard(pipadapterinfo))
        {
            pipadapterinfo = pipadapterinfo->next;
            continue;
        }
        //输出信息
        cout << "网卡名称:" << pipadapterinfo->adaptername << endl;
        cout << "网卡描述:" << pipadapterinfo->description << endl;
        cout << "网卡mac地址:" << pipadapterinfo->address;
        for (uint i = 0; i < pipadapterinfo->addresslength; i++)
        {
            if (i == pipadapterinfo->addresslength - 1)
            {
                printf("%02x\n", pipadapterinfo->address[i]);
            }
            else
            {
                printf("%02x-", pipadapterinfo->address[i]);
            }
        }
        cout << "网卡ip地址如下:" << endl;
        ip_addr_string *pipaddrstring = &(pipadapterinfo->ipaddresslist);
        //可能网卡有多ip,因此通过循环去判断
        do
        {
            cout << pipaddrstring->ipaddress.string << endl;
            pipaddrstring = pipaddrstring->next;
        } while (pipaddrstring);
        pipadapterinfo = pipadapterinfo->next;
        cout << "*****************************************************" << endl;
    }
    return;
}

//结果输出3(去除非pci物理网卡)
void output3(pip_adapter_info pipadapterinfo)
{
    //可能有多网卡,因此通过循环去判断
    while (pipadapterinfo)
    {
        //去除非pci物理网卡
        if (ispcinetcard(pipadapterinfo) != is_pci)
        {
            if (ispcinetcard(pipadapterinfo) == reg_error)
            {
                printf("1\n");
                return;
            }
            pipadapterinfo = pipadapterinfo->next;
            continue;
        }
        //输出信息
        cout << "网卡名称:" << pipadapterinfo->adaptername << endl;
        cout << "网卡描述:" << pipadapterinfo->description << endl;
        cout << "网卡mac地址:" << pipadapterinfo->address;
        for (uint i = 0; i < pipadapterinfo->addresslength; i++)
        {
            if (i == pipadapterinfo->addresslength - 1)
            {
                printf("%02x\n", pipadapterinfo->address[i]);
            }
            else
            {
                printf("%02x-", pipadapterinfo->address[i]);
            }
        }
        cout << "网卡ip地址如下:" << endl;
        ip_addr_string *pipaddrstring = &(pipadapterinfo->ipaddresslist);
        //可能网卡有多ip,因此通过循环去判断
        do
        {
            cout << pipaddrstring->ipaddress.string << endl;
            pipaddrstring = pipaddrstring->next;
        } while (pipaddrstring);
        pipadapterinfo = pipadapterinfo->next;
        cout << "*****************************************************" << endl;
    }
    return;
}

//结果输出4(筛选内网网卡)
void output4(pip_adapter_info pipadapterinfo)
{
    //可能有多网卡,因此通过循环去判断
    while (pipadapterinfo)
    {
        //筛选内网网卡
        if (!isintranetip(pipadapterinfo))
        {
            pipadapterinfo = pipadapterinfo->next;
            continue;
        }
        //输出信息
        cout << "网卡名称:" << pipadapterinfo->adaptername << endl;
        cout << "网卡描述:" << pipadapterinfo->description << endl;
        cout << "网卡mac地址:" << pipadapterinfo->address;
        for (uint i = 0; i < pipadapterinfo->addresslength; i++)
        {
            if (i == pipadapterinfo->addresslength - 1)
            {
                printf("%02x\n", pipadapterinfo->address[i]);
            }
            else
            {
                printf("%02x-", pipadapterinfo->address[i]);
            }
        }
        cout << "网卡ip地址如下:" << endl;
        ip_addr_string *pipaddrstring = &(pipadapterinfo->ipaddresslist);
        //可能网卡有多ip,因此通过循环去判断
        do
        {
            cout << pipaddrstring->ipaddress.string << endl;
            pipaddrstring = pipaddrstring->next;
        } while (pipaddrstring);
        pipadapterinfo = pipadapterinfo->next;
        cout << "*****************************************************" << endl;
    }
    return;
}

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网