ARM64的KASLR分析

基本概念

加载地址:内核解压到物理内存上的物理起始地址

链接地址:内核编译链接后的虚拟起始地址

我们的这篇 文章,介绍了加载地址可以是自动的,也可以是固定的;一般都是物理内存的起始地址 + 一个偏移 ;这个是编译时就决定了链接地址跟加载地址的映射

我们的这篇 文章,介绍了kimage_voffset,就是运行时的内核的虚拟地址跟物理地址映射的真实偏移,不管经过与否kaslr

KASLR, kernel address space layout randomization,内核地址空间布局随机化。KASLR技术可以让kernel image的编译链接时确定的加载地址,在真正解压加载到物理内存时产生一个偏移,然后给这个新的加载地址映射一个新的虚拟地址

流程

stext作为镜像的开始的地方

#define KERNEL_START    _text
#define __PHYS_OFFSET   (KERNEL_START - TEXT_OFFSET)
ENTRY(stext)bl      preserve_boot_argsbl      el2_setup                       // Drop to EL1, w0=cpu_boot_modeadrp    x23, __PHYS_OFFSETand     x23, x23, MIN_KIMG_ALIGN - 1    // KASLR offset, defaults to 0bl      set_cpu_boot_mode_flagbl      __create_page_tables/** The following calls CPU setup code, see arch/arm64/mm/proc.S for* details.* On return, the CPU will be ready for the MMU to be turned on and* the TCR will have been set.*/bl      __cpu_setup                     // initialise processorb       __primary_switch
ENDPROC(stext)

__create_page_tables

因为不知道有没kaslr,先通过__create_page_tables创建加载地址跟链接地址的映射

__create_page_tables:mov     x28, lr/** Invalidate the init page tables to avoid potential dirty cache lines* being evicted. Other page tables are allocated in rodata as part of* the kernel image, and thus are clean to the PoC per the boot* protocol.*/adrp    x0, init_pg_diradrp    x1, init_pg_endsub     x1, x1, x0bl      __inval_dcache_area/** Clear the init page tables.*/adrp    x0, init_pg_diradrp    x1, init_pg_endsub     x1, x1, x0
1:      stp     xzr, xzr, [x0], #16stp     xzr, xzr, [x0], #16stp     xzr, xzr, [x0], #16stp     xzr, xzr, [x0], #16subs    x1, x1, #64b.ne    1bmov     x7, SWAPPER_MM_MMUFLAGS/** Create the identity mapping.*/adrp    x0, idmap_pg_diradrp    x3, __idmap_text_start          // __pa(__idmap_text_start)#ifdef CONFIG_ARM64_VA_BITS_52mrs_s   x6, SYS_ID_AA64MMFR2_EL1and     x6, x6, #(0xf << ID_AA64MMFR2_LVA_SHIFT)mov     x5, #52cbnz    x6, 1f
#endifmov     x5, #VA_BITS_MIN
1:adr_l   x6, vabits_actualstr     x5, [x6]dmb     sydc      ivac, x6                // Invalidate potentially stale cache line/** VA_BITS may be too small to allow for an ID mapping to be created* that covers system RAM if that is located sufficiently high in the* physical address space. So for the ID map, use an extended virtual* range in that case, and configure an additional translation level* if needed.** Calculate the maximum allowed value for TCR_EL1.T0SZ so that the* entire ID map region can be mapped. As T0SZ == (64 - #bits used),* this number conveniently equals the number of leading zeroes in* the physical address of __idmap_text_end.*/adrp    x5, __idmap_text_endclz     x5, x5cmp     x5, TCR_T0SZ(VA_BITS_MIN) // default T0SZ small enough?b.ge    1f                      // .. then skip VA range extensionadr_l   x6, idmap_t0szstr     x5, [x6]dmb     sydc      ivac, x6                // Invalidate potentially stale cache line#if (VA_BITS < 48)
#define EXTRA_SHIFT     (PGDIR_SHIFT + PAGE_SHIFT - 3)
#define EXTRA_PTRS      (1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT))/** If VA_BITS < 48, we have to configure an additional table level.* First, we have to verify our assumption that the current value of* VA_BITS was chosen such that all translation levels are fully* utilised, and that lowering T0SZ will always result in an additional* translation level to be configured.*/
#if VA_BITS != EXTRA_SHIFT
#error "Mismatch between VA_BITS and page size/number of translation levels"
#endifmov     x4, EXTRA_PTRScreate_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
#else/** If VA_BITS == 48, we don't have to configure an additional* translation level, but the top-level table has more entries.*/mov     x4, #1 << (PHYS_MASK_SHIFT - PGDIR_SHIFT)str_l   x4, idmap_ptrs_per_pgd, x5
#endif
1:ldr_l   x4, idmap_ptrs_per_pgdmov     x5, x3                          // __pa(__idmap_text_start)adr_l   x6, __idmap_text_end            // __pa(__idmap_text_end)map_memory x0, x1, x3, x6, x7, x3, x4, x10, x11, x12, x13, x14/** Map the kernel image (starting with PHYS_OFFSET).*/adrp    x0, init_pg_dirmov_q   x5, KIMAGE_VADDR + TEXT_OFFSET  // compile time __va(_text)add     x5, x5, x23                     // add KASLR displacementmov     x4, PTRS_PER_PGDadrp    x6, _end                        // runtime __pa(_end)adrp    x3, _text                       // runtime __pa(_text)sub     x6, x6, x3                      // _end - _textadd     x6, x6, x5                      // runtime __va(_end)map_memory x0, x1, x5, x6, x7, x3, x4, x10, x11, x12, x13, x14/** Since the page tables have been populated with non-cacheable* accesses (MMU disabled), invalidate those tables again to* remove any speculatively loaded cache lines.*/dmb     syadrp    x0, idmap_pg_diradrp    x1, idmap_pg_endsub     x1, x1, x0bl      __inval_dcache_areaadrp    x0, init_pg_diradrp    x1, init_pg_endsub     x1, x1, x0bl      __inval_dcache_arearet     x28
ENDPROC(__create_page_tables)

