【干货】《GTAOL》外挂开发教程10:动态库劫持
文摘
时事
2025-01-08 00:00
广西
欢迎回到我们的教程,咱本期继续深入开发动态库劫持。首先我们需要声明一个头文件。在这个头文件中,我们声明需要导出的枚举结构体。然后,我们需要实现这个枚举的结构体。总体来说,这个流程是有点麻烦的。我们需要考虑声明头文件、实现枚举结构体,还要把这些东西搞到动态库项目中去。但有时候,直接把这些东西丢到汇编里会更简单一些。
基本上,整个流程就是这样的:首先,用工具把符号导出来,比如说这里有个A点DL。然后,把这些符号搞到我们的动态库项目中去。最后,生成一个动态库,把它给替换掉。这个流程大家清楚了吗?主要的工作集中在声明头文件、实现枚举的结构体,以及工具的使用上。操作步骤没有问题吧?都不要睡着了,如果有问题,可以留言讨论。我们要做的这个流程主要就是这样,要写代码主要是集中在这个工具上。至于导出符号的问题,相对来说比较简单,因为在2019里面有这个功能。但是需要注意的是,要区分是32位还是64位的。可以通过计算器来判断,看寄存器是否是64位的。如果是64位的话,那动态库一定是64位的。
如果你的寄存器是AXBXCX,而没有任何一个是ex,那么就是16位的。所以这个地方一定要注意,要用对应的当铺兵。在64位的项目中,不要使用32位的当铺兵,否则可能会出现问题。要确保一致性,否则会导致一些无法弹出的问题。为了导出符号表,我们需要使用export命令。通过这个命令,我们可以得到一个符号表的导出结果。这个导出结果通常会输出到标准输出,是一个文本形式的导出符号表。解决符号问题的关键在于处理这个导出符号表。我们可以使用管道将命令的输出重定向到文件中,然后逐行读取这个文件,找到我们需要的导出符号表。一旦找到,我们就可以开始处理这些符号。整个工具主要分为两个项目:工具项目和动态库项目。工具项目负责导出符号表并处理,而动态库项目则稍微复杂一些,因为它需要进行一些初始化的处理,包括加载动态库并加载导出符号。由于这些导出符号通常不可能自己去实现,所以我们需要加载它们并在之后使用。因为我不清楚你的游戏规则和参数结构,我也不想去做这个事情。如果必须根据你的参数结构去调整我的代码,那就太麻烦了。除非有特别关键的函数,你觉得必须手动实现,否则我会按照默认的方式去编写代码。整个代码的总体方案很清晰:有一个工具类和一个动态库类。工具类的主要任务是导出符号并生成动态库所需的内容,最终生成一个动态库。这个动态库将会提供给游戏使用,可以理解为一种暴力破解方式。在导出符号的过程中,我会介绍一个函数。这个函数的作用是处理一些变化的结构。在这个函数中,我会忽略特定位数的整数和十六进制数字,然后取得我需要的值。如果解析失败,我会终止操作。这个逻辑需要理解清楚。这个地方我想要提一下,虽然你可以自己去实现,但是可能会让代码变得更复杂一些。不能像这样一行代码解决问题,有些复杂的情况可能需要使用正则表达式,但我认为没有必要。这个地方可能会成为一个坑,如果你自己写的话可能会更麻烦一些。现在我要创建一系列的文件,包括临时的头文件temple.h。temple.h中包含一些函数指针,因为这些函数指针的参数类型可能会变化。我要声明一个函数指针类型,并且使用C的方式来声明变量,因为它可能在C和C++中使用。这是一个小细节。声明完这些变量后,我要实现一个函数,这个函数会给上面声明的变量填充真实的值。有同学问handle是从哪里来的,其实在汇编中也有定义,它是一个八字节的值,因为我们是64位的系统。接下来,我会加载动态库并且填充函数指针,然后加载符号。在调用真实函数之前,我还需要做一些工作,但还差一点点。现在,我们加载了动态库,将其函数指针加载到了load_funk中,这些函数指针实际上是真实的工作库函数。然后,我们在load_funk中声明了这些变量,并且进行了导出。接着,在这里进行了实际变量的声明,在ext中进行了导出符号的声明。然后,我们还有第三个任务,那就是实现本地符号函数。我们需要将这些函数实现,并且在接下来的时间里要做的事情是声明并实现这些函数。在代码中,我们需要实现的是将名称中的问号和艾特符号去掉,以便与其他地方兼容。因为在汇编中,这些符号是不需要的。我们将名称与PLC、POC等结合起来,以确保它们符合特定的格式要求。接下来,我们要填写这些函数的函数体了。函数体的构建需要考虑到一些细节,我稍微思考一下。在这个过程中,我发现我们可能会用到之前提到的temple,看起来它还挺有用的。在这个过程中,我们需要使用到一些指令,比如move。我们需要将函数名称直接传给IX寄存器,然后进行跳转。在函数体中,我们的目标是不破坏其他寄存器的值,一般来说,函数参数会使用RCX、RDX,以及R8、R9寄存器。IX和BX寄存器一般不用于传递参数,但我们需要在这里使用它们。然后,我们加上一些换行符号,保持格式的清晰。再试一下这段代码能否运行,我需要确认一下。看来还要添加一些换行符,让代码看起来更清晰一些。然后,我要检查一下这个动态库是否能正常工作。我看看导出符号表,确认一下是否一切正常。在导出符号表的地方,可能还需要添加一些内容。可能还需要在这个地方添加一些东西,我先试一下public这个指令,看看有没有问题。查一下汇编导出的内容,看看有没有问题。看起来比较麻烦,动态库的导出要处理一下。在填写函数体的过程中,我们要确保不破坏其他寄存器的值,一般情况下函数参数会使用RCX、RDX、R8、R9等寄存器,而IX和BX寄存器一般不用于传递参数,但我们需要在这里使用它们。然后,我们需要在函数体中添加一些换行符,以保持代码的可读性。我要试一下这段代码是否能正常运行,需要确认一下。看来还要添加一些换行符,让代码看起来更清晰一些。然后,我要检查一下这个动态库是否能正常工作。我要查看导出符号表,确认一下是否一切正常。在导出符号表的地方,可能还需要添加一些内容。我要试一下使用public这个指令,看看有没有问题。查一下汇编导出的内容,看看有没有问题。看起来比较麻烦,需要处理动态库的导出问题。接下来,我们需要填写这些函数的函数体。函数体的构建需要注意保留其他寄存器的值,一般来说,函数参数会使用RCX、RDX、R8、R9等寄存器,而IX和BX寄存器一般不用于传递参数,但我们在这里需要使用它们。然后,我们要在函数体中添加一些换行符,以保持代码的可读性。我需要试一下这段代码是否能正常运行,需要确认一下。看来还需要添加一些换行符,让代码看起来更清晰一些。然后,我要检查一下这个动态库是否能正常工作。我要查看导出符号表,确认一下是否一切正常。在导出符号表的地方,可能还需要添加一些内容。我要试一下使用public这个指令,看看有没有问题。查一下汇编导出的内容,看看有没有问题。看起来比较麻烦,需要处理动态库的导出问题。下一步是要导出一个名为test的函数,还需要添加一个DX文件。我得看一下。需要确保属性链接器设置正确,输出的文件也没问题。看起来还需要添加一个DX文件。让我看看。还要检查一下TTF文件的位置。看一下VS动态库DX。看一下DX文件。需要添加一个输入模块定义文件,然后再指定一个DX。在这个指定的DX文件中,我们需要添加一些内容。我们需要创建一个新的Replacement并将其添加到DX文件中。我先试一下手动添加。看看能不能成功。这个库的名字是Replacement,别名是“有人性能”。我看看能不能导出FK线中的方向盘。我再看看。重新加载一下。重新加载一下看看。又有一个新的问题,符号的导出有问题。现在代码已经有了,但是缺少一个符号的导出。还是有点麻烦。有个地方有问题。需要把N改成PDF。在导出符号的部分,我要写一个PDF。如果不为空,那么就是Export。然后添加FY Fright和c spring,然后添加一个PDF,最后再添加一个换行。然后添加PDF,把FLZ也加上去。DX还是有点麻烦,因为汇编的导出有点麻烦。我先看一下改变了什么。导出一个名为test的函数,还需要添加一个DX文件。我得看一下。需要确保属性链接器设置正确,输出的文件也没问题。还需要添加一个DX文件。让我看看。还要检查一下TTF文件的位置。看一下VS动态库DX。看一下DX文件。需要添加一个输入模块定义文件,然后再指定一个DX。在这个指定的DX文件中,我们需要添加一些内容。这里我要查看导出符号表。有一个DLL入口点,这个是DXNK的破译。我要看一下他的原版。原版的那个地方好像也是有一个叫做f model的地方。原版是有个这个东西的。这个h instant reason,就是那个DL MAY。所以这个地方我得复制一下,如果复制不走波,他是这个地方有一个DX修复,也是跟这个东西一样的啊。首先我们得弄一个这个类型,然后这里的话呢就是这样子的。其实我都无所谓,觉得有帮助就可以了。不可能像这种东西都不太可能说,就是所有的人都能够明白的啊,不太可能的。这个东西可以不要啊。不太可能说所有的人都能够都能够去接受啊。你想学技术,他到后面肯定是慢慢地,因为这个东西很简单,两三下就懂了啊,大家都搞明白了,你这个东西有啥意义呢?没啥意义啊,都会了就不值钱了,撑不下去的就不要留下来,这是最好的,就是最好的一个事情,留下来的愿意听的就听啊,还是这个样子,有那么一两个人能听进去,我觉得就可以了,没啥大不了的,这个是很正常的事情。这里面有一个问题,就是我要把这个东西给加载上来,就是这里面有一个a real real entry啊,有一个这个东西,这个东西是空的,然后呢我要把这个东西给它搞过来,然后这里是这样的,这个地方是必须要进行一个数据类型转换的,不转换的话,这个是不行的。好搞了这个东西以后,这里面我要再来看看,如果他这个东西不等于空,成功加载了的话,那我就要返回这个东西。成功加载了的话就是h model,然后就是ul reason,Reason for cool,然后就是lp reserved啊。为什么要搞这个东西?这个地方的话,这个地方就是这样的,这个地方就是这个样子的。那么这一块东西的话呢,就是因为这个动态库啊,它本身也有个DLN,也有个dx main这个函数,我必须要把他的这个给调一下,防止他在这个里面加一些初始化。我要防止他在这个里面加初始化。如果他加了初始化,我又没有调用它的话,这个时候会出问题,就是比较麻烦,就是说有些初始化没做,然后你调用可能这个程序不正常,可能会挂掉啊,所以这个地方我得把它去弄一下。然后我要把这个地方重新生成一下。那我加载完这个玩意以后呢,我会去调它的这个东西好。然后这里面还有一个问题,就是我要怎么知道我的这个东西是不是调用了?所以我还得加一个东西啊,就是等于这个FO,我得写个日志出来,这个东西没办法去调试了,我只能写个日志,写个日志叫做logo.txt,然后这里的话就是A加A加,就追加的一个形式去弄。如果这个p feel不为空的话,那我们就f close,FCLPFI怎么关闭掉?当然在这个之前,我要f right f right,就是hello,然后这里的话就是1234啊,这个地方也是这样的,这里的话是1234566个字节,六个字节,所以我这里就是一六,然后就是p feel,就是每一次调用这个地方,我就会打个卡漏出来,那我就知道这个玩意是OK的了。