ntdll.dll(vcruntime140dll丢失的解决方法仅一步解决)
资讯
2023-12-04
185
1. ntdll.dll,vcruntime140dll丢失的解决方法仅一步解决?
一步vcruntime140.dll丢失的方法:
打开控制面板,选择程序和功能,右击C++2015(64),卸载,会出现修复选项,点击修复,修复完成基本就可以解决丢失文件问题。
其他方法:
一、如果在运行某软件或编译程序时提示缺少、找不到dll等类似提示,您可将下载来的dll拷贝到指定目录即可(一般是system系统目录或放到软件同级目录里面),或者重新添加文件引用。
二、直接拷贝该文件到系统目录里:
1、Windows 95/98/Me系统,将vcruntime140.dll复制到C:WindowsSystem目录下。
2、Windows NT/2000系统,将vcruntime140.dll复制到C:WINNTSystem32目录下。
3、Windows XP/WIN7系统,将vcruntime140.dll复制到C:WindowsSystem32目录下。
三、打开"开始-运行-输入regsvr32 vcruntime140.dll",回车即可解决。
2. 因为计算机中丢失api?
下载api-ms-win-crt-runtime-l1-1-0.dll复制到系统文件中就行了(1)下载文件api-ms-win-crt-runtime-l1-1-0.dll文件到您的桌面上。(2)将api-ms-win-crt-runtime-l1-1-0.dll文件放到提示丢失的文件的程序目录下。(3)如果第2步是行不通的。将文件api-ms-win-crt-runtime-l1-1-0.dll到系统目录下。C:\Windows\System(Windows95/98/Me)C:\WINNT\System32(WindowsNT/2000)C:\Windows\System32(WindowsXP,Vista)C:\Windows\System32(Windows7/8/2008r2)C:\Windows\SysWOW64(Windows7/8/2008r2)
3. 计算机丢失iusb3mondll怎么办?
下载iusb3mon.dll放到C:\WINNT\System32 (Windows NT/2000), C:\Windows\System32 (Windows XP,Vista,7)或者下载一个dll修复软件再不行就重新暗黄系统就好了
4. 缺少msvcr110dll文件怎么办?
楼主你好,你可以重新下载一个msvcr110.dll文件,然后按如下步骤操作:
上传了,在附件
一、解压后直接拷贝该文件到系统目录里:
1、Windows 95/98/Me系统,复制到C:\Windows\System目录下。
2、Windows NT/2000系统,复制到C:\WINNT\System32目录下。
3、Windows XP/WIN7/Vista系统,复制到C:\Windows\System32目录下。
4、如果您的系统是64位的请将文件复制到C:\Windows\SysWOW64目录
二、打开"开始-运行-输入regsvr32 msvcr110.dll",回车即可解决。
已上传并提供下载连接,可根据需要下载。
msvcr110.dll下载地址:http://51dll.com/dll/file/?173.1.32132.htm
小技巧:如果无法进入桌面,可以启动安全模式或者使用PE启动电脑,然后修复。
【重要】:一定要选择与系统版本一致的DLL才可以
msvcr110.dll无法定位、丢失、找不到、加载失败 等问题的修复
5. 电脑丢失commondll怎么办?
如果你的电脑上丢失了common.dll文件,以下是一些可能的解决方法:
1. 从回收站或垃圾箱中恢复:首先,检查一下你的回收站或垃圾箱,看是否不小心将common.dll文件删除了。如果发现了该文件,请将其还原到原始位置。
2. 在其他电脑或备份文件中寻找:如果你有其他电脑上有相同的操作系统版本,并且已经安装了相同的程序,那么你可以尝试从该电脑上复制common.dll文件到丢失的电脑上。
3. 重新安装相关程序:common.dll文件通常是某个软件或程序的一部分。你可以尝试重新安装与该文件相关的程序,例如游戏、应用程序等。在安装过程中,可能会还原丢失的common.dll文件。
4. 使用系统还原:如果你的电脑上启用了系统还原功能,你可以尝试还原到最近的一个系统还原点。这将恢复你的电脑至先前的工作状态,包括丢失的common.dll文件。
5. 下载并安装common.dll:你可以在一些可信赖的网站上下载common.dll文件,并将其手动粘贴到Windows系统的正确位置(通常是C:\Windows\System32或C:\Windows\SysWOW64)。
请注意,下载dll文件时要小心,确保只从可信赖的来源下载,并且要检查文件以确保其安全性。另外,最好备份你的重要文件和数据,以防止在处理问题时发生意外。如果问题仍然存在,建议你咨询专业技术人员的帮助。
6. 请问comsvcsdll是什么?
comsvcs.dll就是COM+ Services Type Library,也就是COM+的类型库,在winnt\System32里。你找到你电脑里的comsvcs.dll,删掉。再去网上下个放原来的地方。应该就行了。如果不能删你就直接覆盖它。步骤一、如果您的系统提示"找不到comsvcs.dll"或"comsvcs.dll缺失" 或者"comsvcs.dll错误"等等,请不用担心,请把comsvcs.dll下载到本机。二、直接拷贝该文件到系统目录里: 1、Windows 95/98/Me系统,将comsvcs.dll复制到C:\Windows\System目录下。 2、Windows NT/2000系统,将comsvcs.dll复制到C:\WINNT\System32目录下。 3、Windows XP/WIN7系统,将comsvcs.dll复制到C:\Windows\System32目录下。三、然后打开"开始-运行-输入regsvr32 comsvcs.dll",回车即可解决错误。
7. Windows是如何将64位Ntdll映射到32位进程的?
WoW64是什么?
来自MSDN:
WOW64是允许32位Windows应用程序无缝运行在64位Windows的模拟器。
换句话说,随着64位版本Windows的引进,Microsoft需要拿出一种允许在32位时代的Windows程序与64位Windows新的底层组件无缝交互的解决方案。特别是64位内存寻址和与内核直接交流的组件。
两个NT层,一个内核在32位的Windows系统中,要调用Windows API的应用程序需要经过一系列的动态链接库(DLL)。然而,所有的系统调用最终会定向到ntdll.dll,它是在用户模式下将用户模式API传递给内核的最高层。以调用CreateFileW为例,这个API调用源于用户模式下的kernel32.dl,随后它以NtCreateFile传递给ntdll,随后NtCreateFile通过系统调度程序将控制权传递给内核。
在32位Windows下这是非常简单的,然而,在WoW64下需要额外的步骤。32位的ntdll不可以直接将控制权交给内核,因为内核是64位的,只接受遵循64位ABI的类型(译者注:ABI,Application Binary Interface,应用二进制接口)。正因为如此,一个翻译层以几个标准的命名为wow64.dll,wow64cpu.dll和wow64win.dll的DLL的形式被添加到64位Windows。这几个DLL负责将32位调用转换成64位调用。那些调用最终被定向到映射到每个32位进程中的64位ntdll。许多关于这种从32位系统调用到64位系统调用(1)的神奇转换的信息是可获得的,所以我们不会从这里进入。我们最关注的是内核何时和怎样将64位版本的ntdll映射到一个32位进程。看起来像这样:
我们特别关注倒数第二项。我们能发现ntdll被映射到地址是64位地址范围(7FFFFED40000-7FFFFEF1FFFF),而且它的位置在Windows 64位系统文件所在的System32\路径下。然而,我们知道32位进程不可以访问或者运行在64位内存空间。
为了理解上面输出的内容,我们首先讨论VAD(Virtual Address Descriptor,虚拟地址描述符)是什么和它将如何帮助我们理解加载64位dll到32位进程的机制的。
什么是虚拟地址描述符?VAD是Windows操作系统跟踪系统中可用物理内存的许多方法之一。VAD专门跟踪每个进程用户模式范围的保留的和提交的地址。任何时候一个进程请求一些内存,一个新的VAD实力被创建用来跟踪内存。
VAD被构造成一个自平衡树,每个节点描述了一段内存范围。每个节点至多包含两个子节点,左边是低地址,右边是高地址。每个进程被分配一个VadRoot,之后通过遍历VadRoot来分辨额外用来描述保留或提交的虚拟地址范围的额外节点。我们需要关注WindDBG中的!vad命令的输出,因为这是我们将大量使用来跟踪64位Windows中32位进程的映射的输出。对于这个练习,不是所有的域对我们来说都是特别有趣的。我们考虑测试程序HelloWorld.exe的输出。通过!process ProcessObject 命令的输出来分辨我们进程的VadRoot。
一旦我们确定了VadRoot,我将地址输入到 !vad 命令。(输出为了容易分析已被截断)
我们看到五列: "VAD", "Level", "Start", "End", 和"Commit".!vad命令 接受VAD实例的地址;在我们的例子中,我们已经为它提供了在此进程中通过使用!process命令获得的VadRoot。
VAD地址是当前VAD结构体或实例的地址:
等级(Level)描述了这个VAD实例(节点)在所在树中的级别。Level 0是从上面!process输出中获得的VadRoot。开始(Starting)和结束(Ending)地址值用VPN(Virtual Page Numbers,虚拟页数量)表示。这些地址可以通过乘以页面大小(4kb)或者左移3位转化为虚拟地址。结束VPN会添加一个额外的0xFFF来扩展到页面末尾。如我们上面例子中的D20->D20000,DD20->DD2FFF。提交(Commit)是被此VAD实例描述的范围内提交页面的数量。分配类型(type of allocation)告诉我们改特定范围是否已经被映射或是进程私有的。访问类型(Type of access)描述改范围内的允许访问。最后是被映射到当前区域对应的名称。一个AVD实例可以以多种方式创建。如通过使用映射API(CreateFileMapping/MapViewOfFile)或者内存分配API如VirutalAlloc函数。内存可以是保留或者提交的(或free的),或保留和部分提交的。无论哪一种,一个VAD项被映射到进程的Vad树来让内存管理器知道此进程中当前已提交的内存。我们对VAD 的观察将揭示WoW64下运行的32位进程的初始设置。 映射NT子系统DLL进程初始化的早期,在主可执行文件被映射和初始化之前,Windows为特殊区域确定和保留一些地址范围。其中包含初始进程地址空间,共享系统空间(_KUSER_SHARED_DATA),控制流守护位图区域,和NT本地子系统(ntdll)。由于进程初始化整体的复杂性,我们只关注最后一块,它包含32位ntdll和64位ntdll加载到32位进程地址空间的逻辑。我们关注一系列的API调用和在每个点的内存区域的虚拟地址描述符(VAD)。为了让内核区分怎样映射一个新进程,它需要知道是否这是一个WoW64进程。当进程对象最初被创建,内核通过读取名为_EPROCESS.Wow64Process的未文档化结构体_EPROCESS结构体的值来实现此操作。
PspAllocateProcess是我们探索开始的地方,但是更具体的说,我们开始在MmInitializeProcessAddressSpace()。MmInitializeProcessAddressSpace()负责与一个新进程地址空间有关的初始化。它调用MiMapProcessExecutable,该函数创建了定义初始进程可寻址内存空间的VAD项,随后将新创建的进程映射到它的基虚拟地址。
一个特别有趣的函数是PspMapSystemDlls。我们关注在调用PspMapSystemDlls之前的进程地址空间的样子。在WinDBG中确保我们当前处于我们测试应用程序的上下文中(.process),并寻找当前VadRoot(!vad output)。
到目前为止我们可以观察到,我们的进程在32问地址空间中被映射和分配了一个基地址(1200),内核共享内存(0x7FFE0000-0x7FFE0FFF) 和64KB保留内存区域(0x7FFE1000-0x7FFEFFFF) 也已经被映射到他们各自的虚拟地址。
PspMapSystemDlls通过一个包含多个平台子系统模块的全局指针迭代。对于x86和x64Windows,这些是分别位于C:\Windows\SysWow64 和C:\Windows\System目录中的ntdll.dll。
一旦PspMapSystemDlls发现要加载的DLL,它调用PspMapSystemDll 来映射他们(DLLs)到进程的地址空间。该函数非常简短,下面展示了一个片段。为了正确映射本地子系统,需要满足一些条件。
PspMapSystemDll通过调用MmMapViewOfSection实现实际的本地DLL的映射,并保存所占的基地址。在这两个DLL映射完成并且他们的VAD项初始化完成后,我们的32位进程地址空间看起来像这样:
所以现在,我们映射完我们的进程(0xc40000-0xcf2fff),内核共享内存空间(0x7ffe0000-0x7ffe0fff),32位地址空间的有效结束区域(0x7ffe1000-0x7ffeffff),和我们的两个NT子系统DLL。
锁定地址空间为了完成32位进程的映射,还有最后一步要做。我们知道一个32位进程最多寻址到2GB的虚拟内存,所以Windows需要屏蔽此进程剩余的地址空间。对于32位进程,屏蔽在 0x7FFF0000 - 0x7FFFFFFF之后;然而,0x7FFeFFFF之后什么也不可以映射。基于此事实,紧邻64位NTDLL的内存区域需要保留或者屏蔽。要做到这一点,内核标记剩下的64位地址空间为私有。它通过遍历当前进程的VAD树和定位最后可用的虚拟地址来创建此VAD项,然后附加一个新的VAD项。
完成此任务的API是MiInitializeUserNoAccess。该函数接受当前进程句柄和一个虚拟地址。传递的虚拟地址是0x7FFF0000,这是32为进程最后可寻址范围的起始。然后,它遍历当前的VAD项并执行一个新范围的插入,该范围覆盖了32位进程剩余的地址空间。在此调用后,我们的进程地址空间看起来像这样:
我们现在可以发现,我们的32位进程已经映射,并且它的合规的内存地址范围已经被内核保留。涵盖0x7FFF0 - 0x7FFFFED3F和0x7FFFFEF20- 0x7FFFFFFEF 范围的VAD实例已经被内核保留为私有。随后任何检索内存的调用仅仅会发生在允许的32为地址空间内。一旦进程完全加载,我们可以看到额外的已提交的内存出现在进程(0xC40000)附近的地址空间。
结束演讲我们观察到64位Windows下的32位进程的初始映射以及64位ntdll如何被映射到64位区域,随后64位地址空间被锁定,防止用户访问,我们学到了什么?
1. 早期初始化逻辑决定我们是否准备映射一个WoW64进程。
2. 分配最初的32位地址空间区域;这包括最高可访问的32位地址范围,和进程首选的基虚拟地址。
3. NT子系统DLL被加载到他们各自的地址范围,32位ntdll加载到32位空间,64位ntdll加载到64位地址空间。
4. MmInitializeUserNoAccess 用来创建与64位ntdll范围相邻的范围。这具有从32位进程锁定64位可寻址空间的效果。
希望这篇文章提供了一些关于Windows如何允许讲32位进程无缝集成到64位Windows操作系统的透明度。随着WoW64模拟层的添加,对地址空间可用性进行了一些额外的考虑,并且这个过程反映了一些这些考虑和及其实现。
本站涵盖的内容、图片、视频等数据系网络收集,部分未能与原作者取得联系。若涉及版权问题,请联系我们删除!联系邮箱:ynstorm@foxmail.com 谢谢支持!
1. ntdll.dll,vcruntime140dll丢失的解决方法仅一步解决?
一步vcruntime140.dll丢失的方法:
打开控制面板,选择程序和功能,右击C++2015(64),卸载,会出现修复选项,点击修复,修复完成基本就可以解决丢失文件问题。
其他方法:
一、如果在运行某软件或编译程序时提示缺少、找不到dll等类似提示,您可将下载来的dll拷贝到指定目录即可(一般是system系统目录或放到软件同级目录里面),或者重新添加文件引用。
二、直接拷贝该文件到系统目录里:
1、Windows 95/98/Me系统,将vcruntime140.dll复制到C:WindowsSystem目录下。
2、Windows NT/2000系统,将vcruntime140.dll复制到C:WINNTSystem32目录下。
3、Windows XP/WIN7系统,将vcruntime140.dll复制到C:WindowsSystem32目录下。
三、打开"开始-运行-输入regsvr32 vcruntime140.dll",回车即可解决。
2. 因为计算机中丢失api?
下载api-ms-win-crt-runtime-l1-1-0.dll复制到系统文件中就行了(1)下载文件api-ms-win-crt-runtime-l1-1-0.dll文件到您的桌面上。(2)将api-ms-win-crt-runtime-l1-1-0.dll文件放到提示丢失的文件的程序目录下。(3)如果第2步是行不通的。将文件api-ms-win-crt-runtime-l1-1-0.dll到系统目录下。C:\Windows\System(Windows95/98/Me)C:\WINNT\System32(WindowsNT/2000)C:\Windows\System32(WindowsXP,Vista)C:\Windows\System32(Windows7/8/2008r2)C:\Windows\SysWOW64(Windows7/8/2008r2)
3. 计算机丢失iusb3mondll怎么办?
下载iusb3mon.dll放到C:\WINNT\System32 (Windows NT/2000), C:\Windows\System32 (Windows XP,Vista,7)或者下载一个dll修复软件再不行就重新暗黄系统就好了
4. 缺少msvcr110dll文件怎么办?
楼主你好,你可以重新下载一个msvcr110.dll文件,然后按如下步骤操作:
上传了,在附件
一、解压后直接拷贝该文件到系统目录里:
1、Windows 95/98/Me系统,复制到C:\Windows\System目录下。
2、Windows NT/2000系统,复制到C:\WINNT\System32目录下。
3、Windows XP/WIN7/Vista系统,复制到C:\Windows\System32目录下。
4、如果您的系统是64位的请将文件复制到C:\Windows\SysWOW64目录
二、打开"开始-运行-输入regsvr32 msvcr110.dll",回车即可解决。
已上传并提供下载连接,可根据需要下载。
msvcr110.dll下载地址:http://51dll.com/dll/file/?173.1.32132.htm
小技巧:如果无法进入桌面,可以启动安全模式或者使用PE启动电脑,然后修复。
【重要】:一定要选择与系统版本一致的DLL才可以
msvcr110.dll无法定位、丢失、找不到、加载失败 等问题的修复
5. 电脑丢失commondll怎么办?
如果你的电脑上丢失了common.dll文件,以下是一些可能的解决方法:
1. 从回收站或垃圾箱中恢复:首先,检查一下你的回收站或垃圾箱,看是否不小心将common.dll文件删除了。如果发现了该文件,请将其还原到原始位置。
2. 在其他电脑或备份文件中寻找:如果你有其他电脑上有相同的操作系统版本,并且已经安装了相同的程序,那么你可以尝试从该电脑上复制common.dll文件到丢失的电脑上。
3. 重新安装相关程序:common.dll文件通常是某个软件或程序的一部分。你可以尝试重新安装与该文件相关的程序,例如游戏、应用程序等。在安装过程中,可能会还原丢失的common.dll文件。
4. 使用系统还原:如果你的电脑上启用了系统还原功能,你可以尝试还原到最近的一个系统还原点。这将恢复你的电脑至先前的工作状态,包括丢失的common.dll文件。
5. 下载并安装common.dll:你可以在一些可信赖的网站上下载common.dll文件,并将其手动粘贴到Windows系统的正确位置(通常是C:\Windows\System32或C:\Windows\SysWOW64)。
请注意,下载dll文件时要小心,确保只从可信赖的来源下载,并且要检查文件以确保其安全性。另外,最好备份你的重要文件和数据,以防止在处理问题时发生意外。如果问题仍然存在,建议你咨询专业技术人员的帮助。
6. 请问comsvcsdll是什么?
comsvcs.dll就是COM+ Services Type Library,也就是COM+的类型库,在winnt\System32里。你找到你电脑里的comsvcs.dll,删掉。再去网上下个放原来的地方。应该就行了。如果不能删你就直接覆盖它。步骤一、如果您的系统提示"找不到comsvcs.dll"或"comsvcs.dll缺失" 或者"comsvcs.dll错误"等等,请不用担心,请把comsvcs.dll下载到本机。二、直接拷贝该文件到系统目录里: 1、Windows 95/98/Me系统,将comsvcs.dll复制到C:\Windows\System目录下。 2、Windows NT/2000系统,将comsvcs.dll复制到C:\WINNT\System32目录下。 3、Windows XP/WIN7系统,将comsvcs.dll复制到C:\Windows\System32目录下。三、然后打开"开始-运行-输入regsvr32 comsvcs.dll",回车即可解决错误。
7. Windows是如何将64位Ntdll映射到32位进程的?
WoW64是什么?
来自MSDN:
WOW64是允许32位Windows应用程序无缝运行在64位Windows的模拟器。
换句话说,随着64位版本Windows的引进,Microsoft需要拿出一种允许在32位时代的Windows程序与64位Windows新的底层组件无缝交互的解决方案。特别是64位内存寻址和与内核直接交流的组件。
两个NT层,一个内核在32位的Windows系统中,要调用Windows API的应用程序需要经过一系列的动态链接库(DLL)。然而,所有的系统调用最终会定向到ntdll.dll,它是在用户模式下将用户模式API传递给内核的最高层。以调用CreateFileW为例,这个API调用源于用户模式下的kernel32.dl,随后它以NtCreateFile传递给ntdll,随后NtCreateFile通过系统调度程序将控制权传递给内核。
在32位Windows下这是非常简单的,然而,在WoW64下需要额外的步骤。32位的ntdll不可以直接将控制权交给内核,因为内核是64位的,只接受遵循64位ABI的类型(译者注:ABI,Application Binary Interface,应用二进制接口)。正因为如此,一个翻译层以几个标准的命名为wow64.dll,wow64cpu.dll和wow64win.dll的DLL的形式被添加到64位Windows。这几个DLL负责将32位调用转换成64位调用。那些调用最终被定向到映射到每个32位进程中的64位ntdll。许多关于这种从32位系统调用到64位系统调用(1)的神奇转换的信息是可获得的,所以我们不会从这里进入。我们最关注的是内核何时和怎样将64位版本的ntdll映射到一个32位进程。看起来像这样:
我们特别关注倒数第二项。我们能发现ntdll被映射到地址是64位地址范围(7FFFFED40000-7FFFFEF1FFFF),而且它的位置在Windows 64位系统文件所在的System32\路径下。然而,我们知道32位进程不可以访问或者运行在64位内存空间。
为了理解上面输出的内容,我们首先讨论VAD(Virtual Address Descriptor,虚拟地址描述符)是什么和它将如何帮助我们理解加载64位dll到32位进程的机制的。
什么是虚拟地址描述符?VAD是Windows操作系统跟踪系统中可用物理内存的许多方法之一。VAD专门跟踪每个进程用户模式范围的保留的和提交的地址。任何时候一个进程请求一些内存,一个新的VAD实力被创建用来跟踪内存。
VAD被构造成一个自平衡树,每个节点描述了一段内存范围。每个节点至多包含两个子节点,左边是低地址,右边是高地址。每个进程被分配一个VadRoot,之后通过遍历VadRoot来分辨额外用来描述保留或提交的虚拟地址范围的额外节点。我们需要关注WindDBG中的!vad命令的输出,因为这是我们将大量使用来跟踪64位Windows中32位进程的映射的输出。对于这个练习,不是所有的域对我们来说都是特别有趣的。我们考虑测试程序HelloWorld.exe的输出。通过!process ProcessObject 命令的输出来分辨我们进程的VadRoot。
一旦我们确定了VadRoot,我将地址输入到 !vad 命令。(输出为了容易分析已被截断)
我们看到五列: "VAD", "Level", "Start", "End", 和"Commit".!vad命令 接受VAD实例的地址;在我们的例子中,我们已经为它提供了在此进程中通过使用!process命令获得的VadRoot。
VAD地址是当前VAD结构体或实例的地址:
等级(Level)描述了这个VAD实例(节点)在所在树中的级别。Level 0是从上面!process输出中获得的VadRoot。开始(Starting)和结束(Ending)地址值用VPN(Virtual Page Numbers,虚拟页数量)表示。这些地址可以通过乘以页面大小(4kb)或者左移3位转化为虚拟地址。结束VPN会添加一个额外的0xFFF来扩展到页面末尾。如我们上面例子中的D20->D20000,DD20->DD2FFF。提交(Commit)是被此VAD实例描述的范围内提交页面的数量。分配类型(type of allocation)告诉我们改特定范围是否已经被映射或是进程私有的。访问类型(Type of access)描述改范围内的允许访问。最后是被映射到当前区域对应的名称。一个AVD实例可以以多种方式创建。如通过使用映射API(CreateFileMapping/MapViewOfFile)或者内存分配API如VirutalAlloc函数。内存可以是保留或者提交的(或free的),或保留和部分提交的。无论哪一种,一个VAD项被映射到进程的Vad树来让内存管理器知道此进程中当前已提交的内存。我们对VAD 的观察将揭示WoW64下运行的32位进程的初始设置。 映射NT子系统DLL进程初始化的早期,在主可执行文件被映射和初始化之前,Windows为特殊区域确定和保留一些地址范围。其中包含初始进程地址空间,共享系统空间(_KUSER_SHARED_DATA),控制流守护位图区域,和NT本地子系统(ntdll)。由于进程初始化整体的复杂性,我们只关注最后一块,它包含32位ntdll和64位ntdll加载到32位进程地址空间的逻辑。我们关注一系列的API调用和在每个点的内存区域的虚拟地址描述符(VAD)。为了让内核区分怎样映射一个新进程,它需要知道是否这是一个WoW64进程。当进程对象最初被创建,内核通过读取名为_EPROCESS.Wow64Process的未文档化结构体_EPROCESS结构体的值来实现此操作。
PspAllocateProcess是我们探索开始的地方,但是更具体的说,我们开始在MmInitializeProcessAddressSpace()。MmInitializeProcessAddressSpace()负责与一个新进程地址空间有关的初始化。它调用MiMapProcessExecutable,该函数创建了定义初始进程可寻址内存空间的VAD项,随后将新创建的进程映射到它的基虚拟地址。
一个特别有趣的函数是PspMapSystemDlls。我们关注在调用PspMapSystemDlls之前的进程地址空间的样子。在WinDBG中确保我们当前处于我们测试应用程序的上下文中(.process),并寻找当前VadRoot(!vad output)。
到目前为止我们可以观察到,我们的进程在32问地址空间中被映射和分配了一个基地址(1200),内核共享内存(0x7FFE0000-0x7FFE0FFF) 和64KB保留内存区域(0x7FFE1000-0x7FFEFFFF) 也已经被映射到他们各自的虚拟地址。
PspMapSystemDlls通过一个包含多个平台子系统模块的全局指针迭代。对于x86和x64Windows,这些是分别位于C:\Windows\SysWow64 和C:\Windows\System目录中的ntdll.dll。
一旦PspMapSystemDlls发现要加载的DLL,它调用PspMapSystemDll 来映射他们(DLLs)到进程的地址空间。该函数非常简短,下面展示了一个片段。为了正确映射本地子系统,需要满足一些条件。
PspMapSystemDll通过调用MmMapViewOfSection实现实际的本地DLL的映射,并保存所占的基地址。在这两个DLL映射完成并且他们的VAD项初始化完成后,我们的32位进程地址空间看起来像这样:
所以现在,我们映射完我们的进程(0xc40000-0xcf2fff),内核共享内存空间(0x7ffe0000-0x7ffe0fff),32位地址空间的有效结束区域(0x7ffe1000-0x7ffeffff),和我们的两个NT子系统DLL。
锁定地址空间为了完成32位进程的映射,还有最后一步要做。我们知道一个32位进程最多寻址到2GB的虚拟内存,所以Windows需要屏蔽此进程剩余的地址空间。对于32位进程,屏蔽在 0x7FFF0000 - 0x7FFFFFFF之后;然而,0x7FFeFFFF之后什么也不可以映射。基于此事实,紧邻64位NTDLL的内存区域需要保留或者屏蔽。要做到这一点,内核标记剩下的64位地址空间为私有。它通过遍历当前进程的VAD树和定位最后可用的虚拟地址来创建此VAD项,然后附加一个新的VAD项。
完成此任务的API是MiInitializeUserNoAccess。该函数接受当前进程句柄和一个虚拟地址。传递的虚拟地址是0x7FFF0000,这是32为进程最后可寻址范围的起始。然后,它遍历当前的VAD项并执行一个新范围的插入,该范围覆盖了32位进程剩余的地址空间。在此调用后,我们的进程地址空间看起来像这样:
我们现在可以发现,我们的32位进程已经映射,并且它的合规的内存地址范围已经被内核保留。涵盖0x7FFF0 - 0x7FFFFED3F和0x7FFFFEF20- 0x7FFFFFFEF 范围的VAD实例已经被内核保留为私有。随后任何检索内存的调用仅仅会发生在允许的32为地址空间内。一旦进程完全加载,我们可以看到额外的已提交的内存出现在进程(0xC40000)附近的地址空间。
结束演讲我们观察到64位Windows下的32位进程的初始映射以及64位ntdll如何被映射到64位区域,随后64位地址空间被锁定,防止用户访问,我们学到了什么?
1. 早期初始化逻辑决定我们是否准备映射一个WoW64进程。
2. 分配最初的32位地址空间区域;这包括最高可访问的32位地址范围,和进程首选的基虚拟地址。
3. NT子系统DLL被加载到他们各自的地址范围,32位ntdll加载到32位空间,64位ntdll加载到64位地址空间。
4. MmInitializeUserNoAccess 用来创建与64位ntdll范围相邻的范围。这具有从32位进程锁定64位可寻址空间的效果。
希望这篇文章提供了一些关于Windows如何允许讲32位进程无缝集成到64位Windows操作系统的透明度。随着WoW64模拟层的添加,对地址空间可用性进行了一些额外的考虑,并且这个过程反映了一些这些考虑和及其实现。
本站涵盖的内容、图片、视频等数据系网络收集,部分未能与原作者取得联系。若涉及版权问题,请联系我们删除!联系邮箱:ynstorm@foxmail.com 谢谢支持!