__primary_switch

1.如果开启了CONFIG_RANDOMIZE_BASE(kaslr),先通过第一次的__primary_switched里面的kaslr_early_init,解析出KASLR offset并存储到X23寄存器

2.然后通过__create_page_tables重新映射内核镜像,也就是给物理地址分配虚拟地址

3.分配完的地址跟编译时的链接地址不一样了,所以需要重定位内核镜像---对符号地址进行重定位,校正内核代码的符号寻址,以此确保内核代码的正常执行

4.再执行一次__primary_switched去更新kimage_voffset

__primary_switch:
#ifdef CONFIG_RANDOMIZE_BASEmov     x19, x0                         // preserve new SCTLR_EL1 valuemrs     x20, sctlr_el1                  // preserve old SCTLR_EL1 value
#endifadrp    x1, init_pg_dirbl      __enable_mmu
#ifdef CONFIG_RELOCATABLE
#ifdef CONFIG_RELRmov     x24, #0                         // no RELR displacement yet
#endifbl      __relocate_kernel
#ifdef CONFIG_RANDOMIZE_BASEldr     x8, =__primary_switchedadrp    x0, __PHYS_OFFSETblr     x8/** If we return here, we have a KASLR displacement in x23 which we need* to take into account by discarding the current kernel mapping and* creating a new one.*/pre_disable_mmu_workaroundmsr     sctlr_el1, x20                  // disable the MMUisbbl      __create_page_tables            // recreate kernel mappingtlbi    vmalle1                         // Remove any stale TLB entriesdsb     nshisbmsr     sctlr_el1, x19                  // re-enable the MMUisbic      iallu                           // flush instructions fetcheddsb     nsh                             // via old mappingisbbl      __relocate_kernel
#endif
#endifldr     x8, =__primary_switchedadrp    x0, __PHYS_OFFSETbr      x8
ENDPROC(__primary_switch)

__primary_switched

上述操作执行完_text变了,kimage_vaddr(_text - TEXT_OFFSET)也就跟着变了,kimage_voffset也就成了虚拟地址转物理地址函数的实际偏移了,就可以通过start_kernel进内核的C语言部分了

