急在线等!!贴出程序,关于corrupted double-linked list错误和aborted (core dumped)的问题

时间:2022-09-06 17:06:27
C++新手,刚从学校出来实习,公司要求做一个分析pcap文件的小程序。
原理如下:
将每一个http的请求报文的host、URL、和其对应的tcp的源端口读取,写入list容器,接收到一个http响应报文,读取目的端口,与list容器里的源端口对比,对比成功则新建一个结构体将其对应的HOST和URL赋值给这个结构体,并删除list容器里的对应元素,如果这个响应报文携带数据,即状态码在200那一段的,以host为名字建立文件夹,并将数据写入这个文件夹,以URL命名。

现在的情况是 能建两个文件夹,也有文件写入但是不是按照预期写入,且有corrupted double-linked list和aborted (core dumped)报错。

各位大哥看看是什么原因,找了两天也不知道该怎么改。谢谢了!!!!
前两个是请求报文和响应报文的数据写入,算测试。
急在线等!!贴出程序,关于corrupted double-linked list错误和aborted (core dumped)的问题
急在线等!!贴出程序,关于corrupted double-linked list错误和aborted (core dumped)的问题
急在线等!!贴出程序,关于corrupted double-linked list错误和aborted (core dumped)的问题
急在线等!!贴出程序,关于corrupted double-linked list错误和aborted (core dumped)的问题
红色框出来的是创建的文件夹
急在线等!!贴出程序,关于corrupted double-linked list错误和aborted (core dumped)的问题

下面贴代码:
main.cpp

#include "pcap.h"
#include "method.hpp"
#include <iostream>
#include <memory.h>
#include <string>
#include <vector>
#include <list>
#include <cstdio>
#include <fstream>
#include <iomanip>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>

using namespace std;

int main(int argc, char *argv[]){
int a=1 ,b = 1,i=1;
pcap_header pcap_head_buf;
pkt_header pkt_head_buf;
ip_header ip_head_buf;
tcp_header tcp_head_buf;
u_int16 srcport_buf;
u_int16 dstport_buf;
FILE *fp = NULL;
if (fopen("/home/yiyada/http/http7.pcap", "rb") == NULL){
printf("Fail to open the file");
}else
fp = fopen("/home/yiyada/http/http7.pcap", "rb");

getPcapFileHead(fp, pcap_head_buf);

fseek(fp, 0, SEEK_END);//改变流指针位置,失败不改变
long fileSize = ftell(fp);
long fpOffset = sizeof(pcap_header);
fseek(fp, fpOffset, SEEK_SET);//回调指针

/*!!*/
list <HttpList1> httplist;
/*!!*/

while ((fseek(fp, fpOffset, SEEK_SET) == 0) && (fpOffset < fileSize)){//循环处理每一个Pkt_Header
getPktHead(fp, pkt_head_buf);
fpOffset += (sizeof(pkt_header)+pkt_head_buf.caplen);
//fpOffset 当前位置 +sizeof( pkt_header) +sizeof (pkt_data) ,得到下一网络帧的 offset

u_int16 framType = getFramType(fp, pcap_head_buf.linktype);
if (framType == 0xdd86){//IPV6链接 , 跳过该网络帧
continue;
}

else{
getIpHead(fp, ip_head_buf);

if (ip_head_buf.Protocol != 0x06){// Protocol != 0x06  表示非TCP链接 , 跳过该网络帧
continue;
}
else { //TCP 链接类型
getTcpHead(fp, tcp_head_buf);

fseek(fp, -20, SEEK_CUR);
fread(&srcport_buf, 2, 1, fp);
fread(&dstport_buf, 2, 1, fp);
fseek(fp, 16, SEEK_CUR);

long tcp_data_size = fpOffset - ftell(fp);
// 当前位置在一个 tcp_header 后  ,fpOffset - 当前位置 得到 tcp_data 的长度

if(tcp_data_size != 0)
{
u_int8 tempBuf[4];
u_int8 tempBuf2[12];

string methodBuf;//似乎没有用
string urlBuf;
string hostBuf;
string uaBuf;

fread(tempBuf, 4, 1, fp);
fseek(fp, -4, SEEK_CUR);
char tcp_data_buf[100000];//总的传输字节数应该小于100000
memset(tcp_data_buf, 0, sizeof(tcp_data_buf) / sizeof(char));//内存清空

if((tempBuf[0] == 0x50 && tempBuf[1] == 0x4f && tempBuf[2] == 0x53 && tempBuf[3] == 0x54) ||
(tempBuf[0] == 0x47 && tempBuf[1] == 0x45 && tempBuf[2] == 0x54)
)//两个条件分别表示"POST"和"GET",判断成功表明该网络帧包含了一个http,get或者post链接
{
fread(tcp_data_buf, tcp_data_size, 1, fp);
matchHttp(tcp_data_buf, methodBuf, urlBuf, hostBuf, uaBuf);

/*!!*/
HttpList1 node = { urlBuf,hostBuf,srcport_buf };
httplist.push_back(node);//将请求报文加入list

/*!!!!!!!!!!!*/


//写请求报文
ofstream f1("/home/yiyada/http/request_msg.txt", ios::app);           //打开文件用于写,若文件不存在就创建它
if (!f1)return 0;                                  //打开文件失败则结束运行
f1 << "No." << a << endl;
f1 << "URL:"<<hostBuf+urlBuf<< endl;
f1 << "user-agent:" << uaBuf << endl;
f1 << "===========+===========+===========+===========" << endl;
f1.close();
a++;
}
else//写响应报文
{
fread(tempBuf2, 12, 1, fp);
fseek(fp, -12, SEEK_CUR);
if (tempBuf2[0] == 0x48 && tempBuf2[1] == 0x54 && tempBuf2[2] == 0x54 && tempBuf2[3] == 0x50 && tempBuf2[4] == 0x2f && tempBuf2[5] == 0x31 && tempBuf2[6] == 0x2e && tempBuf2[7] == 0x31 && tempBuf2[8] == 0x20 && tempBuf2[9] == 0x32 && tempBuf2[10] == 0x30 && ( 0<= tempBuf2[11] <=9 )){//HTTP/1.1 202判断
fread(tcp_data_buf, tcp_data_size, 1, fp);

char *data;
if (strstr(tcp_data_buf, "\r\n\r\n") == NULL)
cout << "error" << endl;
else
{
data = strstr(tcp_data_buf, "\r\n\r\n");
}

                            HttpList2 index_http=analyse(httplist,srcport_buf);//找到对应响应报文并删除
                            if(opendir(index_http.host.c_str())==NULL){
                            mkdir(index_http.host.c_str(),S_IRWXU|S_IRWXG|S_IRWXO);
                            }
                            ofstream out("/home/yiyada/http/res_msg.txt", ios::app);//打开文件用于写,若文件不存在就创建它
if (!out)return 0;                                       //打开文件失败则结束运行
out << (data+4) << endl;
out.close();

rename("/home/yiyada/http/res_msg",index_http.URL.c_str());


ofstream f1("/home/yiyada/http/response_msg.txt", ios::app);//打开文件用于写,若文件不存在就创建它
if (!f1)return 0;                                       //打开文件失败则结束运行
f1 << "No." << b << endl;
f1 << (data+4) << endl;
f1 << "===========+===========+===========+===========" << endl;
f1.close();
b++;
}
}
}
}
}
}
return 0;
}


