【干货】C++游戏外挂开发教程13:编写DLL注入和调用

文摘   社会   2025-01-06 00:00   广西  


欢迎来到C++游戏外挂开发系列教程! 

游戏外挂开发是一个既有挑战性又充满乐趣的领域,它让我们有机会深入探索计算机程序设计和系统底层原理。本教程将带领你从零开始,逐步学习如何使用C++编程语言开发游戏外挂,包括各种常见游戏中的作弊功能,如自动射击、透视功能、无敌模式等。通过本系列教程,你将了解到游戏外挂的基本原理、常见开发工具、技术挑战和实际应用技巧,为你打造成一名优秀的游戏外挂开发者提供全面的指导。

我们的程序可以加载动态链接库,没错。那么,其他程序是否也能加载我们的库呢?是的,我们可以让其他程序加载我们的库。我们将一段内存写入其中,这段内存包含了我们的 API 函数。

接着,我们将库的参数填充为我们的第二参数。这样,我们就成功地将库加载进去了。其他程序加载了我们的库后,我们的程序就运行在它们的进程中了。这样,它们所有的东西都会暴露给我们。注入完成后,我们就合体了。合体的意思就是,我的功能与他们的进程相结合,但我的功能是由我设计的,做我想做的事情。注入的方法有很多,我知道的就有 20 种。简单的方法之一是远线程注入,它的原理是在其他进程中申请一段内存,将我们的参数填写为我们的第二参数。第二种方法是钩子注入。

比如,使用微软的 API SetWindowsHookEx,它可以拦截系统消息。当其他进程满足条件时,系统会加载 SetWindowsHookEx,并且我们可以在其中加载我们的库。这是消息注入的一种形式。另一种方法是修改函数地址。比如,如果某个程序调用了打印文字的 API,我们可以将其地址改为我们的地址,这样当它调用时,就会执行我们的代码。这种方法比较逆天,但确实有效。完成注入后,我们的代码会在目标进程中正常运行,而目标进程则不会察觉到我们的存在。

这里的是也修改 EIP 的指向,在汇编中,EIP 是改变程序执行流程的关键。它决定了程序下一段代码执行的指向地址,而不是直接改变 VIP。这意味着我们可以改变 EIP,使其跳转到我们指定的代码位置。改变寄存器也是一种方法,比如直接改变 EIP 指向的地址,然后执行我们的代码,完成后再跳回原程序。这种方法直接有效,无需远程申请。

除了直接写入,还有其他方法,比如远线程注入。它通过在其他进程中申请一段内存,并填充我们的参数来实现注入。对于钩子注入,我们可以使用微软的 API SetWindowsHookEx,它可以拦截系统消息,然后加载我们的库。另外,我们还可以修改函数地址,比如修改某个程序调用的函数地址,使其指向我们的代码。这样一来,我们的代码就能在目标进程中正常运行。至于输入法,我们可以伪造一个输入法,欺骗程序,让它认为我们是系统或其他输入法。这些方法虽然多,但都围绕着注入展开。所以,在实践中,我们需要选择合适的方法来进行注入。

当前我们在讨论第二模块的区别,对吧?那就来说说 BEWORD 吧。这个是一个调动原因,是指 60 啊。这里的 2PWORD 不用管它,它是 DL 的入口,对吧?跟 EX 一样,DL 不能像 EX 一样点开就能打开。那么 DL 在被加载的时候会怎样呢?会运行吗?还有被卸载的时候呢?这里稍微写一下 switch,诶,手机来调用原因,带进来。然后搞个 ATTACH,对吧?这是在进程加载时被调用的。在被继承加载时,DL 会执行到这里,对吧?不是一定会跟着那个布瑞克。这点一定要记住啊,之后真的就是一个 freak 啊,不用想都知道。那么 ATCH 是进程加载进程时的处理,对吧?当进程开启一个新的线程时呢?或者进程有新的线程呢?这就牵涉到了多线程,对吧?

你开启一个多线程,它就会响应,对吧?和 EXACTLY 一样,TRDR,这个是进程有一个线程关闭的时候。最后,当进程被卸载时呢?是的,被进程被卸载就是,对吧?但经常被加载的时候,我们就可以比如说我们注入进来了,这会儿我们的第二已经注入进来了,已经打入敌人内部了,对吧?我们要写一个函数,我们 CALL,好好写个函数,WORD,是的。它吃了哭 ASSEMBLY 啊,然后一个汇编过来,对吧?哭啊,游戏吃药控啊,这个参数差一个杀手是吧,人物 ID 啊,任务 ID,这怕一个是吧啊,物品栏,对吧?

