捕获实时攻击力并打印出来
const unsigned char signature[] = {
0x1b, 0x1b, 0x18, 0x81, 0x85, 0xb4, 0xc6, 0xbc, 0x11, 0x11
};
//这个数据可能每个人不一样,防止这里包含了隐私数据,我也没用我真实的
不解释,直接上代码

//XHGM.h
#pragma once
#include <pcap.h>
#include <Winsock2.h>
#include <iostream>
#include <iomanip>
#include <string>
#include<vector>
#include <memory>
#include<map>
#include<chrono>
#include <set>
#include <iphlpapi.h>
#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "iphlpapi.lib")

struct ATK
{
	long long max, now;
};
long long parse_varint(const char* data, int count);//解析商店时使用
bool parse_attack_power(const unsigned char* data, size_t length, ATK*atk1);

class infs_1
{
public:
	int itemid;
	int count;
	int min_money;
	int load(const char*);
	infs_1();
};
class page {
public:
	std::vector<infs_1*> vec;
	int length;
	int ID;
	int XL;
	int D_length;
	int sjq;
	int unknow1;
	int unknow2;
	char start_bs[2];
	int load_sp(const char*t1, int pos1);
	int load(const char *t1);
};
//XHGM.cpp
#include "XHGM.h"

long long parse_varint(const char* data, int count)//解析商店时使用
{
	long long value = 0;
	int shift = 0;
	for (int i = 0; i < count; i++) {
		char byte = data[i];
		value |= ((byte & 0x7F) << shift);
		shift += 7;
	}
	return value;
}
const unsigned char signature[] = {
	0x1b, 0x1b, 0x18, 0x81, 0x85, 0xb4, 0xc6, 0xbc, 0x11, 0x11
};//这个数据可能每个人不一样,防止这里包含了隐私数据,我也没用我真实的

bool parse_attack_power(const unsigned char* data, size_t length, ATK*atk1) {
	// 特征序列
	
	//const size_t sig_len = sizeof(signature);

	// 遍历数据包寻找特征序列
	bool ok = false;
	int pos = 0;
	atk1->max = 0;
	atk1->now = 0;
	for (size_t i = pos; i < length - 11; ++i) {
		if (std::memcmp(data + i, signature, 10) == 0) {
			// 找到特征序列,提取后面的两个字节(小端序)
			int lens = data[i - 1];
			size_t atk_pos = i + 10;
			if (atk_pos + 1 >= length) {
				for (size_t i = pos; i < length - 9; ++i) {
					if (data[i] == 0x48)
					{
						for (int j = 1; j < 10; j++)
						{
							if (data[i - j] == 0x30 || data[i - j] == 0x40)
							{
								atk1->max = -1;
								atk1->now = parse_varint((const char*)(data + i - j + 1), j - 1);
								return true;
							}
						}
						break;
					}
				}
				return false;  // 数据不足
			}
			pos = atk_pos + lens - 10;
			ok = true;
			atk1->max= parse_varint((const char*)(data + atk_pos), lens - 10);
			break;
		}
	}
	for (size_t i = pos; i < length - 9; ++i) {
		if (data[i] == 0x48)
		{
			for (int j = 1; j < 10; j++)
			{
				if (data[i - j] == 0x30 || data[i - j] == 0x40)
				{
					atk1->now = parse_varint((const char*)(data + i - j+1), j-1);
				}
			}
			break;
		}
	}
	if (ok) return true;
	return false;  // 未找到特征序列
}
infs_1::infs_1()
{

}
int infs_1::load(const char* t1)
{
	if (t1[1] == 0x04)
	{
		this->itemid = parse_varint(t1 + 3, 3);
		this->count = 0;
		this->min_money = 0;
		return 6;
	}
	else
	{
		this->itemid = parse_varint(t1 + 3, 3);
		int s1 = 0;
		for (int i = 7; i < t1[1] + 2; i++)
		{
			if (t1[i] == 0x18)
			{
				this->count = parse_varint(t1 + 7, i - 7);
				s1 = i + 1;
			}
		}
		this->min_money = parse_varint(t1 + s1, t1[1] + 2 - s1);
		return (int)(t1[1] + 2);
	}
	return true;
}


int page::load_sp(const char*t1, int pos1)
{
	int pos = pos1;
	while (true)
	{
		if (pos >= this->length - 1)
			return 0;
		//printf("%x  %d  %d\n", t1[pos],pos,this->length);
		if (t1[pos] != 0x12)
			return 0;
		infs_1 *t = new infs_1();
		pos += t->load(t1 + pos);
		vec.push_back(t);
	}
	return 0;
}