method.hpp

#ifndef METHOD_H
#define METHOD_H

#include "pcap.h"
#include <cstdio>
#include <iostream>
#include <vector>
#include <string>
#include <list>


using namespace std;

typedef struct HttpList1 {
string URL;
string host;
u_int16 port;
}HttpList1;

typedef struct HttpList2 {
string URL;
string host;
}HttpList2;

void getPcapFileHead(FILE *fp, pcap_header &pcap_head){
fread(&pcap_head, sizeof(pcap_header), 1, fp);//返回真实写入的项数
}

void getPktHead(FILE *fp, pkt_header &pkt_head){
fread(&pkt_head, sizeof(pkt_header), 1, fp);
}

u_int32 getFramType(FILE *fp, u_int32 linktype){
if (linktype == 0x71){
Linux_cooked_capture temp;
fread(&temp, sizeof(temp), 1, fp);
return temp.FrameType;
}

else if (linktype == 0x01){
Ethernet temp;
fread(&temp, sizeof(temp), 1, fp);
return temp.FrameType;
}
else
return linktype;
}

void getIpHead(FILE *fp, ip_header &ip_head_buf){
fread(&ip_head_buf, sizeof(ip_header), 1, fp);
}

void getTcpHead(FILE *fp, tcp_header &tcp_head_buf){
fread(&tcp_head_buf, sizeof(tcp_header), 1, fp);
}
//请求报文
void matchHttp(char tcp_data_buf[], string&methodBuf, string&urlBuf, string&hostBuf, string&uaBuf){
vector <string> tempStrVector;//声明容器
string tempSring(tcp_data_buf);
for (string::size_type beginPos = 0; beginPos != tempSring.size();){
string::size_type endPos = beginPos;
while (++endPos && endPos != tempSring.size()){
if (tempSring[endPos] == '\n'){
break;
}
}
tempStrVector.push_back(tempSring.substr(beginPos, endPos - beginPos));//一行一行的存入
if (endPos == tempSring.size()){
break;
}
beginPos = endPos;
}//把数据存入VECTOR

for (vector <string>::iterator posVector = tempStrVector.begin(); posVector != tempStrVector.end(); ++posVector){
if (string::size_type tempPos = (*posVector).find("GET") != (*posVector).npos){
methodBuf = "GET";
string::size_type endPos = (*posVector).find("HTTP/1.1");
urlBuf = (*posVector).substr(tempPos + sizeof("GET") - 1, endPos - tempPos - sizeof("GET"));
}   // “ GET ” 和  “ HTTP/1.1”  之间字符串为 url

if (string::size_type tempPos = (*posVector).find("POST") != (*posVector).npos){
string::size_type endPos = (*posVector).find("HTTP/1.1");
methodBuf = "POST";
urlBuf = (*posVector).substr(tempPos + sizeof("POST") - 1, endPos - tempPos - sizeof("POST"));
}   // “ POST ” 和  “ HTTP/1.1”  之间的字符串为 url


if (string::size_type tempPos = (*posVector).find("Host:") != (*posVector).npos){
hostBuf = (*posVector).substr(tempPos + sizeof("Host:"));
}  //" Host:" 后的字符串为 host

if (string::size_type tempPos = (*posVector).find("User-Agent:") != (*posVector).npos){
uaBuf = (*posVector).substr(tempPos + sizeof("User-Agent:"));
}   // " User-Agent:" 后的字符串为 ua

}
}
//响应报文

