【干货】《绝地求生》外挂开发教程10:9-9-9-9-12分页
文摘
社会
2025-01-02 00:11
广西
本期教程我们要讨论为了一项任务做好准备的情况。回想一下我们之前的代码,你还记得吧?我们要去目标进程用的是跨进程VisualAllocEx,跨进程申请一段内存。但是这个内存里面只有可读和可写的权限,如果你把可执行的权限也加上了,它就无法注入成功了,申请不出来。所以为了解决这个问题,我尝试过直接在CR3这个方面做修改。我们打开的假设是我附加的是绝地游戏,因为我们没有处理这个,第八个附加不了绝地对吧?我尝试着去修改这个页属性,页属性是一个内存地址的一页的属性。这又涉及到了页的概念。页是Windows内存管理的一种方式,等一下我们来详细讲解。也就是说,这些内存都是分成一页一页的。每一个页都有自己的属性,而这个属性是当前的属性。但直接改变这个属性是不行的,它会检测最初的保护属性。如果你最初的属性里没有可执行的权限,它会检测到你没有这个属性,然后将其卸载。那么,遇到这种情况要怎么办呢?我们想了一个办法,我们直接改变这个物理页的属性。这个时候又涉及到了一个物理地址。所以,这节课我们也讲不到那么深入。我们这节课就来讲一讲什么是页。页上面都是一些虚拟地址,虚拟地址就是一个64位程序里的内存地址。理论上,它是从0000到FF,一共有64个一对。这在理论上是如此,但实际情况是,虚拟地址就是我们在使用C语言时看到的地址。当我们用C1看到这个地址时,这个虚拟地址也被称为线性地址。这个地址是虚拟的,是每个进程都有的。但是,这涉及到一个问题,就是操作系统是否有足够的硬盘空间来容纳每个进程的大量内存地址。如果每个进程都拥有64GB的内存地址,那么开启100个进程就需要100个64GB,这样的话硬盘是否足够使用呢?这就涉及到Windows的内存管理。硬盘上的空间会映射为物理地址,而内存地址并不直接对应物理地址,而是经过一层映射。这个映射涉及到硬件层面的东西,我们不在此讨论。我们的重点是讲解物理地址如何与虚拟地址对应。有一句话是这样说的,也是我在百度上找到的:Windows只有正在被使用的线性地址才会被映射为物理地址。也就是说,一个程序并不是整个64GB的内存都在使用,它可能只是使用了一小部分,比如说几十KB或几百KB。只有正在使用的部分才会被映射为物理地址。如果一段时间没有使用,或者当前的物理页被用完了,那么就会把这些数据存储到硬盘上。这个存储的位置可以在系统配置中找到,如下所示:(这里可以插入一些相关的图表)。总之,我们现在要深入研究的是物理地址究竟是什么样的,以及它和虚拟地址是如何对应的。在我们的64位系统中,我们使用的是9994个912分页,也就是四级分页机制,这是Windows系统的一种分页形式。每一个9代表一个级别。虚拟地址和物理地址之间的转换是我们今天要关注的重点。讲这么多理论可能有点枯燥,但是通过实际操作将虚拟地址转换成物理地址,或者将物理地址转换成虚拟地址,大家就能更好地理解。让我们打开调试工具,比如WinDbg。我们打开C1,这样就关闭了当前窗口。比如,我在这里编写了一个网络。然后,我附加到记事本,搜索网络的话,必然会有一个内存地址存储着。代码页勾选上还是阿斯卡?不用勾选也可以,不过是阿斯克的,所以没关系。我们可以尝试修改一下,看看地址是否发生了变化。如果搜索不到,可能是因为网络是阿斯克的。它每次都会有一个新的内存地址,所以这不是很重要。接着,我们可以看看Gun Process,看看有没有相关的信息。我们可以使用999912分页的方式来进行分析。我们可以看到两个可能是因为之前打开过一次,有一些缓存。我们要关注的是dial base,也就是CR3,物理机制。我们可以用一个命令来查看其二进制格式,然后我们可以拆分这个64位的地址。我们来拆分一下。其中有48位,前面的16位可能是FFF或者其他值,表示内核地址或用户地址。接下来的16位表示我们自己使用的部分。然后,剩下的16位是要看的关键部分。这48位需要拆分成四个9加一个12,这样就是48位。首先,我们看看这个地址的前半部分,是不是一个9加一个8?这应该是一个9。然后是六位,应该是777加2,都是9。最后一个是99加3,应该也是9。这是第一步。我们用一个代码段来展示一下。这个颜色就用黑色吧。然后,我们还要进行第二步的拆分,把它变成这样。这是第二步。现在你应该知道我们要做什么了。我们要把记事本中的内存地址转换成对应的物理地址。这个物理地址由四张表组成,因为是四级分页。我们通过虚拟地址的位数来查找它在物理页表的哪一页上。我们将它转换成16进制。这里是一个F对吧?真的是吗?这个是888加2,应该是AB对吧?这里是084对吧?再往下就不对齐了。这里是700吗?好,这样就分析出来了。然后我们继续。我们刚刚看到了CR3对吧?CR3实际上是一个特权寄存器,里面存放着物理页表。只有内核才有权限访问。那么我们现在要看一下DQ表,长这样对吧?好,现在我们要开始查找微财网络这个内存地址存在于哪个表的哪个页面。首先是003,所以你只需要加上003,就是0X0038乘以8。这是第一层。第一层长这样,我们需要拿的是这一段,最后三位不用拿,要改成000。然后是第二层,长这样,八后面三个零,我们拿选中的这一段,同样把后面三位改成零,然后乘以8。然后进入第三层,同样的,只拿三位,还要留三位。最后进入第四层,是084。这样,就到了这个页的第七版的地方。第700的地方,我们需要同样的步骤,不要后三位,加上700。这里不需要再乘以八了。我们要把它转成DDB,因为我们是字节级数组。我这里也可以把它转成字节级数组看看。看起来一模一样的,后面的就不用看了。所以这就是我们的四级页表。最开始的PPT里面是一个CR3寄存器,存的就是第一张表的地址,然后它一共有四张表来存放每一个页。这种寻址的方式最终能找到你这个页所在的地方,然后最后面的12位就是你的偏移,就是你这个地址在物理内存中的偏移,它就这样给你挂上去了。这就是我们本期教程要讲的内容。我建议大家跟着我敲一遍,找一遍,然后你就能理解了。虽然X86和64的X86有点不一样,但基本原理是相似的。如果你搞懂了本期教程,接下来的内容你就能看得懂了。好,本期教程就到这里吧。