我们做过一般是不是这个流程呢?是不是这个流程呢?然后吃药对吧?在这里我们可以直接写一个界面,加载的程序界面,对吧?这个界面,因为我们要开一个线程,对吧?开一个线程在跑,对。是这样。那么今天我们不讲好,我们讲什么?把基础的东西讲清楚啊,免得后面搞不清楚啊。我要写个什么呀?问一下,先让我们的第二被调起来,就被调用起来,对吧?被调动起来之后,我们 INT,我的 LAB,等于导出变量啊。

这样就不能用中文了,如果说要让其他程序调用它,这个变量你就不能用中文了呀。啊你要用中文也导不出去了。我倒对了,倒完我把好。我们的程序怎么调用它?怎么调用它啊?比如说我们现在调用这个地方啊。我现在曝光第二的头文件,对吧?诶,不是他啊,不用包含头文件。我们调用它是不用包含头文件,我看一下啊。我们首先要加载,对吧?外部调用第二。哈,多哈,MODE,然后什么,DEARNODELOADLIB,对

那带上它吧,带上它吧。如果他不成立啊,他不存在,我干什么呀?输出一下,加载地方 400。他们试一下 F 卡跟 F 运行起来,加载失败了。打开项目啊,看啊,它编译到哪啊?我们这同一个工程,我们应该是编译到 debug 里边,对不对吧?Debug 里边这个是之前的啊,我要编译出二了。

两个 EXE 文件和第二模块同时编译,那么必须返回一个值。返回什么值呢?能返回去吧,对不对?T2,Ctrl 加 F7,好,成功了。诶我们是二嘛,它编译到哪儿去了?编译到哪儿去了?Debug,来找找找找,打开文件夹,嗯,编译运行过来啊,DL2,他怎么会生成这个名字呢?我们把它删了,先删了,没接他跑到这儿来,诶跑到这儿来了。

我捋一下捋一下,启动配置生成,对D22 跑到哪去,算了重新来,我搞搞搞乱了不算数。然后重新重新再演示一遍啊,重新再演示一遍。我先把这个删了啊,一会儿搞不清楚,唉麻烦啊,我们先把它删了就打开了,重新演示,创建,呃添加,新建项啊,空项目买DL,源文件添加CPP,Yeah,拷贝进来再添加一个一边一头头文件,原拜拜马,这个第二项目和我们的工程项目是无关的,两个项目是无关的,只是它编译的时候会编译到同一个地方去过来。把这个生成方式改成D22 F7,这玩应该可以了吧,生成了,跑到这儿来啊,得了吧,出来了啊,出来了,那么就不是二,好像是一,看一下啊,成功了,他没提示错误就成功了,看一下。

然后我们我们我们要使用第二中的变量,唉这来写type,这个是个规范,type什么呀,第二中变量等于安提,good for serge,然后把第二带进来,对不对好,然后找找找找他的导出名称,对不对,导出的这个,找出这个对不对,value value对不对,找他,怎么回事?NT,不是这个是函数定义啊,这个是函数定义,好变量不能这么定义,变量不是这样,我们输出一下看看对不对啊,错了,是不是没没有对吧,他没有,是什么原因呢?什么原因?有没有同学知道是什么原因,快知道的打个知道的,打个一,不知道,打个二,不知道都不知道啊,他是为什么呀,因为我们没有导出,因为我们没有导出符号啊,我们需要加一个导出符号。

