特征码扫描(Signature Scanning)
说明
本文演示一个被 Lance Vorgin 称为 “签名扫描”(sigscanning) 的技术
签名扫描(sigscanning) 是什么?
sigscanning 是一个从二进制文件中提取 函数(function) 签名的过程,然后在程序运行时扫描并定位这个隐藏的函数(function)。函数的签名(signature)是函数(function)唯一的一组字节。这些字节是程序用于执行的指令。当我们有足够多的字节来形成一个唯一的集合时,我们就可以再次从内存中匹配到这些函数。
为什么这对插件有用?每次valve释放他们的更新,都有可能改变CBaseEntity(被很多插件开发者用来操作玩家数据的实体)。由于每次更新我们都没有对应的类头,所以我们之前使用的虚拟函数可能现在基址已经改变,这将导致运行时崩溃。为了避免这种情况,下面的解决方案:
- 依靠手工设置offsets偏移到类的虚拟函数
- 修改类头插入虚拟函数来修正offsets
- sigscanning
每个方法都有优缺点,但事实证明,虽然sigscanning是最麻烦呐的,但它却是最可靠的。前两个通常会因为更新而被破坏。
程序集和内存
要了解这一切,首先要了解c++代码如何编译成二进制文件。
当你点击“生成解决方案”在你的IDE或运行文件,编译器会多种操作。首先用代码并运行它通过一个预处理。预处理器把所有的“#”指令(如#define,#include,等)和替代他们正常的C++代码。在预处理方面所做的工作,代码传递给解析器。简单来说,解析器主要以C++代码转换为汇编(ASM)代码。在解析器解析代码转换为汇编代码,汇编代码为“组装”机器(字节)编码是把目标文件进行.obj或.o扩展名。然后链接器收集所有对象文件的地方寻找函数的调用和设置“链接”给他们(静态链接)以及外部函数调用外部汇编代码的范围(动态链接),最后将任何运行时调用(运行时链接)。在这之后,最后输出成品(二进制文件,即一个可执行文件或库)。当服务器加载你的插件,它使用运行时调用在你的插件调用函数,同样你的插件调用的功能从服务器。
现在,这一切在sigscanning进场,你将以服务器模块(.dll或。所以文件)从内存和扫描它的机器码形式的那些功能,你需要。这是第一次拆卸服务器模块重新装配形式和发现弥补功能你想要的指示做。
程序集是“低级”语言。这是很容易组装和机器代码之间的触发器,因为他们基本上是相同的,除了装配使用所谓的“记忆”在每一个指令。这些都是人类可读的关键词 push, pop, mov, call、等,定义了什么是教学。为C++代码翻译成汇编,你可以想象的结构语法的C++将为原始简单的汇编指令。我不会进入进一步的细节上由于其复杂性装配。要了解更多关于它的最好的方式(推荐)是阅读的参考链接在写这篇文章的底部。

浙公网安备 33010602011771号