HttpList2 analyse(list<HttpList1>& httplist,u_int16 srcport_buf){
list < HttpList1 > ::iterator lis = httplist.begin();
for (lis = httplist.begin(); lis != httplist.end(); ++lis){
if ((*lis).port==srcport_buf) {
HttpList2 found_req = {(*lis).URL,(*lis).host};
lis = httplist.erase(lis);
return found_req;
}
}
}

#endif


pcap.h

#ifndef DEFINEPCAP_H
#define DEFINEPCAP_H

typedef unsigned int u_int32;
typedef unsigned short u_int16;
typedef unsigned char u_int8;
typedef int int32;

typedef struct pcap_header{ 
u_int32 magic;
u_int16 Ver_major;
u_int16 Ver_minor;
int32 thiszone;
u_int32 sigfigs;
u_int32 snaplen;
u_int32 linktype;
}pcap_header;//占24字节

typedef struct timestamp{
u_int32 timestamp_s;
u_int32 timestamp_ms;
}timestamp;//时间戳

typedef struct pkt_header{
timestamp ts;
u_int32 caplen;
u_int32 len;
}pkt_header;

typedef struct Ethernet{
u_int8 DstMAC[6];//目的MAC地址
u_int8 SrcMAC[6];//源MAC地址
u_int16 FrameType;//以太网帧类型
}Ethernet;//4字节

typedef struct Linux_cooked_capture{
u_int16 package_type;
u_int16 address_type;
u_int16 address_length;
u_int16 un_used[4];
u_int16 FrameType; //帧类型
}Linux_cooked_capture;//10字节

typedef struct ip_header{
u_int8 Ver_HLen;
u_int8 TOS;
u_int16 TotalLen;
u_int16 ID;
u_int16 Flag_Segment;
u_int8 TTL;
u_int8 Protocol;
u_int16 Checksum;
u_int32 SrcIP;
u_int32 DstIP;
}ip_header;//20字节

typedef struct tcp_header{
u_int16 SrcPort;
u_int16 DstPort;
u_int32 SeqNo;
u_int32 AckNo;
u_int8 HeaderLen;//数据报头的长度(4 bit) + 保留(4 bit)
u_int8 Flags;
u_int16 Window;//窗口大小
u_int16 Checksum;//校验和
u_int16 UrgentPointer;//紧急指针
}tcp_header;//20字节

#endif

10 个解决方案

#1


为什么木有回复   急在线等!!贴出程序,关于corrupted double-linked list错误和aborted (core dumped)的问题

#2


真的没有大哥可以帮看看吗 TAT

#3


有没有大佬可以来看看啊 

#4


你要写抓包工具吧,代码太长,你可以使用gdb调试coredump,看看是哪一行代码导致崩溃,查看对应的变量内存,就可以找到原因。

#5


引用 4 楼 gzshun 的回复:
你要写抓包工具吧,代码太长,你可以使用gdb调试coredump,看看是哪一行代码导致崩溃,查看对应的变量内存,就可以找到原因。
好的 我先试试,谢谢!!!

#6


引用 4 楼 gzshun 的回复:
你要写抓包工具吧,代码太长,你可以使用gdb调试coredump,看看是哪一行代码导致崩溃,查看对应的变量内存,就可以找到原因。
急在线等!!贴出程序,关于corrupted double-linked list错误和aborted (core dumped)的问题
可是这上面 的函数除了最后一个都不是我写的,我第一次用这种办法看,也看不出个所以然,请教 一下。

#7