int page::load(const char *t1)
{
	int pos = 0;
	int *tmp_val = NULL;
	{
		tmp_val = &(this->length);
		*tmp_val = 0;
		for (int i = 0; i < 4; i++)
		{
			*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
		}
		pos += 4;
	}
	{
		tmp_val = &(this->ID);
		*tmp_val = 0;
		for (int i = 0; i < 4; i++)
		{
			*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
		}
		pos += 4;
	}
	{
		tmp_val = &(this->XL);
		*tmp_val = 0;
		for (int i = 0; i < 4; i++)
		{
			*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
		}
		pos += 4;
	}
	{
		tmp_val = &(this->D_length);
		*tmp_val = 0;
		for (int i = 0; i < 4; i++)
		{
			*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
		}
		pos += 4;
	}
	{
		tmp_val = &(this->sjq);
		*tmp_val = 0;
		for (int i = 0; i < 4; i++)
		{
			*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
		}
		pos += 4;
	}
	{
		tmp_val = &(this->unknow1);
		*tmp_val = 0;
		for (int i = 0; i < 4; i++)
		{
			*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
		}
		pos += 4;
	}
	{
		tmp_val = &(this->unknow2);
		*tmp_val = 0;
		for (int i = 0; i < 4; i++)
		{
			*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
		}
		pos += 4;
	}
	{
		for (int i = 0; i < 2; i++)
		{
			this->start_bs[i] = t1[pos + i];
		}
		pos += 2;
	}
	return 0;
}
//主函数
#include"XHGM.h"
#pragma warning(disable:4996)
pcap_if_t* dev;
char xhgm_ip[255];
pcap_t* fp;
std::set<std::string> GetLocalIPs() {
	std::set<std::string> localIPs;
	PIP_ADAPTER_INFO pAdapterInfo;
	PIP_ADAPTER_INFO pAdapter = NULL;
	DWORD dwRetVal = 0;
	ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);

	// 第一次调用获取缓冲区大小
	pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen);
	if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) {
		free(pAdapterInfo);
		pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen);
	}

	if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen))) {
		free(pAdapterInfo);
		return localIPs;
	}

	pAdapter = pAdapterInfo;
	while (pAdapter) {
		IP_ADDR_STRING* pIpAddr = &(pAdapter->IpAddressList);
		while (pIpAddr) {
			if (pIpAddr->IpAddress.String[0] != '\0') {
				localIPs.insert(pIpAddr->IpAddress.String);
			}
			pIpAddr = pIpAddr->Next;
		}
		pAdapter = pAdapter->Next;
	}

	free(pAdapterInfo);
	return localIPs;
}

std::string GetMostFrequentIP() {
	char errbuf[PCAP_ERRBUF_SIZE];
	struct bpf_program fcode;
	bpf_u_int32 netmask;
	std::map<std::string, int> ipCount;
	auto start = std::chrono::steady_clock::now();

	// 获取本机IP集合
	std::set<std::string> localIPs = GetLocalIPs();


	// 获取网络掩码
	if (dev->addresses != nullptr)
		netmask = ((struct sockaddr_in*)(dev->addresses->netmask))->sin_addr.S_un.S_addr;
	else
		netmask = 0xFFFFFF;

	// 编译TCP过滤器
	if (pcap_compile(fp, &fcode, "tcp", 1, netmask) < 0) {
		return "";
	}

	// 设置过滤器
	if (pcap_setfilter(fp, &fcode) < 0) {
		return "";
	}


	// 开始捕获
	while (true) {
		pcap_pkthdr* header;
		const u_char* pkt_data;
		int res = pcap_next_ex(fp, &header, &pkt_data);

		// 检查超时
		auto now = std::chrono::steady_clock::now();
		if (std::chrono::duration_cast<std::chrono::seconds>(now - start).count() >= 3) {
			break;
		}

		if (res > 0) {
			// 解析IP头
			struct ip_header {
				u_char  ver_ihl;
				u_char  tos;
				u_short len;
				u_short id;
				u_short flags_fo;
				u_char  ttl;
				u_char  proto;
				u_short checksum;
				u_int   src;
				u_int   dst;
			} *ip_hdr = (ip_header*)(pkt_data + 14); // 跳过以太网头

													 // 提取源IP和目标IP
			struct in_addr src_addr, dst_addr;
			src_addr.S_un.S_addr = ip_hdr->src;
			dst_addr.S_un.S_addr = ip_hdr->dst;

			std::string srcIP = inet_ntoa(src_addr);
			std::string dstIP = inet_ntoa(dst_addr);

			// 只统计从本机发出的流量(源IP是本机,目标IP非本机)
			if (localIPs.find(srcIP) != localIPs.end() &&
				localIPs.find(dstIP) == localIPs.end()) {
				ipCount[dstIP]++;
			}
		}
		else if (res == -1) {
			return "";
		}
	}

	// 查找最高频IP
	if (ipCount.empty()) {
		return "";
	}

	std::string mostFrequentIP;
	int maxCount = 0;
	for (const auto& pair : ipCount) {
		if (pair.second > maxCount) {
			maxCount = pair.second;
			mostFrequentIP = pair.first;
		}
	}

	return  mostFrequentIP;
}
// 定义段节点结构

