目录
进程和线程的概念
进程是一个容器,容器里面装的是线程
把进程比作工厂,那么线程就是工厂里的工人。
工厂提供生产资料,工人在流水线上把生产资料打造成产品。
所以为什么说多线程要比单线程快,工厂里面只有一个工人,那干活能快的起来吗。
当然也不是说线程这玩意越多越好,工厂的空间是有限的,计算机的资源也是有限的。
假设一个小工厂,里面有几十万个工人同时干活,人山人海、水泄不通,那干活效率还不如几个人来做。
计算机也是如此,线程主要消耗的是cpu,进程消耗的是内存。
一般来说,进程拥有的线程刚好是cpu核心的数量,这时效率是最高的。
运行中的程序有四大空间:数据区、代码区、堆区、栈区
进程提供数据(常量、全局变量、静态变量..)、代码
告诉线程该怎么做,拿什么做。
线程之间是并行的,也就是说这条流水线卡带了,并不会影响另一条流水线的工人正常干活。
数据区和代码区都是归进程所有的,是给线程拿来用的。
栈是只有线程才有的,栈的大小一般固定为1M,用于存放局部变量和一些cpu上的数据。
线程其实就是函数。
你想,工人干活总的需要点工具吧,工具肯定要放在身边比较近的地方才好对吧。
对于线程来说,访问局部变量的速度要大于全局变量,访问栈区比访问数据区要快。
钩子注入原理
现在假设我们有一个正在运行中的游戏,一个用于注入的程序。
注入程序包含 注入器(注入程序本身)、注入模块(DLL 动态链接库)
钩子注入需要4样东西:消息、消息响应函数、注入模块、通过哪个线程完成注入
其实钩子注入更直白的叫法应该是消息注入才对。
我们这里以键盘消息举例,你按下键盘的按键就是一个消息。
比如你按下了home键、A键、CTRL键.....
那么操作系统收到了这个按键消息,该发送给谁呢?
一般来说是发送给活动窗口,也就是当前你正在操作的程序。
比如说你正在打lol,那么你按下一个R键,那操作系统肯定是发送给你呀,你要放大招了呀。
但是操作系统给我们提供了接口,使得我们可以截取到发送给任何程序的键盘消息。
想想如果操作系统不准你这么做,那么哪些搞截图、录屏、输入法的软件还怎么活。
为什么要叫钩子注入呢,因为一个一个的消息就像一节一节连着的火车车厢。
车厢之间要用钩子连起来,消息之间也是用钩子连起来的。
我们要截取操作系统的消息,就是通过这中间的钩子,当然写代码的时候其实看不出来钩子不钩子的。
重申一遍,钩子注入需要4样东西:消息、消息响应函数、注入模块、通过哪个线程完成注入
注入是干什么,就是把我的代码(注入模块)放到别人的程序里。
消息我们这里单指键盘消息
消息响应函数就是拿到消息之后要给谁去处理
注入模块有我们写好的一些功能代码(无敌、加速啥的),还有消息响应函数。
线程就是别人程序的主线程或子线程。
钩子注入其实更像是给操作系统增加一条规则。
首先我们拿到了一条消息,也就是用户按键行为了。
那么他具体按了哪个键,是home键,回车键还是关机键,就交给消息响应函数做判断。
消息响应函数判断之后,知道这小子原来是按了F1键,这不就是要开启无敌了嘛。
那么无敌的代码在哪呢,就在注入模块里面。
接下来呢,计算机怎么知道是哪个游戏要无敌,这就要我们指定一个游戏的线程。
需要注意的是消息响应函数是放在注入模块里的。
注入模块一开始是放在注入器里的,游戏线程是没有的。
那么操作系统就懵圈了呀,键盘消息是要发给消息响应函数的。
你指定的游戏线程里面又没有他的注入模块,这样就不行呀。
所以操作系统就帮你完成了注入这档子事。
至于这里为什么要指定程序的线程而不是进程。
进程是工厂,注入模块是包含了数据和代码,注入模块确实是放在进程里的没错。
但是工厂是不会自己动的呀,就像来了一车货,肯定是叫工人去搬,而不是工厂。
所以指定线程是要让游戏的线程把你的注入模块搬到进程里面去。
本来消息发出是直接给游戏线程的。
我们做了钩子注入后,消息再发出,就会先由我们的响应函数处理,再给指定的线程处理。
指定的线程有俩个作用,一是辨别身份,告诉操作系统模块注入到哪,二是消息的传递
写到这里1550多个字了呀,求个免费的点赞可以嘛,看官老板