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