点击第8行,也就是main那一行,监视相应的变量,运行错误只能靠调试,查看堆栈提示的行数存在的几个变量

#8


引用 7 楼 gzshun 的回复:
点击第8行,也就是main那一行,监视相应的变量,运行错误只能靠调试,查看堆栈提示的行数存在的几个变量
急在线等!!贴出程序,关于corrupted double-linked list错误和aborted (core dumped)的问题24行这个是 析构函数的问题吗。。。第一次 这样调试过,我也 看不懂。。。请教一下该如何发现这个问题在哪里呢?

#9


我试了下,这个程序很多隐患,一有逻辑错误segmentation fault,生成core dump。
先打开系统生成core:
ulimit -c unlimited

带上-g参数
g++ main.cpp -g

崩溃会产生core文件,运行:
gdb a.out core

进入gdb,输入backtrace可以看到堆栈信息,基本上就是那一行出问题,肯定是空指针,去做响应的修改,一直修改直到程序正常。

若要看汇编,直接敲入 layout asm可以查看汇编。

初学者更应该学习调试技巧,不是一句不熟就可以掩盖过去,这都得靠自己。

#10


引用 9 楼 gzshun 的回复:
我试了下,这个程序很多隐患,一有逻辑错误segmentation fault,生成core dump。
先打开系统生成core:
ulimit -c unlimited

带上-g参数
g++ main.cpp -g

崩溃会产生core文件,运行:
gdb a.out core

进入gdb,输入backtrace可以看到堆栈信息,基本上就是那一行出问题,肯定是空指针,去做响应的修改,一直修改直到程序正常。

若要看汇编,直接敲入 layout asm可以查看汇编。

初学者更应该学习调试技巧,不是一句不熟就可以掩盖过去,这都得靠自己。

问题已经解决,一个函数参数传入的逻辑问题和 另一个函数 写法不规范
谢谢!!

#1


为什么木有回复   急在线等!!贴出程序,关于corrupted double-linked list错误和aborted (core dumped)的问题

#2


真的没有大哥可以帮看看吗 TAT

#3


有没有大佬可以来看看啊 

#4


你要写抓包工具吧,代码太长,你可以使用gdb调试coredump,看看是哪一行代码导致崩溃,查看对应的变量内存,就可以找到原因。

#5


引用 4 楼 gzshun 的回复:
你要写抓包工具吧,代码太长,你可以使用gdb调试coredump,看看是哪一行代码导致崩溃,查看对应的变量内存,就可以找到原因。
好的 我先试试,谢谢!!!

#6


引用 4 楼 gzshun 的回复:
你要写抓包工具吧,代码太长,你可以使用gdb调试coredump,看看是哪一行代码导致崩溃,查看对应的变量内存,就可以找到原因。
急在线等!!贴出程序,关于corrupted double-linked list错误和aborted (core dumped)的问题
可是这上面 的函数除了最后一个都不是我写的,我第一次用这种办法看,也看不出个所以然,请教 一下。

#7


点击第8行,也就是main那一行,监视相应的变量,运行错误只能靠调试,查看堆栈提示的行数存在的几个变量

#8


引用 7 楼 gzshun 的回复:
点击第8行,也就是main那一行,监视相应的变量,运行错误只能靠调试,查看堆栈提示的行数存在的几个变量
急在线等!!贴出程序,关于corrupted double-linked list错误和aborted (core dumped)的问题24行这个是 析构函数的问题吗。。。第一次 这样调试过,我也 看不懂。。。请教一下该如何发现这个问题在哪里呢?

#9


我试了下,这个程序很多隐患,一有逻辑错误segmentation fault,生成core dump。
先打开系统生成core:
ulimit -c unlimited

带上-g参数
g++ main.cpp -g

崩溃会产生core文件,运行:
gdb a.out core

进入gdb,输入backtrace可以看到堆栈信息,基本上就是那一行出问题,肯定是空指针,去做响应的修改,一直修改直到程序正常。

若要看汇编,直接敲入 layout asm可以查看汇编。

初学者更应该学习调试技巧,不是一句不熟就可以掩盖过去,这都得靠自己。

#10


引用 9 楼 gzshun 的回复:
我试了下,这个程序很多隐患,一有逻辑错误segmentation fault,生成core dump。
先打开系统生成core:
ulimit -c unlimited

带上-g参数
g++ main.cpp -g

崩溃会产生core文件,运行:
gdb a.out core

进入gdb,输入backtrace可以看到堆栈信息,基本上就是那一行出问题,肯定是空指针,去做响应的修改,一直修改直到程序正常。

若要看汇编,直接敲入 layout asm可以查看汇编。

初学者更应该学习调试技巧,不是一句不熟就可以掩盖过去,这都得靠自己。

问题已经解决,一个函数参数传入的逻辑问题和 另一个函数 写法不规范
谢谢!!