前言:最近为了完成课题,需要写系统API的钩子程序。然而系统API种类繁多,手动调配是不可能的。而只改写一些API来应付课题又不甘心,想起之前读某位大佬的论文,提到了写爬虫程序并改写的思路,遗憾的是并没有代码。今天仿照大佬的思路,自己动手了一遍,遇到了诸多问题,以这篇博客记录之。

一、爬取程序

首先,我进入了MSDN的网站(https://docs.microsoft.com/zh-cn/windows/desktop/api/ ),仔细的考量了一下其网站结构,可以发现,想要进入详细的API介绍页面需要三步:

  • 选择头文件
  • 选择详细的API
  • 查看API详细信息

这里以Readfile为例,如果我们想要看到readfile这个API的详细情况,我们需要做三步:点击fileapi.h头文件->找到API->爬取所需要的信息,网站结构如下图:

头文件界面

API界面

于是,我们的爬取路线就很明朗了:

  • 爬取头文件网址作为下级线索
  • 爬API网址作为下级线索
  • 爬你所需要的信息

完成这三步后便得到我们所需要的信息了,我在这里选择了爬取API名称、API原型、API所在的DLL这三条数据。

二、处理原型函数

为了写我们的hook程序,我们应用了easyhook这个开源工具。为此,我们需要编写自己的钩子函数。以WriteFile为例,我们需要将以下我们爬到的函数原型:

BOOL WriteFile(HANDLE       hFile,LPCVOID      lpBuffer,DWORD        nNumberOfBytesToWrite,LPDWORD      lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped
);

改写成我们需要的钩子函数:

BOOL WINAPI new_WriteFile(HANDLE       hFile,LPCVOID      lpBuffer,DWORD        nNumberOfBytesToWrite,LPDWORD      lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped
)
{senddata("Writefile");return WriteFile(hFile,lpBuffer,nNumberOfBytesToWrite,lpNumberOfBytesWritten,lpOverlapped);
}

其中senddata(string str)函数是向我们的监控进程发送数据,这里可以改写成你自己函数,改写完了后再返回原API调用,这样我们就相当于写了一个新的系统API,这个API看起来似乎没什么不同,但其实中间中转过了我们的程序。
除了新的API,我们还要写对应的钩子语句,方便easyhook将我们的API覆盖原来的API:

 HOOK_TRACE_INFO hHook_WriteFile = { NULL };LhInstallHook(GetProcAddress(GetModuleHandle(TEXT("kernel32")), "WriteFile"),new_WriteFile,NULL,&hHook_WriteFile);ULONG ACLEntries_WriteFile[1] = { 0 };LhSetExclusiveACL(ACLEntries_WriteFile, 1, &hHook_WriteFile);

好了,将我们爬取到的API改写成这两部分,并放入我们的DLL就可以开始注入工作了。然而,这只是几百个系统调用中的一个而已。为了完成自动化配接任务,我写了以下一段代码,这段代码的作用是读取API.txt中的内容,即我们爬取的函数原型,改写成两部分,分别至Hook.txt(我们的钩子代码)和API_New.txt(新的API)。

#include "pch.h"
#include <iostream>
#include<fstream>
#include<string>
#include<vector>
#include <regex>using namespace std;
int main()
{int lastpos = 0;int i = 0;ifstream API_Origin("D:\API.txt");ofstream API_Hook("Hook.txt");//储存钩子ofstream API_New("API_New.txt");//储存新的API//函数原型 string API_now;//用于获得参数的正则表达式regex regPere("[^ ][_a-zA-Z]+(?=,|\n)");//储存参数 0号位置为返回类型,1号位置为函数名称,后面的为参数vector<string> peres;//用于储存参数if (!API_Origin.is_open()){cout << "can not open this file" << endl;return 0;}//读取API文件中的一个API至我们的缓冲区,即‘;’前的内容getline(API_Origin, API_now, ';');cout << API_now;while (API_now[i] != ' ') i++;peres.insert(peres.end(),API_now.substr(lastpos, i-lastpos));lastpos = i + 1;while (API_now[i] != '(') i++;peres.insert(peres.end(), API_now.substr(lastpos, i-lastpos));//写我们的新函数API_New << peres[0] << " WINAPI new_" << peres[1]<<API_now.substr(i,API_now.size()-i)<<"{\n"<<"   senddat(\""+peres[1]+"\");\n"<<"  return "<<peres[1]<<"(\n\t";sregex_iterator it(API_now.begin(), API_now.end(), regPere);sregex_iterator end;for (; it != end; ++it){API_New << it->str() << ",\n\t";}API_New << ");\n}";return cin.get();}

先来看看效果吧:


API果然被改写成了我们所需要的形式,总结一下,这段代码主要干了几件事:

  • 在函数返回值和函数名间加上了WINAPI
  • 改写了新的函数名
  • 增添了函数内容
  • 攥写返回值

因为比较晚了,代码比较粗糙,有空再改进,这里原本想得是利用一个vector来存储各种参数信息,后来写着写着觉得太麻烦,于是想尝试着用正则表示式,来获取各个参数,由于以前没用过正则,加上C++的正则机制又比较坑,没想到踩了更多坑。于是把这里的正则单独领出来讲讲。

三、正则的使用

先阐述一下目的吧,我们的函数原型如下:

BOOL WriteFile(HANDLE       hFile,LPCVOID      lpBuffer,DWORD        nNumberOfBytesToWrite,LPDWORD      lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped
);

而返回值需要如下:

 return WriteFile(hFile,lpBuffer,nNumberOfBytesToWrite,lpNumberOfBytesWritten,lpOverlapped);

所以我们得单独把原型里的每个参数拎出来,这种提取子字符串显然是用正则比较方便。细化一下需求,即:提取空格与逗号或换行符(最后一个参数)之间的字符串,但不包括空格与逗号或换行符。
一开始时我用了以下的形式:

“(?<= )[a-zA-Z_]+(?=,|\n)”

并在网上通过了测试:
当我得意洋洋的放在VS里跑时,却得到了下面的错误:

网上并找不到合理的解释,经过多次调试后我认为是C++中正则版本不太一样。这时候经过室友提示,可以在regex后加basic参数,然而试了还是不行。后来我改成了一下形式:

[^ ][_a-zA-Z]+(?=,|\n)

成功的过了调试,总结原因就是C++并不支持“?<=”这种语法(也可能是我没找对版本),以上的模板用于匹配两个特定字符间的字符串均可适用。

hook系统调用(一):爬取MSDN官网上的API调用并改为自己的API(c++正则表达式的应用)相关推荐

  1. 用python输出所有的玫瑰花数_用Python爬取WordPress官网所有插件

    转自丘壑博客,转载注明出处 前言 只要是用WordPress的人或多或少都会装几个插件,可以用来丰富扩展WordPress的各种功能.围绕WordPress平台的插件和主题已经建立了一个独特的经济生态 ...

  2. 爬取CSDN官方博客粉丝中码龄20年以上的用户数量

    文章目录 序 正文开始 IP代理 请求头 cookie 接口分析 爬虫数据保存 重点,爬取数据方法 多线程爬取 完整代码 爬取结果 序 又是一周周末了,闲暇无事,很有精神, 准备看一下csdn社区中码 ...

  3. python人人贷爬虫_爬取人人贷网上部分借贷信息以及数据可视化

    一.主题式网络爬虫设计方案:爬取人人贷网上部分借贷信息 1.主题式网络爬虫名称:爬取人人贷网上部分信息 2.主题式网络爬虫的内容与数据特征分析:爬取人人贷部分信息数据,借贷信息 3.主题式网络爬虫设计 ...

  4. python爬取千图网_python爬取lol官网英雄图片代码

    python爬取lol官网英雄图片代码可以帮助用户对英雄联盟官网平台的皮肤图片进行抓取,有很多喜欢lol的玩家们想要官方的英雄图片当作自己的背景或者头像,可以使用这款软件为你爬取图片资源,操作很简单, ...

  5. Python3爬取国家统计局官网2019年全国所有城市(2020年更新)

    Python3爬取国家统计局官网2019年全国所有城市(2020年更新) 一级城市爬取 一级城市爬取 由于最近需要用到所有城市的数据,故从统计局爬取19年的一级城市数据 import random i ...

  6. Python爬虫爬取链家网上的房源信息练习

    一 原链接:用Python爬虫爬取链家网上的房源信息_shayebuhui_a的博客-CSDN博客_python爬取链家 打开链家网页:https://sh.lianjia.com/zufang/  ...

  7. 如何用Python爬取LOL官网全英雄皮肤

    今天小编带你爬取LOL官网全英雄皮肤的图片 不要失望,也不要难过 接下咱们来讲讲怎么爬取LOL官网 本次案例使用到的模块 import requests import re import json 安 ...

  8. 爬虫实战(二)—利用requests、selenium爬取王者官网、王者营地APP数据及pymongo详解

    概述 可关注微信订阅号 loak 查看实际效果. 代码已托管github,地址为:https://github.com/luozhengszj/LOLGokSpider ,包括了项目的所有代码. 本文 ...

  9. python爬虫入门练习,使用正则表达式和requests爬取LOL官网皮肤

    刚刚python入门,学会了requests模块爬取简单网页,然后写了个爬取LOL官网皮肤的爬虫,代码奉上 #获取json文件 #获取英雄ID列表 #拼接URL #下载皮肤 #导入re request ...

最新文章

  1. 遗传算法来控制进入(一)
  2. 3.IDA-数据显示窗口(导出窗口、导入窗口、String窗口、...窗口)
  3. [译]提案:在Go语言中增加对持久化内存的支持
  4. TIP 2021论文:多曝光图像融合及超分辨的联合实现
  5. php 转发邮件,PHP Email();我不接收转发的电子邮件
  6. 【译】 WebSocket 协议第十章——安全性考虑(Security Considerations)
  7. centos 之7zip
  8. c语言erf函数,c/c++开发分享精确计算缩放互补误差函数,erfcx()
  9. 二、SSD网络原理及代码讲解
  10. 攻防世界-logmein-wp
  11. python——设计一个简单的购房商贷月供计算器
  12. 【文献翻译】用于5G蜂窝的毫米波移动通信:我看行!
  13. 全球最大同性交友网站十周年!
  14. 任正非,马云,马化腾:真正顶级厉害的人,都有一个共同特点
  15. 无线路由器信号互相干扰怎么办
  16. java返回图片base64_java将图片转为base64返回给前端
  17. android广告赚钱[转]
  18. 利用华为短信包开发短信功能中中文转码和msgId获取经验
  19. java后端如何主动发数据到前端_javaweb把后端数据返回到前端
  20. 纯CSS3制作逼真的iphone 6手机模型

热门文章

  1. python判断两个数是否互质_《算法》第一章——判断两个整数是否互质
  2. Weka中分类器指标的说明
  3. C#:Krypton控件使用方法详解(第九讲) ——kryptonRadioButton
  4. Java爬虫.HttpClient
  5. NG Toolset开发笔记--5GNR Resource Grid(9)
  6. 一证通查查询名下互联网账户
  7. 《深入理解Elasticsearch(原书第2版)》一1.1.4 Lucene查询语言
  8. Linux下MyCat的安装即使用
  9. Discuz!论坛实现帖子回复可见内容功能
  10. python3实现阿拉伯数字和中文数字转换