星痕共鸣 C++显示打出的攻击力
捕获实时攻击力并打印出来
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;elsenetmask = 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和目标IPstruct 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 "";}}// 查找最高频IPif (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和目的IPstruct 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(<ime, &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", <ime);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;elsestd::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.0if (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;
}