它返回的是什么呢?我看一下啊,返回的是NT的类型。C盘不允许强制转换,放多的呀,怎么会不允许强制转换呢?哦我们写到外面写错了啊,把这去掉,然后强制转换成这个啊,是这样,这个是定义一个空参数的函数,然后加载函数地址,得到第二函数地址,它的函数名称是什么,方形一对不对?对吧,我们看一下得到了没有啊,嗯看一下复述一下他的这个地址,对不对?啊零零就不对,零就不对,FK线一嘛加载DL过来,是不是必须传一个参数嗯?我们还没有编译啊,还没有编译啊,编译一下啊,啊这下得到了,最后得到他地址了吧,啊得到没有得到了吧,放个屁。我们怎么调用它?我们怎么调用它?对不对?我们怎么在写一个放心,那么直接调用不就行了对吧,既然得到函数地址了,直接调用它,直接调用它对啊。
返回的是多少?12345对,直接点,对吧说了没有都没有,有没有不明白的地方?不明白的打个二啊,明白的打个一啊,没问题吧?没问题。也不知道函数名字,那那就没没没办法了呀。如果说你不知道函数名字,那那怎么导出呢,对吧,你首先你得知道函数名对不对,你不知道他是名名字,只有这样了,只有什么啊,拿到A20反面压反面啊,这样来,我们搞搞搞一下啊,不知道诶,那个小小小宇同学问的也不错啊,他问不知道函数名字这种怎么办啊,我们看一下怎么办,我我我搞逆向是不是要搞,就是要搞这些东西啊。
如果他不给你啊,他不给你函数名称啊,我找的对不对,我们用用IP找,呃我们把它拖过来啊,拖过来不给你函数名称怎么办,这个是什么呀,蓝色的地方就是你的代码就是代码,蓝色的地方就是代码啊,诶诶诶过来了,我找找找找一下,找一下我们的这个导出的导出表,查找视图,打开视图反原与输出函数导出,我们找找啊,看他现在还有没有这个导出输出函数,有没有看到没有,坐上去啊,他不给你名字怎么办,不名字咱们就搞事情啊,不给我们名字我们就搞事情。
然后我们直接反编译代码啊,诶诶跑哪去啊,我们来来来,正好教你们搞一下这个ID呃,我找啊找找他的什么呀,DLM DM,这在哪儿啊,是不是太看下是不是他唉,不是他吧,返回过来还不是这个也不是啊,这个也不是,那找找找找找下,我看下第二问在哪,应该是他,好就是它就是它就是它,这个就是我们的梦函数啊,过来吃饭不是看能写出来啊,它它这个伪代码,他这个是伪代码,我们我们复制一下,复制一下,对不对,他是他伪出来的代码啊,啊和和他一模一样的,是不是一模一样的,但是他那个尾的也不是太好啊。

有输出表的话,我们就没关系了嘛,就没关系了吧。啊是这样这样有没有为ID伪代码,伪的和你这个它尾的是C代码啊。KDA诶阿伟,伪代码是C代码。以后我会教你们用这个ID啊,反编译APK全靠ID。你要搞安卓安排ID,学好学好啊。算不算?我听听听他们说,他说的是不可能被反编译的。啊,根本不懂啊,根本不懂。好继续啊继续,第二MAN啊对吧?函数我们也知道怎么调用的变量,我们也知道怎么取的啊。

现在怎么办啊?如果我们我们写一个类,如果我们第二写一个类,写一个类,我怎么带呀?我怎么带呀对吧?好今天最后的课程啊,把这个类写出来啊,来添加啊,添加什么呀?添加一个类写呃,随便写你的名称,第二DL class对吧?虚析构函数类连啊,不要内敛,虚虚构函数是要的啊,嗯虚啊,不要吧。不要虚,虚的函数知不知道什么呀?现在不用知道也可以啊,现在不用知道也可以。PP.class,我添加的累啊,添加到哪啊?添加到头文件里面,添加了,麦克拉斯好吧。

这样吧,出来了好,这个是实现的类啊,在这对吧?然后然后实现接口函数在这接口函数在这啊,我们来写写写个写个add,比如说NT a,然后NT b,我们添加a加b,我们同样的每个里面都包含这个一边一头。好add在这个CPP里面实现在CPP里面实现这样啊,然后a加b,a给a加b。绿色返回加b对不对?我再加上这个啊,这个表示它是内成员,这这有没有问题啊?这有没有不懂的?这有没有不懂的?我也不懂的吧,明白吧。

我们怎么加载它?怎么加载它?但内LT是C++的对吧?类似C++的,这也是C++的啊。那么那么DI又不语,又不推荐用C++的方式。但怎么办?我们用静态啊,用静态静态链接的方式,静态链接的方式。怎么静态链接啊?怎么进来链接?看一下啊,同样我们要把类导出来导出来,这样把泪导出去之后呢,我们编译啊,编译先编译出来啊,编译出来,把这两个文件带进来,把这两个文件带进来,一个这个静态链接库。



暮色的狐
这是一只高强度上网冲浪、高质量输出内容的狐狸。主打ACGN杂谈、技术干货分享、第九艺术鉴赏、网梗百科解析、情感树洞鸡汤、正能量价值观~
 最新文章