__primary_switched:adrp    x4, init_thread_unionadd     sp, x4, #THREAD_SIZEadr_l   x5, init_taskmsr     sp_el0, x5                      // Save thread_infoadr_l   x8, vectors                     // load VBAR_EL1 with virtualmsr     vbar_el1, x8                    // vector table addressisbstp     xzr, x30, [sp, #-16]!mov     x29, sp#ifdef CONFIG_SHADOW_CALL_STACKadr_l   x18, init_shadow_call_stack     // Set shadow call stack
#endifstr_l   x21, __fdt_pointer, x5          // Save FDT pointerldr_l   x4, kimage_vaddr                // Save the offset betweensub     x4, x4, x0                      // the kernel virtual andstr_l   x4, kimage_voffset, x5          // physical mappings// Clear BSSadr_l   x0, __bss_startmov     x1, xzradr_l   x2, __bss_stopsub     x2, x2, x0bl      __pi_memsetdsb     ishst                           // Make zero page visible to PTW#ifdef CONFIG_KASANbl      kasan_early_init
#endif
#ifdef CONFIG_RANDOMIZE_BASEtst     x23, ~(MIN_KIMG_ALIGN - 1)      // already running randomized?b.ne    0fmov     x0, x21                         // pass FDT address in x0bl      kaslr_early_init                // parse FDT for KASLR optionscbz     x0, 0f                          // KASLR disabled? just proceedorr     x23, x23, x0                    // record KASLR offsetldp     x29, x30, [sp], #16             // we must enable KASLR, returnret                                     // to __primary_switch()
0:
#endifadd     sp, sp, #16mov     x29, #0mov     x30, #0b       start_kernel
ENDPROC(__primary_switched)/** end early head section, begin head code that is also used for* hotplug and needs to have the same protections as the text region*/.section ".idmap.text","awx"ENTRY(kimage_vaddr).quad           _text - TEXT_OFFSET
EXPORT_SYMBOL(kimage_vaddr)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/17841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pillow学习3

Pillow库中&#xff0c;图像的模式代表了图像的颜色空间。以下是一些常见的图像模式及其含义&#xff1a; L&#xff08;灰度图&#xff09;&#xff1a;L模式表示图像是灰度图像&#xff0c;每个像素用8位表示&#xff08;范围为0-255&#xff09;&#xff0c;0表示黑色&#…

在flutter initState 方法,触发 setState导致循环执行

在Flutter中&#xff0c;如果你在initState中调用了一个方法&#xff0c;并且这个方法可能导致状态更新&#xff0c;这可能会引起无限循环&#xff0c;因为每次状态更新都会再次调用initState。 为了避免这种情况&#xff0c;你应该检查调用的方法是否会导致状态更新&#xff…

图算法新书发布会圆满成功,大咖现场都讲了啥?

5月24日&#xff0c;嬴图与机工社携手举办的“《图算法&#xff1a;行业应用与实践》新书发布会”圆满成功。 现场直播在线观众达4000人/次左右&#xff0c;点赞数量超7000&#xff0c;直至发布会尾声&#xff0c;观看人数仍在持续增长。 通过观众们的反馈&#xff0c;我们也对…

Matplotlib 实践指南:图形样式、风格与标记探索

目录 前言 第一点&#xff1a;导入模块 第二点&#xff1a;创建二维图 第三点&#xff1a;创建统计图 总结 前言 Matplotlib 是一个强大的数据可视化库&#xff0c;可用于创建各种类型的图形。在本文中&#xff0c;我们将研究如何在 Matplotlib 中设置图形的颜色、风格和标记…

【LeetCode算法】第88题:合并两个有序数组

目录 一、题目描述 二、初次解答 三、官方解法 四、总结 一、题目描述 二、初次解答 1. 思路&#xff1a;首次想到的解法&#xff1a;定义一个mn长度的辅助数组&#xff0c;从头遍历这两个数组&#xff0c;谁小就放进辅助数组中并且对应往后走&#xff0c;最后使用memcpy函…

巧用java8的stream流的.collect(Collectors.toMap(arg1,arg2))

最近公司接手了一个低代码二次开发平台的需求&#xff0c;需要连接多张表的数据然后展示到界面上。 按照java的sql思路&#xff0c;我们直接通过left join去关联表就行了&#xff0c;但是该低代码平台有对sql连表查询有限制&#xff0c;就是有些表它是存在一个domainKey的&…

HotSpot虚拟机的几个实现细节

文章目录 STW安全点安全区域记忆集与卡表读写屏障 STW 收集器在根节点枚举这步都是必须要暂停用户线程的&#xff08; STW &#xff09;&#xff0c;如果不这样的话在根节点枚举的过程中由于引用关系在不断变化&#xff0c;分析的结果就不准确 安全点 收集器在工作的时候某些…

切勿安装这五款流氓软件,你中招了没

流氓软件&#xff0c;又称为恶意软件&#xff0c;是一类设计用来损害用户设备、窃取信息或干扰正常使用的程序。以下是五款臭名昭著的流氓软件介绍&#xff0c;提醒切勿安装&#xff0c;只能说一个比一个毒&#xff0c;你中招了没 可以去去虚拟机试试谁的毒更强一些&#xff0…

