大家好你们可以叫我凌。今天我们来学习下 WOW64兼容性检测与32/64位PEB差异。本篇章具体文档及代码WOW64兼容性检测与32及64位PEB差异Github仓库https://github.com/LingBale/My-Learning-Journey/tree/63c6b8841fd9e53f40e43d2ebdca90431179a5ab/Windows%20%E7%BA%A2%E9%98%9F%E5%AE%9E%E6%88%98/%E7%AC%AC2%E8%AF%BE.WOW64%E5%85%BC%E5%AE%B9%E6%80%A7%E6%A3%80%E6%B5%8B%E4%B8%8E32%E5%8F%8A64%E4%BD%8DPEB%E5%B7%AE%E5%BC%82为什么“位数”是个问题Windows 系统有两套完全不同的内存布局逻辑➢ 64位进程原生运行在64位地址空间PEB在gs:[0x60]指针是8字节。➢ 32位进程在64位Windows上通过WOW64Windows32-bitonWindows64-bit 子系统运行PEB在fs:[0x30]指针是4字节。关键陷阱如果用64位的偏移量比如PEB0x18找Ldr去读32位进程的PEB会读到 一堆错位的数据轻则输出乱码重则直接崩溃。所以在跨进程读取PEB、遍历模块、注入Shellcode之前必须先判断目标进程的位数。WOW64机制的物理本质建立画面➢ 一个32位程序mushiai_chs.exe运行在64位Windows上。➢ 系统为它在C:\Windows\SysWOW64\里准备了32位的ntdll.dll、kernel32.dll。➢ 它的fs:[0x30]指向32位PEB。➢ 但同时系统还会在64位地址空间里为这个WOW64进程维护一个64位PEB用 来跟内核沟通。涉及的核心结构体与类型pNtQueryInformationProcess函数指针类型定义typedef NTSTATUS (NTAPI * NtQueryInformationProces)( HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG );为什么需要自定义函数指针类型NtQueryInformationProcess不在kernel32.lib或标准C库中无法直接链接调用。必须通过GetProcAddress动态获取其地址再强转为该函数指针类型才能调用。PROCESSINFOCLASS枚举类型typedef enum _PROCESSINFOCLASS { ProcessBasicInformation 0, ProcessWow64Information 26, // 本节使用的参数 ProcessImageFileName 27, // ... 更多枚举值 } PROCESSINFOCLASS;ProcessWow64Information 值为 26查询目标进程的 WOW64 状态。ULONG_PTR自适应指针类型ULONG_PTR wow64Info 0;➢ 在32位编译环境下ULONG_PTR 为 4 字节unsigned int➢ 在64位编译环境下ULONG_PTR 为 8 字节unsigned __int64➢ 用它接收 NtQueryInformationProcess 的返回结果可以自适应位数避免在32/64 位环境下长度不匹配。NTSTATUS原生API返回类型NTSTATUS status NtQuery(hProcess, ...);➢ NTSTATUS 是 LONG 的别名4字节有符号整数➢ status 0即 STATUS_SUCCESS表示成功➢ 非0值表示错误如 0xC0000005 表示访问违规涉及的关键宏与常量ProcessWow64Information(值 26)NtQuery(hProcess, ProcessWow64Information, wow64Info, sizeof(wow64Info), NULL);作用告诉 NtQueryInformationProcess我们要查询的是“目标进程是否为 WOW64”。返回值规律➢ wow64Info 0 → 目标进程为纯64位➢ wow64Info ! 0 → 目标进程为32位(WOW64)且该值就是该进程的64位PEB地址NTAPI调用约定宏typedef NTSTATUS(NTAPI pNtQueryInformationProcess)(...);➢ 展开为__stdcallWindows原生API统一使用__stdcall调用约定参数从右向左入栈 被调用者清理栈。➢ 为何必加如果漏写NTAPI编译器默认用__cdecl调用时栈会失衡导致程序崩溃。STATUS_SUCCESS(值为 0)if (status ! 0) { /* 失败 */ }➢ 原生API的标准成功返回码。➢ 等价于status 0。两个辅助APIGetModuleHandleA API介绍作用给一个模块名比如ntdll.dll返回这个模块当前加载在内存里的基址。HMODULEhNtdllGetModuleHandleA(ntdll.dll); //如果成功hNtdll就是ntdll.dll 的基址 //如果失败返回NULLGetProcAddress API介绍作用给一个模块基址和一个函数名返回这个函数的内存地址。//假设hNtdll 是 ntdll.dll 的基址 pNtQueryInformationProcess NtQuery(pNtQueryInformationProcess)GetProcAddress(hNtdll,NtQueryInformationProcess); //如果成功NtQuery就是NtQueryInformationProcess 函数的地址利用链路第 1 步获取 ntdll.dll 基址GetModuleHandleA(ntdll.dll)│└── 返回 HMODULE模块基址失败返回 NULL第 2 步获取 NtQueryInformationProcess 函数地址GetProcAddress(hNtdll, NtQueryInformationProcess)│└── 返回 FARPROC函数地址失败返回 NULL│└── 强转为 pNtQueryInformationProcess 类型第 3 步调用函数查询目标进程位数NtQuery(hProcess, ProcessWow64Information, wow64Info, sizeof(wow64Info), NULL)│└── status 0 → 调用成功│└── 读取 wow64Info 的值第 4 步判断结果┌──────────────────────────────────┐│ wow64Info 0 → 纯64位进程 ││ wow64Info ! 0 → 32位进程(WOW64) ││ 且值 64位PEB地址 │└──────────────────────────────────┘第 5 步关闭句柄清理资源CloseHandle(hProcess)总结➢ GetModuleHandleA拿到ntdll.dll基址这个DLL是原生API的“仓库”。➢ GetProcAddress从ntdll.dll导出表中找到NtQueryInformationProcess函数地址。➢ 强转类型后调用传入ProcessWow64Information参数。➢ 检查status是否为0若成功则读取wow64Info判断位数。➢ 清理hProcess句柄。代码示例以下为相关代码示例以供参考#include windows.h #include winternl.h #include tlhelp32.h #include iostream #include string // 定义函数指针类型为后续通过 GetProcAddress 动态获取做准备 typedef NTSTATUS (NTAPI * NtQueryInformationProcess)( HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG ); // // 判断目标进程架构 // bool IsProcess64Bit(HANDLE Process){ HMODULE hNtdll GetModuleHandleA(ntdll.dll); if(!hNtdll){ std::cerr [-] 无法获取 ntdll.dll 句柄 std::endl; return false; } NtQueryInformationProcess NtQuery (NtQueryInformationProcess)GetProcAddress(hNtdll, NtQueryInformationProcess); if(!NtQuery){ std::cerr [-] 获取 NtQueryInformationProces 失败 std::endl; return false; } ULONG_PTR Wow64Infor{}; NTSTATUS status NtQuery(Process, ProcessWow64Information, Wow64Infor, sizeof(ULONG_PTR), NULL); if(status ! 0){ std::cerr [-] ProcessWow64Information 调用失败 std::endl; return false; } if(Wow64Infor 0){ std::cout [*] 目标为64位进程 std::endl; return true; }else{ std::cout [*] 目标为32位进程64位PEB地址为 std::hex Wow64Infor std::dec std::endl; return false; } } // // 通过进程名获取 PID // DWORD GetProcessPidByName(const std::string ProcessName){ HANDLE hSnap CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(hSnap INVALID_HANDLE_VALUE){ std::cerr [-] 进程快照拍摄失败 std::endl; return false; } PROCESSENTRY32 pe; pe.dwSize sizeof(PROCESSENTRY32); if(Process32First(hSnap, pe)){ do{ if(ProcessName pe.szExeFile){ CloseHandle(hSnap); return pe.th32ProcessID; } }while(Process32Next(hSnap, pe)); } CloseHandle(hSnap); std::cout [-] 未找到目标进程 std::endl; return 0; } // // 主函数 // int main(){ std::string ProcessName; std::cout 请输入目标进程名; getline(std::cin, ProcessName); DWORD ProcessPID GetProcessPidByName(ProcessName); if(ProcessPID 0){ std::cerr [-] 获取目标PID失败 std::endl; system(pause); return 0; } HANDLE hProcess OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ProcessPID); if(!hProcess){ std::cout [-] 进程打开失败 std::endl; system(pause); return 0; } IsProcess64Bit(hProcess); CloseHandle(hProcess); system(pause); }32/64位PEB偏移差异对照表目标内容64 位PEB偏移32位PEB偏移LdrPEB0x18PEB0x0CInMemoryOrderModuleListLdr0x20Ldr0x14LDR_DATA_TABLE_ENTRY 的 InMemoryOrderLinks0x100x08DllBase0x300x18BaseDllNameUNICODE_STRING0x580x2CEntryPoint0x380x1CSizeOfImage0x400x20
企业数字化 ERP 产品动态
相关推荐
基于微信小程序的医疗服务系统-附源码 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台… · 2026/9/24 17:28:04
Lecture: Interactive Speaking Interactive Speaking 中的精准语言
你的下一个目标是准确性,而不是新的答案结构。在 Interactive Speaking 中,每个回答持续 35 秒,没有准备时间。简短的填充词,例如 “Well, let me think”,可以帮助你开始。然后使用具体的语言,而不是重复一般的短语。例如,将 “get… · 2026/9/24 17:28:04
基于微信小程序的学校食堂点餐系统-附源码 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台… · 2026/9/24 17:28:04
农田害虫检测实战:YOLO数据清洗与小目标优化指南 简介:本资源是2022年泰迪杯数据挖掘竞赛A题《农田害虫检测识别》的完整实现方案,面向计算机、人工智能、自动化等专业学生及初学者,解决农业场景下小目标、多类别的害虫视觉检测难题。项目基于Detectron2框架,创新融合Mask R-CNN与… · 2026/9/24 18:38:27
养老中心护理服务管理系统:基于asp.net的毕业设计全攻略 1. 毕业设计选题:养老中心护理服务管理系统,到底值不值得做每年到了毕业季,计算机专业的同学们就开始为选题发愁。选题太简单怕过不了答辩,太难又怕做不完,更怕的是选了个满大街都是的“图书管理系统”或者“学生选课系… · 2026/9/24 18:38:27
Flutter跨平台共享社区App架构设计与HarmonyOS适配实战 1. 项目概述与整体技术选型1.1 “享”到底要解决什么问题做“享”这个共享社区App之前,我们团队其实犹豫了很久。市面上的社区类产品已经非常成熟,从早期的BBS到现在的信息流产品,用户对“社区”两个字已经有了非常固化的认知——无非是发帖子… · 2026/9/24 18:38:27
端口扫描与Snort检测:从nmap参数到日志聚合的实战解析 我自己的主机最近被安全部门拉出来做了一次授权巡检,nmap 扫完回来看到一堆 open 端口,说实话那一刻我心里是有点发虚的。端口扫描这个词听起来像是安全从业者的基本功,但真正能把“扫出来的东西”讲清楚、用明白的人,实际上并不算… · 2026/9/24 18:38:26
平潭智能家居服务:高湿高盐环境下的系统韧性实践 1. 平潭智能家居服务的特殊性:不是装完就完事,而是持续运转的系统工程“想找平潭服务好的智能家居?这里有你不可错过的答案!”——这句话乍看像一句普通广告语,但如果你真在平潭买过房、装过家、甚至跑过三趟装修工地&… · 2026/9/24 18:38:26
SpringBoot图书馆座位预约系统:从需求拆解到核心实现全流程指南 每年一到毕业季,“图书馆座位预约系统”就会出现在很多计算机专业的选题清单里。我接触到不少同学拿着“星辰阅影”“书海拾座”“静阅空间”这类项目名来问,其实它们本质上是同一套东西——基于Java的SpringBoot图书馆座位预约系统,换的是名… · 2026/9/24 18:38:20
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44