-
Notifications
You must be signed in to change notification settings - Fork 4
3 Client以及Hook代码框架
jialuhu edited this page May 13, 2019
·
5 revisions
hook框架主要由四个函数模块和两个枚举类型组成。
| 函数模块 | 功能 |
|---|---|
| int open(const char *pathname, int flags, ...) | 劫持本地被监测目录的open调用 |
| int close(int fd) | 劫持本地被监测目录的close调用 |
| enum MONITOR_STATE Unix_Socket(enum TYPE_HOOK types, char *pathname) | Unix域套接字创建以及连接 |
| enum MONITOR_STATE prase_monitor_package(const char *package) | 接收监测工具进程返回的状态(备份是否成功,取备份是否成功) |
| Socket | 封装了一些基本的socket系列函数 |
| 枚举类型 | 含义 |
|---|---|
| enum TYPE_HOOK{OPEN_CALL=0,CLOSE_CALL} | 启动hook函数的系统调用:open或者为close |
| enum MONITOR_STATE{OPEN_SAVE_OK,CLOSE_GET_OK,OPEN_SAVE_FAILT,CLOSE_GET_FAILT,USOCKET_FAILT,UCONNECT_FAILT,UWRITE_FAILT} | 备份和取备份成功,以及失败返回 |
client框架主要由线程池+事件封装类队列和epoll组成
| 类 | 用途 |
|---|---|
| Monitored_event | Unix域套接字事件封装,即本地进程事件封装 |
| 类模版 | 用途 |
|---|---|
| threadpool | 线程池处理任务队列中的任务事件 |
| epoll | 事件表 | 模式 |
|---|---|---|
| epoll相关函数 | Unix域的套接字、与远程服务器连接的套接字 | 本地Unix套接字采用ET模式与非EPOLLOENSHOT模式,远程连接的套接字采用ET模式+EPOLLONESHOT模式 |
| 类模版成员函数 | 功能 |
|---|---|
| threadpool() | 构造函数,创建线程并且进入线程执行函数 |
| ~threadpool() | 析构函数 |
| bool addjob(T* request) | 往事件队列中添加一个事件 |
| void run() | 轮询等待任务队列有事件,并且从队列中拿出事件进行处理 |
| 线程池与监测工具的接口 | 功能 |
|---|---|
| request->do_process() | 调用到事件类的接口函数 |
| 类成员函数 | 功能 |
|---|---|
| /被监测事件含参构造并初始化/ | |
| void init(int ed, int i_s, int u_s) | 被监测事件含参构造并初始化 |
| void close_monitored() | 关闭连接 |
| void do_process() | 分析被监测事件的类型,线程池轮询事件队列的接口 |
| bool u_write() | Unix写到hook.c进程函数 |
| bool i_write() | 与远端服务器连接写函数 |
| bool u_read() | Unix读取hook.c进程发送包函数 |
| bool i_read() | 与远端服务器连接的函数 |
| void Monitored_modfd(int epfd, int fd, int ev) | 因为是EPOLLNESHOT,所以每次要修改epoll事件表 |
| bool get_line(const char *test_buf) | 获取协议包头的每行并且解析 |
| Request_State parse_read_buf() | 通过解析Unix套接字的读缓冲区,判断是open调用还是close调用被劫持 |
| void fill_swrite_buf(Request_State state) | 填写向服务器发送的写缓冲区,根据请求类型进行填写响应包 |
| void fill_uwrite_buf(Request_State state) | 填写Unix的发送缓冲区,根据请求填写响应包 |
class Monitored_event{
public:
/*Unix套接字读缓冲区有三种状态:OPEN请求,CLOSE请求,重复打开同一个文件*/
enum Request_State{OPEN_SAVE, CLOSE_GET, REPEAT_FILE};
/*解析有两种状态,一种是解析头部,另一种是还有文件内容*/
enum Parse_State{HEAD, CONTENT};
public:
static const int READ_BUF_SIZE = 2048;
static const int WRITE_BUF_SIZE = 1024;
private:
static int epfd;//所有被监测的事件共同使用一个epoll注册事件
static int i_socketfd;//所有被监测的事件共同使用一个远程连接
int u_socketfd;//Unix套接字
static int Monitored_number;//所有被监测事件的个数
Parse_State p_state;//解析头部和内容,状态转移标志
char *line_buf;//读取到的每一行的头指针
int now_index;//当前解析了多少字节
int file_length;//文件的大小
map<string, int> repeat_path;//查看是否是重复文件
public:
/*由于之后用的是类数组形式,初始化类成员统一在init成员函数中进行*/
Monitored_event(){}
~Monitored_event(){}
public:
/*被监测事件含参构造并初始化*/
void init(int ed, int i_s, int u_s);
/*关闭连接(考虑之中,因为不能关闭网络套接字和Unix套接字)*/
void close_monitored();
/*分析被监测事件的类型,线程池轮询事件队列的接口*/
void do_process();
/*Unix写到hook.c进程函数*/
bool u_write();
/*与远端服务器连接写函数*/
bool i_write();
/*Unix读取hook.c进程发送包函数*/
bool u_read();
/*与远端服务器连接的函数*/
bool i_read();
private:
/*unix套接字的读取缓冲区*/
char unix_read_buf[READ_BUF_SIZE];
/*TCP套接字读取缓冲区,即服务器应答缓冲区*/
char server_read_buf[READ_BUF_SIZE];
/*unix套接字的发送缓冲区*/
char unix_write_buf[READ_BUF_SIZE];
/*TCP套接字发送缓冲区*/
char server_write_buf[READ_BUF_SIZE];
private:
/*因为是EPOLLNESHOT,所以每次要修改epoll事件表*/
void Monitored_modfd(int epfd, int fd, int ev);
/*获取每行并且解析*/
bool get_line(const char *test_buf);
/*通过解析Unix套接字的读缓冲区,判断是open调用还是close调用被劫持*/
Request_State parse_read_buf();
/*填写向服务器发送的写缓冲区,根据请求类型进行填写响应包*/
void fill_swrite_buf(Request_State state);
/*填写Unix的发送缓冲区,根据请求填写响应包*/
void fill_uwrite_buf(Request_State state);
};
类方法的实现细节中会相继添加一些类成员或者是类成员函数

版权所有 ©️ XiYouLinux Group