最新要闻
- 广汽集团曾庆洪:汽车产业告别高增长黄金时代,淘汰赛加速进行 全球视讯
- 大爷将2台电动车焊一起自制代步车:觉得代步车太贵
- 小金毛冲进考场被无情请出 网友:忘带双证了?
- 突发!中国电信大面积崩溃:手机没信号、电话空号
- 显卡带来巨额利润 英伟达股价还能再涨30% 五大看涨理由…… 播资讯
- 今日精选:看似灯泡其实是个智能家居摄像机!萤石C8b 4G版图赏
- 天天微头条丨头部 UP 主入局,B 站带货时代来了?
- 中意悦享安康重疾险怎么样?保什么? 每日热讯
- 弥勒岩在福清什么地方_弥勒岩
- 商家被大学生“占便宜”到崩溃引热议 7天无理由退货该取消吗?勿以恶小而为之|每日焦点
- 浙大创造出新物质:兼具硬度和弹性 真五边形战士
- 佛山一考生第一天走错考场:第二天赶不上公交 两次获救助 环球百事通
- 高考生出考场接受采访 同学跑来喊话:加强李信 环球热文
- MediaTek天玑开发者中心官网上线 天玑生态圈加速引领移动应用体验进化 世界报道
- 每日看点!notify party和consignee(外贸单据中CONSIGNEE和NOTIFY PARTY有什么区别)
- 海口一老人街边突然摔倒,两小伙上前将人扶起 焦点速看
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
详解驱动开发中内核PE结构VA与FOA转换|热资讯
摘要:本文将探索内核中解析PE文件的相关内容。
本文分享自华为云社区《驱动开发:内核PE结构VA与FOA转换》,作者: LyShark 。
本章将探索内核中解析PE文件的相关内容,PE文件中FOA与VA、RVA之间的转换也是很重要的,所谓的FOA是文件中的地址,VA则是内存装入后的虚拟地址,RVA是内存基址与当前地址的相对偏移,本章还是需要用到封装的KernelMapFile()映射函数,在映射后对其PE格式进行相应的解析,并实现转换函数。
首先先来演示一下内存VA地址与FOA地址互相转换的方式,通过使用WinHEX打开一个二进制文件,打开后我们只需要关注如下蓝色注释为映像建议装入基址,黄色注释为映像装入后的RVA偏移。
(相关资料图)
通过上方的截图结合PE文件结构图我们可得知0000158B为映像装入内存后的RVA偏移,紧随其后的00400000则是映像的建议装入基址,为什么是建议而不是绝对?别急后面慢来来解释。
通过上方的已知条件我们就可以计算出程序实际装入内存后的入口地址了,公式如下:
VA(实际装入地址) = ImageBase(基址) + RVA(偏移) => 00400000 + 0000158B = 0040158B
找到了程序的OEP以后,接着我们来判断一下这个0040158B属于那个节区,以.text节区为例,下图我们通过观察区段可知,第一处橙色位置00000B44 (节区尺寸),第二处紫色位置00001000 (节区RVA),第三处00000C00 (文件对齐尺寸),第四处00000400 (文件中的偏移),第五处60000020 (节区属性)。
得到了上方text节的相关数据,我们就可以判断程序的OEP到底落在了那个节区中,这里以.text节为例子,计算公式如下:
虚拟地址开始位置:节区基地址 + 节区RVA => 00400000 + 00001000 = 00401000虚拟地址结束位置:text节地址 + 节区尺寸 => 00401000 + 00000B44 = 00401B44
经过计算得知 .text 节所在区间(401000 - 401B44) 你的装入VA地址0040158B只要在区间里面就证明在本节区中,此处的VA地址是在401000 - 401B44区间内的,则说明它属于.text节。
经过上面的公式计算我们知道了程序的OEP位置是落在了.text节,此时你兴致勃勃的打开x64DBG想去验证一下公式是否计算正确不料,这地址根本不是400000开头啊,这是什么鬼?
上图中出现的这种情况就是关于随机基址的问题,在新版的VS编译器上存在一个选项是否要启用随机基址(默认启用),至于这个随机基址的作用,猜测可能是为了防止缓冲区溢出之类的烂七八糟的东西。
为了方便我们调试,我们需要手动干掉它,其对应到PE文件中的结构为 IMAGE_NT_HEADERS -> IMAGE_OPTIONAL_HEADER -> DllCharacteristics 相对于PE头的偏移为90字节,只需要修改这个标志即可,修改方式 x64:6081 改 2081 相对于 x86:4081 改 0081 以X86程序为例,修改后如下图所示。
经过上面对标志位的修改,程序再次载入就能够停在0040158B的位置,也就是程序的OEP,接下来我们将通过公式计算出该OEP对应到文件中的位置。
.text(节首地址) = ImageBase + 节区RVA => 00400000 + 00001000 = 00401000VA(虚拟地址) = ImageBase + RVA(偏移) => 00400000 + 0000158B = 0040158BRVA(相对偏移) = VA - (.text节首地址) => 0040158B - 00401000 = 58BFOA(文件偏移) = RVA + .text节对应到文件中的偏移 => 58B + 400 = 98B
经过公式的计算,我们找到了虚拟地址0040158B对应到文件中的位置是98B,通过WinHEX定位过去,即可看到OEP处的机器码指令了。
接着我们来计算一下.text节区的结束地址,通过文件的偏移加上文件对齐尺寸即可得到.text节的结束地址400+C00= 1000,那么我们主要就在文件偏移为(98B - 1000)在该区间中找空白的地方,此处我找到了在文件偏移为1000之前的位置有一段空白区域,如下图:
接着我么通过公式计算一下文件偏移为0xF43的位置,其对应到VA虚拟地址是多少,公式如下:
.text(节首地址) = ImageBase + 节区RVA => 00400000 + 00001000 = 00401000VPK(实际大小) = (text节首地址 - ImageBase) - 实际偏移 => 401000-400000-400 = C00VA(虚拟地址) = FOA(.text节) + ImageBase + VPK => F43+400000+C00 = 401B43
计算后直接X64DBG跳转过去,我们从00401B44的位置向下全部填充为90(nop),然后直接保存文件。
再次使用WinHEX查看文件偏移为0xF43的位置,会发现已经全部替换成了90指令,说明计算正确。
到此文件偏移与虚拟偏移的转换就结束了,那么这些功能该如何实现呢,接下来将以此实现这些转换细节。
FOA转换为VA:首先来实现将FOA地址转换为VA地址,这段代码实现起来很简单,如下所示,此处将dwFOA地址0x84EC00转换为对应内存的虚拟地址。
// 署名权// right to sign one"s name on a piece of work// PowerBy: LyShark// Email: me@lyshark.comNTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath){DbgPrint("hello lyshark.com \n");NTSTATUS status = STATUS_SUCCESS;HANDLE hFile = NULL;HANDLE hSection = NULL;PVOID pBaseAddress = NULL;UNICODE_STRING FileName = { 0 };// 初始化字符串RtlInitUnicodeString(&FileName, L"\\??\\C:\\Windows\\System32\\ntoskrnl.exe");// 内存映射文件status = KernelMapFile(FileName, &hFile, &hSection, &pBaseAddress);if (!NT_SUCCESS(status)){return 0;}// 获取PE头数据集PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBaseAddress;PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((PUCHAR)pDosHeader + pDosHeader->e_lfanew);PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHeaders);PIMAGE_FILE_HEADER pFileHeader = &pNtHeaders->FileHeader;DWORD64 dwFOA = 0x84EC00;DWORD64 ImageBase = pNtHeaders->OptionalHeader.ImageBase;DWORD NumberOfSectinsCount = pNtHeaders->FileHeader.NumberOfSections;DbgPrint("镜像基址 = %p | 节表数量 = %d \n", ImageBase, NumberOfSectinsCount);for (int each = 0; each < NumberOfSectinsCount; each++){DWORD64 PointerRawStart = pSection[each].PointerToRawData; // 文件偏移开始位置DWORD64 PointerRawEnds = pSection[each].PointerToRawData + pSection[each].SizeOfRawData; // 文件偏移结束位置// DbgPrint("文件开始偏移 = %p | 文件结束偏移 = %p \n", PointerRawStart, PointerRawEnds);if (dwFOA >= PointerRawStart && dwFOA <= PointerRawEnds){DWORD64 RVA = pSection[each].VirtualAddress + (dwFOA - pSection[each].PointerToRawData); // 计算出RVADWORD64 VA = RVA + pNtHeaders->OptionalHeader.ImageBase; // 计算出VADbgPrint("FOA偏移 [ %p ] --> 对应VA地址 [ %p ] \n", dwFOA, VA);}}ZwUnmapViewOfSection(NtCurrentProcess(), pBaseAddress);ZwClose(hSection);ZwClose(hFile);Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;}
运行效果如下所示,此处之所以出现两个结果是因为没有及时返回,一般我们取第一个结果就是最准确的;
VA转换为FOA:将VA内存地址转换为FOA文件偏移,代码与如上基本保持一致。
// 署名权// right to sign one"s name on a piece of work// PowerBy: LyShark// Email: me@lyshark.comNTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath){DbgPrint("hello lyshark.com \n");NTSTATUS status = STATUS_SUCCESS;HANDLE hFile = NULL;HANDLE hSection = NULL;PVOID pBaseAddress = NULL;UNICODE_STRING FileName = { 0 };// 初始化字符串RtlInitUnicodeString(&FileName, L"\\??\\C:\\Windows\\System32\\ntoskrnl.exe");// 内存映射文件status = KernelMapFile(FileName, &hFile, &hSection, &pBaseAddress);if (!NT_SUCCESS(status)){return 0;}// 获取PE头数据集PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBaseAddress;PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((PUCHAR)pDosHeader + pDosHeader->e_lfanew);PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHeaders);PIMAGE_FILE_HEADER pFileHeader = &pNtHeaders->FileHeader;DWORD64 dwVA = 0x00007FF6D3389200;DWORD64 ImageBase = pNtHeaders->OptionalHeader.ImageBase;DWORD NumberOfSectinsCount = pNtHeaders->FileHeader.NumberOfSections;DbgPrint("镜像基址 = %p | 节表数量 = %d \n", ImageBase, NumberOfSectinsCount);for (DWORD each = 0; each < NumberOfSectinsCount; each++){DWORD Section_Start = ImageBase + pSection[each].VirtualAddress; // 获取节的开始地址DWORD Section_Ends = ImageBase + pSection[each].VirtualAddress + pSection[each].Misc.VirtualSize; // 获取节的结束地址DbgPrint("Section开始地址 = %p | Section结束地址 = %p \n", Section_Start, Section_Ends);if (dwVA >= Section_Start && dwVA <= Section_Ends){DWORD RVA = dwVA - pNtHeaders->OptionalHeader.ImageBase; // 计算RVADWORD FOA = pSection[each].PointerToRawData + (RVA - pSection[each].VirtualAddress); // 计算FOADbgPrint("VA偏移 [ %p ] --> 对应FOA地址 [ %p ] \n", dwVA, FOA);}}ZwUnmapViewOfSection(NtCurrentProcess(), pBaseAddress);ZwClose(hSection);ZwClose(hFile);Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;}
运行效果如下所示,此处没有出现想要的结果是因为我们当前的VA内存地址并非实际装载地址,仅仅是PE磁盘中的地址,此处如果换成内存中的PE则可以提取出正确的结果;
RVA转换为FOA:将相对偏移地址转换为FOA文件偏移地址,此处仅仅只是多了一步pNtHeaders->OptionalHeader.ImageBase + dwRVARVA转换为VA的过程其转换结果与VA转FOA一致。
// 署名权// right to sign one"s name on a piece of work// PowerBy: LyShark// Email: me@lyshark.comNTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath){DbgPrint("hello lyshark.com \n");NTSTATUS status = STATUS_SUCCESS;HANDLE hFile = NULL;HANDLE hSection = NULL;PVOID pBaseAddress = NULL;UNICODE_STRING FileName = { 0 };// 初始化字符串RtlInitUnicodeString(&FileName, L"\\??\\C:\\Windows\\System32\\ntoskrnl.exe");// 内存映射文件status = KernelMapFile(FileName, &hFile, &hSection, &pBaseAddress);if (!NT_SUCCESS(status)){return 0;}// 获取PE头数据集PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBaseAddress;PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((PUCHAR)pDosHeader + pDosHeader->e_lfanew);PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHeaders);PIMAGE_FILE_HEADER pFileHeader = &pNtHeaders->FileHeader;DWORD64 dwRVA = 0x89200;DWORD64 ImageBase = pNtHeaders->OptionalHeader.ImageBase;DWORD NumberOfSectinsCount = pNtHeaders->FileHeader.NumberOfSections;DbgPrint("镜像基址 = %p | 节表数量 = %d \n", ImageBase, NumberOfSectinsCount);for (DWORD each = 0; each < NumberOfSectinsCount; each++){DWORD Section_Start = pSection[each].VirtualAddress; // 计算RVA开始位置DWORD Section_Ends = pSection[each].VirtualAddress + pSection[each].Misc.VirtualSize; // 计算RVA结束位置if (dwRVA >= Section_Start && dwRVA <= Section_Ends){DWORD VA = pNtHeaders->OptionalHeader.ImageBase + dwRVA; // 得到VA地址DWORD FOA = pSection[each].PointerToRawData + (dwRVA - pSection[each].VirtualAddress); // 得到FOADbgPrint("RVA偏移 [ %p ] --> 对应FOA地址 [ %p ] \n", dwRVA, FOA);}}ZwUnmapViewOfSection(NtCurrentProcess(), pBaseAddress);ZwClose(hSection);ZwClose(hFile);Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;}
运行效果如下所示;
点击关注,第一时间了解华为云新鲜技术~
关键词:
详解驱动开发中内核PE结构VA与FOA转换|热资讯
全球视点!MegEngine 动态执行引擎-Imperative Runtime 概述
当前聚焦:【新华500】新华500指数(989001)8日低开高走涨0.66%
广汽集团曾庆洪:汽车产业告别高增长黄金时代,淘汰赛加速进行 全球视讯
大爷将2台电动车焊一起自制代步车:觉得代步车太贵
小金毛冲进考场被无情请出 网友:忘带双证了?
突发!中国电信大面积崩溃:手机没信号、电话空号
显卡带来巨额利润 英伟达股价还能再涨30% 五大看涨理由…… 播资讯
今日精选:看似灯泡其实是个智能家居摄像机!萤石C8b 4G版图赏
天天微头条丨头部 UP 主入局,B 站带货时代来了?
理论+示例,详解GaussDB(DWS)资源管理 环球最新
C++ 引用
跟着源码学IM(十一):一套基于Netty的分布式高可用IM详细设计与实现(有源码)|当前快讯
观天下!MySQL百万级数据大分页查询优化的实现
矩形图的奇妙世界:揭开数据背后的故事 热点聚焦
中意悦享安康重疾险怎么样?保什么? 每日热讯
全球金融周期:趋势和影响——人民银行副行长、外汇局局长潘功胜在第十四届陆家嘴论坛上的主题演讲
弥勒岩在福清什么地方_弥勒岩
商家被大学生“占便宜”到崩溃引热议 7天无理由退货该取消吗?勿以恶小而为之|每日焦点
浙大创造出新物质:兼具硬度和弹性 真五边形战士
佛山一考生第一天走错考场:第二天赶不上公交 两次获救助 环球百事通
高考生出考场接受采访 同学跑来喊话:加强李信 环球热文
MediaTek天玑开发者中心官网上线 天玑生态圈加速引领移动应用体验进化 世界报道
每日看点!notify party和consignee(外贸单据中CONSIGNEE和NOTIFY PARTY有什么区别)
海口一老人街边突然摔倒,两小伙上前将人扶起 焦点速看
steam好友聊天闪退_steam好友功能激活
浙江省养老金调整方案及计算公式表 2022~2023年浙江省养老金调整方案细则最新消息(全文)
李云泽:坚决消除监管的空白和盲区 环球观热点
天天动态:以为走错 到了新考场发现这下真错了:女生闹大乌龙 幸运没耽误考试
不接受没用!欧美要把全球热门IP都改为黑人 塞尔达公主是黑人 太过分了?
百事通!618又要来了,江苏省消保委发布消费提示
岳阳县疾病预防控制局揭牌成立 焦点消息
深度学习应用篇-计算机视觉-目标检测[4]:综述、边界框bounding box、锚框(Anchor box)、交并比、非极大值抑制NMS、SoftNMS
Openjob:更强大、更智能的新一代分布式任务调度框架|世界热推荐
特斯拉被曝动员中国供应商出海 去墨西哥复制“上海工厂”|每日报道
官方重要提醒!网易暴雪游戏退款申请即将截止
全球新资讯:一个游泳池里到底有多少尿?
世界热点评!一本书卖4.5万 日本研究员拆解比亚迪海豹视频流出:竟有些热血
全球微头条丨燃油绝唱! 第八代高尔夫终于改款:首次搭载大尺寸屏幕
天天热门:一字千年,方正字库的守正与创新
MySQL索引的数据结构 环球快资讯
焦点!原生AJAX案例浏览器报错:Cross origin requests are only supported for protocol
全球头条:springboot~jgroups实现节点间的通讯
轻松实现物联网通信的利器:MQTT网关神器——FluxMQ 当前视点
win10配置Electron安装环境以及解决报错-消息
当前热文:青春的答卷
世界最新:当事博主否认被强制执行:特斯拉还想让平台封杀我 不是谁都给你面子
奶凶!沃尔沃史上最小SUV EX30发布!纯电续航480km 3.6秒破百
天天通讯!端午节假期火车票今日开售:调休放三天假 高速不免费
世界新动态:弯道强才是真的强!问界M5智驾版重庆山路实测:尽享丝滑
焦点快报!140W满功耗RTX 4060助力!618百亿补贴ROG魔霸7 Plus到手价仅8999元
天天时讯:郑外名师评卷·高考数学:反刷题、反套路,重视基础,稳中求新
龙湾开展“红色星期天”活动 让“一老一小”共享红色温暖 环球焦点
世界微头条丨太卷了,史上最简单的监控系统 catpaw 简介
小车PID巡线调节 全球报资讯
易基因|一种全新的检测DNA羟甲基化的技术:ACE-Seq 环球时快讯
JPA单表存储List与模糊查询
医保缴费多少年才可以终身享受待遇?多少钱一年?
欧盟将强制禁用华为5G设备 热点在线
性价比口碑双冠王!魅族20 PRO成618四千档性能神机 天天热资讯
雾霾笼罩纽约 自由女神像被“吞没” :美国大片地区昏黄烟雾 宛如末日降临-世界热头条
世界头条:高考时没有一个孔子是饿着的:学子争相给先贤送吃的 期盼金榜题名
女子开门杀致骑手摔倒被罐车卷入车底:第一反应竟是观察车门|天天速递
Adata 展示其 1600W PSU 可以为四个 450W RTX 4090 供电
java~如何使用无符号整型 看热讯
文字效果 用背景渐变实现 波浪背景文字
P1585 魔法阵 题解
关注2023年河南高考丨免费午餐温暖高考学子
西安李姐茶叶蛋的家常做法?
有人在麦田插钢筋损坏收割机:钢筋还特意用麦子包裹 天天报道
帅不过3秒!RTX 4060游戏本挑战全景光追惨败 天天实时
黑龙江黑河村庄遭龙卷风袭击:多处房屋损毁|焦点关注
安卓阵营早已实现:iOS 17相机终于引入“水平”辅助线_天天报资讯
天天看点:买显卡“送”橘猫!COLORFIRE RTX 4060 Ti橘影橙8GB 评测:比公版强2%
当前时讯:文档在线预览(四)将word、txt、ppt、excel、图片转成pdf来实现在线预览
热讯:工会代表候选人初步人选推荐情况的报告_人选和候选人的区别是什么
组图|2023年海南陵水黎安国际教育创新试验区知识产权沙龙活动举行
多家饭店因在凉皮内放黄瓜丝被罚 网友吵翻:专家科普为大家好
第27次参加!高考钉子户梁实愁眉苦脸出考场 直言考得不好_世界今日报
天天实时:Epic祝福高考学子被指配图不佳 随后换成《原神》截图
天天信息:灵商的组成中包括(灵商)
吉视传媒:公司目前没有发展和推动有esim卡业务 今日精选
全球短讯!青海省邮政管理局联合相关部门调研“客货邮”融合发展情况
世界即时看!福达合金:截至本公告披露日 公司及其控股子公司担保余额为人民币约7.86亿元
职业发展战术设计:构建可持续积累的职业优势 每日关注
微控制器实时操作系统实践3任务信令和通信机制
癫痫一年发作一次严重吗
什么海鱼内脏比较好吃?
魔域私服有合宝宝挂吗_457833415@ com 求个 有的给个 谢谢啦|今日视点
全球滚动:卡霍夫卡水电站大坝遭袭 扎波罗热地方官员:核电站情况稳定
万亿美元发债潮将至 美国金融体系或酝酿流动性风险 环球新动态
新兴产业加速崛起 海洋经济破浪前行
江苏黄沙港特大桥顺利合龙 预计6月底完工
高温范围扩大 这些地区的高考考生和家长需注意_当前资讯
雷雨大风+冰雹+龙卷!黑龙江省发布龙卷预警 焦点短讯
临川区气象台发布雷电黄色预警信号【III级/较重】【2023-06-07】 每日速讯
世界看热讯:不回巴萨!曝梅西已决定加盟美国球队迈阿密国际
Mac游戏看齐Win系统 苹果新工具可快速移植游戏
2023高考来临 大学生考点摆摊卖9.85与21.1元花束:给学弟学妹加油
暗黑满级号死于掉线