高工咨询:《2024中国人形机器人产业发展蓝皮书》

高工咨询所发布的《2024中国人形机器人产业发展蓝皮书》全面梳理了人形机器人产业的发展现状、政策环境、资本市场、技术发展、市场前景以及面临的机遇与挑战等情况。 人形机器人是当今世界科技领域最具潜力和前景的产业之一。随着科技的不断进步和人 工智能技术的快速发展&…

基于jeecgboot-vue3的Flowable增加表单功能(二)

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 接上一节 6、增加一个types.ts 类型 export interface FormForm {id: number | string | undefined;formName: string;formContent?: string;remark: string; } 7、api增加一个getForm…

Github Page 部署失败

添加 .gitmodules 文件 [submodule "themes/ayer"]path themes/ayerurl https://github.com/Shen-Yu/hexo-theme-ayer.git 添加 .nojekyll 文件

React Fiber

React引入Fiber前后的区别&#xff1a; 渲染流程的控制&#xff1a; 之前&#xff1a;在Fiber之前&#xff0c;React的渲染过程是一个相对线性的深度优先遍历过程&#xff0c;从根节点开始遍历整个组件树&#xff0c;这个过程一旦开始就无法中断&#xff0c;直到完成。如果遇到…

滚珠花键在工业自动化领域中有什么优势?

滚珠花键是工业自动化设备中重要的传动系统之一&#xff0c;不仅在工业自动化系统中有着广泛的运用&#xff0c;还在机械制造领域、航空航天领域、工业汽车领域、工业机器人、高速铁路、新能源领域 等都得到广泛应用。由于具有高精度、高承载、耐磨损、传递扭矩大等特点&#x…

android 关于自定义View在特殊情况下触发setPressed方法(View源码解析)

文章目录 前言一、为什么样式会变&#xff1f;二、调试发现原因并解决1.找到原因2.解决 总结 前言 最近在负责一些UI相关的工作,测试给到一个UI的bug,说是搜索框在点击的时候,旁边的’‘X’变成按压的效果了,我转手就把bug转给负责公控的同事了,因为这个搜索框是公控同事提供的…

Mysql常用操作DDL数据库、表操作:

SQl DDl-数据库操作 查询 查询所有数据库 show databases; 查询当前数据库 select database(); 创建 create database [if not exists] 数据库名 [default charset 字符集] [collate 排序规则]; 删除 drop database[if exists] 数据库名; 使用 use 数据库名;…

K8s集群中的Pod调度约束亲和性与反亲和性

前言 在 K8s 集群管理中&#xff0c;Pod 的调度约束——亲和性&#xff08;Affinity&#xff09;与反亲和性&#xff08;Anti-Affinity&#xff09;这两种机制允许管理员精细控制 Pod 在集群内的分布方式&#xff0c;以适应多样化的业务需求和运维策略。本篇将介绍 K8s 集群中…

运维开发详解:现代IT环境的核心角色

随着信息技术的快速发展和互联网应用的广泛普及&#xff0c;运维开发&#xff08;DevOps&#xff09;在现代IT环境中扮演着越来越重要的角色。本文将详细探讨运维开发的概念、历史背景、关键实践、工具和未来趋势&#xff0c;旨在为读者提供全面的理解。 什么是运维开发&#…

labview类编程

1.父类的功能是通用功能&#xff0c;所有子类都含有父类的功能&#xff0c;重写会自动执行一次父类的功能。 2.每个子类都用了父类的注册vi&#xff0c;所以在调用的时候&#xff0c;出来的就是子类注册的vi&#xff0c;也就是window.vi。 3.假如要设计一个父类的vi,首先是保存…

手持高速暴力风扇方案32位单片机

RAMSUN一款低成本的暴力无刷风扇方案&#xff0c;集成无刷电机驱动、电池低压保护等功能的同时&#xff0c;保持较低的待机功耗。 手持高速暴力风扇主控芯片MM32SPIN080C高性能的单电机控制 SOC 产品,集成了运动控制所需的专用模拟外设。包括 12 位高精度 ADC、2 路模拟比较器…

Mac 系统 clion 使用 getline 无法读取文件内容

不知道是 mac 的问题还是 clion 的问题&#xff0c;如下面代码 #include <iostream> #include <fstream>using namespace std;int main() {string file_name "1.txt";std::ifstream file(file_name);if (file.is_open()) {std::string line;while (std…