diff --git a/README.md b/README.md index f28f18b..9b47039 100644 --- a/README.md +++ b/README.md @@ -143,3 +143,9 @@ flush 函数,关闭超时的流。 用比较宽松的方案去处理。当找不到需要的流的时候去新建而不是寻找三次握手的首包。当扫描到 User-Agent: 后再捕获包、分析、修改,避免不是 HTTP 流量的包被捕获。如果捕获过程中读到 psh,即使没有读到 UA 末尾也要提交。UA 的长度也需要作假设;可以假定为最多两个包。 +接下里需要修改的文件: + +c +Manager +Map +Stream \ No newline at end of file diff --git a/src/common.h b/src/common.h index 9876445..551f699 100644 --- a/src/common.h +++ b/src/common.h @@ -1,4 +1,3 @@ -#pragma once #include #include #include @@ -14,6 +13,7 @@ #include #include #include +#pragma once const static unsigned char* str_uaBegin = "User-Agent: "; const static unsigned char* str_uaEnd = "\r\n"; diff --git a/src/rkpMap.h b/src/rkpMap.h index a288dd8..c47b82f 100644 --- a/src/rkpMap.h +++ b/src/rkpMap.h @@ -5,27 +5,28 @@ struct rkpMap // 以相对序列号记录应用层数据中需要修改的部分的位置,提供修改的函数 { - int32_t begin, length; // begin 为绝对 + int32_t begin, length; // begin 为绝对序列号 + // int32_t &seq_offset = beign; // 需要一个差不多的数值作为偏移来计算序列号谁先谁后的问题,这个偏移取为 begin struct rkpMap *prev, *next; }; -struct rkpMap* rkpMap_new(int32_t, int32_t); +struct rkpMap* rkpMap_new(int32_t, int32_t); // 两个参数分别为起始和终止绝对序列号 void rkpMap_delete(struct rkpMap*); -unsigned char __rkpMap_map(const struct rkpMap*, int32_t); // 返回某个序列号对应的映射后的值。假定参数是合法的。第一个参数实际上没有用。 -void rkpMap_modify(const struct rkpMap*, struct rkpPacket**, int32_t); // 对一列序列号连续且递增的包进行修改 +unsigned char __rkpMap_map(const struct rkpMap*, int32_t); // 返回某个序列号对应的映射后的值。假定参数是合法的。这里的参数是相对序列号 +void rkpMap_modify(const struct rkpMap*, struct rkpPacket**); // 对一列序列号连续且递增的包进行修改 void rkpMap_insert_begin(struct rkpMap**, struct rkpMap*); // 在开头位置插入一个映射 void rkpMap_insert_end(struct rkpMap**, struct rkpMap*); -void rkpMap_refresh(struct rkpMap**, int32_t, int32_t); // 对于一列序列号递增的映射, +void rkpMap_refresh(struct rkpMap**, int32_t); // 对于一列序列号递增的映射,删除已经回应的映射 -struct rkpMap* rkpMap_new(int32_t begin, int32_t length) +struct rkpMap* rkpMap_new(int32_t seql, int32_t seqr) { struct rkpMap* rkpm = (struct rkpMap*)rkpMalloc(sizeof(struct rkpMap)); if(rkpm == 0) return 0; - rkpm -> begin = begin; - rkpm -> length = length; + rkpm -> begin = seql; + rkpm -> length = seqr - seql; rkpm -> prev = rkpm -> next = 0; return rkpm; } @@ -36,62 +37,64 @@ void rkpMap_delete(struct rkpMap* rkpm) unsigned char __rkpMap_map(const struct rkpMap* rkpm, int32_t seq) { - int32_t offset = seq - rkpm -> begin; - if(offset < strlen(str_uaRkp)) - return str_uaRkp[offset]; + if(seq < strlen(str_uaRkp)) + return str_uaRkp[seq]; else return ' '; } -void rkpMap_modify(const struct rkpMap* rkpm, struct rkpPacket** rkppl, int32_t doff) +void rkpMap_modify(const struct rkpMap* rkpm, struct rkpPacket** rkppl) { - int32_t seql = rkpPacket_seq(rkpp, doff), seqr = seql + rkpPacket_appLen(rkpp); - unsigned char *pl = rkpPacket_appBegin(rkpp), *pr = rkpPacket_appEnd(rkpp); - if(seql >= rkpm -> begin + rkpm -> length || seqr <= rkpm -> begin) + struct rkpPacket* rkpp; + unsigned char* p; + int32_t seq; + + // 尝试确定第一个需要修改的包 + for(rkpp = *rkppl; rkpp != 0; rkpp = rkpp -> next) + if(rkpPacket_seq(rkpp, rkpm -> begin) + rkpPacket_appLen(rkpp) > 0) + break; + if(rkpp == 0) return; - if(seqr > rkpm -> begin + rkpm -> length) + p = rkpPacket_appBegin(rkpp) - rkpPacket_seq(rkpp, rkpm -> begin); + seq = 0; + + // 开始修改 + for(; rkpp != 0; rkpp = rkpp -> next) { - unsigned doff = seqr - (rkpm -> begin + rkpm -> length); - seqr -= doff; - pr -= doff; + if(seq != 0) + p = rkpPacket_appBegin(rkpp); + for(; p != rkpPacket_appEnd(rkpp) && seq < rkpm -> length; p++, seq++) + *p = __rkpMap_map(rkpm, seq); + rkpPacket_csum(rkpp); + if(seq == rkpm -> length) + break; } - if(seql < rkpm -> begin) - { - unsigned doff = rkpm -> begin - seql; - seql += doff; - pl += doff; - } - for(;seql < seqr; seql++, pl++) - *pl = __rkpMap_map(rkpm, seql); -} -void rkpMap_move(struct rkpMap* rkpm, int32_t doff) -{ - rkpm -> begin += doff; } + void rkpMap_insert_begin(struct rkpMap** rkpml, struct rkpMap* rkpm) { rkpm -> next = *rkpml; - rkpm -> prev = 0; *rkpml = rkpm; if(rkpm -> next != 0) rkpm -> next -> prev = rkpm; } +void rkpMap_insert_end(struct rkpMap** rkpml, struct rkpMap* rkpm) +{ + if(*rkpml == 0) + *rkpml = rkpm; + else + { + struct rkpMap* rkpm2; + for(rkpm2 = *rkpml; rkpm2 -> next != 0; rkpm2 = rkpm2 -> next); + rkpm2 -> next = rkpm; + rkpm -> prev = rkpm2; + } +} void rkpMap_refresh(struct rkpMap** rkpml, int32_t seq) { - struct rkpMap* rkpm = *rkpml; - while(rkpm != 0) - { - if(rkpm -> begin + rkpm -> length <= seq) - { - struct rkpMap* rkpm2 = rkpm -> next; - if(rkpm -> prev != 0) - rkpm -> prev -> next = rkpm -> next; - if(rkpm -> next != 0) - rkpm -> next -> prev = rkpm -> prev; - rkpMap_delete(rkpm); - rkpm = rkpm2; - } - else - rkpm = rkpm -> next; - } + struct rkpMap* rkpm; + // 找到第一个不用删除的映射 + for(rkpm = *rkpml; rkpm != 0; rkpm = rkpm -> next) + // if(rkpm -> begin + rkpm -> length <= seq) 需要避免绝对值很大的负数小于绝对值很大的正数的情况 + if((int32_t)(seq - rkpm -> begin) + rkpm -> length) - seq) <= 0) } \ No newline at end of file diff --git a/src/rkpPacket.h b/src/rkpPacket.h index 77cd182..7a46d75 100644 --- a/src/rkpPacket.h +++ b/src/rkpPacket.h @@ -1,5 +1,5 @@ -#pragma once #include "common.h" +#pragma once struct rkpPacket // 存储一个个数据包的类,完全被 rkpStream 和 rkpManager 包裹 diff --git a/src/rkpSettings.h b/src/rkpSetting.h similarity index 100% rename from src/rkpSettings.h rename to src/rkpSetting.h index 87e01fe..761ab4c 100644 --- a/src/rkpSettings.h +++ b/src/rkpSetting.h @@ -1,5 +1,5 @@ -#pragma once #include "common.h" +#pragma once _Static_assert(sizeof(int) == 4, "int is not 4 bit."); _Static_assert(sizeof(unsigned long) >= sizeof(void*), "ulong is too short."); diff --git a/src/rkpStream.h b/src/rkpStream.h index 12d3d56..1b24115 100644 --- a/src/rkpStream.h +++ b/src/rkpStream.h @@ -13,7 +13,7 @@ struct rkpStream } status; u_int32_t id[3]; // 按顺序存储客户地址、服务地址、客户端口、服务端口,已经转换字节序 struct rkpPacket *buff_scan, *buff_disordered; // 分别存储准备扫描的、因乱序而提前收到的数据包,都按照序号排好了 - int32_t seq_offset; // 序列号的偏移。使得 buff_scan 中第一个字节的编号为零。 + int32_t seq_offset; // 序列号的偏移。使得 buff_scan 中第一个字节的编号为零。在 rkpStream 中,序列号基本使用相对值;但在传给下一层时,基本使用绝对值 bool active; // 是否仍然活动,流每次处理的时候会置为 true,每隔一段时间会删除标志为 false(说明它在这段时间里没有活动)的流,将标志为 true 的流的标志也置为 false。 unsigned scan_headEnd_matched, scan_uaBegin_matched, scan_uaEnd_matched; // 记录现在已经匹配了多少个字节,由 __rkpStream_scan 设置,但可以由其它过程置零 unsigned char *scan_uaBegin_p, *scan_uaEnd_p; // 记录扫描的一些结果,由 __rkpStream_scan 设置,但可以由其它过程置零