Windows 10 x86手动映射注入器:kernel32.dll函数转发循环困惑
Windows 10 x86手动映射注入器中API集转发循环问题解析
问题场景
- 编写x86手动映射注入器时,解析导入表发现
kernel32.dll(路径windows\syswow64\kernel32.dll)中的SleepConditionVariableSRW是转发函数,指向api-ms-win-core-synch-l1-2-0.SleepConditionVariableSRW - 测试DLL从
kernel32.dll导入该函数,手动加载syswow64\downlevel下的API集模块后,发现该函数又转发回kernel32.dll,形成循环 - 检查磁盘上所有该API集副本(含x64版本),均只转发到
kernel32.dll,但用LoadLibraryA注入测试DLL时,实际调用的是kernelbase.dll中的SleepConditionVariableSRW - 核心疑问:Windows镜像加载器如何绕过循环找到正确模块,原以为函数转发名称应直接包含目标模块
解答
Windows镜像加载器的处理逻辑并非完全依赖磁盘上的模块文件转发规则,而是结合进程运行时的API集映射表来完成解析,具体逻辑如下:
API集的运行时映射机制
磁盘上的API集模块只是静态转发占位符,系统加载器在进程初始化阶段,会根据系统版本、进程位数(x86/x64)等上下文信息,构建进程专属的API集映射表(存储在PEB的ApiSetMap结构中)。这个映射表会覆盖磁盘API集文件中的静态转发规则,直接将API集名称映射到实际的实现模块(比如kernelbase.dll)。kernel32与kernelbase的分工逻辑
在Windows 10及后续版本中,kernel32.dll本质是一个顶层转发层,大部分核心系统函数的实际实现都在kernelbase.dll中。当加载器处理kernel32.dll的转发函数时,不会像手动加载那样去读取磁盘上的API集模块,而是直接通过进程内的API集映射表,跳过中间的API集转发环节,直接定位到kernelbase.dll中的函数实现,自然不会触发循环。手动映射注入器的适配方案
要模拟系统加载器的行为,你需要:- 不要直接加载磁盘上的API集模块,而是通过
LdrGetProcedureAddress函数(或者直接读取PEB中的ApiSetMap结构)来解析API集对应的实际模块 - 处理
kernel32.dll的转发时,先解析出目标API集名称,再通过API集映射表找到实际实现模块,最后在该模块中查询函数地址
- 不要直接加载磁盘上的API集模块,而是通过
内容的提问来源于stack exchange,提问作者xref
相关产品推荐
相关产品推荐