// 包处理回调函数
ATK atk;
void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data) {
	// 解析IP头部(跳过14字节以太网帧头)
	const u_char* ip_header = pkt_data + 14;
	int ip_header_len = (*ip_header & 0x0F) * 4;

	// 获取源IP和目的IP
	struct in_addr src_addr, dst_addr;
	memcpy(&src_addr, ip_header + 12, 4);
	memcpy(&dst_addr, ip_header + 16, 4);

	char src_ip[INET_ADDRSTRLEN];
	char dst_ip[INET_ADDRSTRLEN];
	inet_ntop(AF_INET, &src_addr, src_ip, INET_ADDRSTRLEN);
	inet_ntop(AF_INET, &dst_addr, dst_ip, INET_ADDRSTRLEN);

	// 检查是否与目标IP(192.168.0.111)通信
	int ff = 0;
	if (strcmp(src_ip, xhgm_ip) == 0)
	{
		ff = 1;
	}
	if (strcmp(dst_ip, xhgm_ip) == 0) {
		ff = 2;
	}
	if (ff == 0)
		return;

	// 打印时间戳 (精确到微秒)
	bool ok = parse_attack_power(pkt_data, header->len,&atk);
	if (!ok)return;
	struct tm ltime;
	char timestr[32];
	time_t local_tv_sec = header->ts.tv_sec;
	localtime_s(&ltime, &local_tv_sec);
	if(ff==2)
		std::cout << "服务器包" << std::endl;
	else if (ff == 1)
		std::cout << "客户端包" << std::endl;
	strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", &ltime);
	std::cout << "[" << timestr << "." << std::setfill('0') << std::setw(6) << header->ts.tv_usec << "] ";

	// 打印包长度
	std::cout << "Length: " << header->len << " bytes" << std::endl;
	std::cout << "攻击力总和: " << atk.max << "\n当前攻击力: " << atk.now << "\n\n" << std::endl;
	
	// 打印十六进制数据 (每行16字节)
	/*for (u_int i = 0; i < header->len; i++) {
		std::cout << std::hex << std::setw(2) << std::setfill('0')
			<< static_cast<int>(pkt_data[i]) << " ";

		if ((i + 1) % 16 == 0)
			std::cout << std::endl;
	}
	std::cout << "\n\n" << std::dec;*/
}

int main() {
	pcap_if_t* alldevs;
	pcap_if_t* d;
	int inum;
	int i = 0;
	pcap_t* adhandle;
	char errbuf[PCAP_ERRBUF_SIZE];
	u_int netmask;
	struct bpf_program fcode;

	// 获取设备列表
	if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) {
		std::cerr << "Error in pcap_findalldevs: " << errbuf << std::endl;
		return -1;
	}

	// 打印设备列表
	for (d = alldevs; d; d = d->next) {
		std::cout << ++i << ". " << d->name;
		if (d->description)
			std::cout << " (" << d->description << ")" << std::endl;
		else
			std::cout << " (No description available)" << std::endl;
	}

	if (i == 0) {
		std::cerr << "No interfaces found!" << std::endl;
		return -1;
	}

	std::cout << "选择你需要抓包的设备 (1-" << i << "): ";
	std::cin >> inum;

	// 跳转到选中的适配器
	for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
	dev = d;
	// 打开设备
	if ((adhandle = pcap_open(d->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf)) == NULL) {
		std::cerr << "Unable to open adapter: " << errbuf << std::endl;
		pcap_freealldevs(alldevs);
		return -1;
	}

	// 检查数据链路层是否为以太网
	if (pcap_datalink(adhandle) != DLT_EN10MB) {
		std::cerr << "This program only supports Ethernet networks." << std::endl;
		pcap_freealldevs(alldevs);
		return -1;
	}
	fp = adhandle;
	std::cout << "正在寻找高频访问IP" << std::endl;
	std::string ip = GetMostFrequentIP();
	strcpy(xhgm_ip, ip.c_str());
	std::cout <<"已找到:"<< xhgm_ip << std::endl;
	char comp[256];
	strcpy(comp, "host ");
	strcat(comp, xhgm_ip);
	// 设置过滤器 (host 192.168.0.111)
	netmask = 0xffffff; // 255.255.255.0
	if (pcap_compile(adhandle, &fcode, comp, 1, netmask) < 0) {
		std::cerr << "Unable to compile the packet filter." << std::endl;
		pcap_freealldevs(alldevs);
		return -1;
	}

	if (pcap_setfilter(adhandle, &fcode) < 0) {
		std::cerr << "Error setting the filter." << std::endl;
		pcap_freealldevs(alldevs);
		return -1;
	}

	std::cout << "\nListening on " << d->description << "...\n" << std::endl;

	// 释放设备列表
	pcap_freealldevs(alldevs);

	// 开始捕获数据包
	pcap_loop(adhandle, 0, packet_handler, NULL);

	return 0;
}

在这里插入图片描述

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