Reverse engineering and exploiting Samsung's TrustZone
三星trustzone的逆向工程和利用
原文链接:1a2K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0k6h3c8A6N6h3#2Q4x3X3g2U0L8$3#2Q4x3V1k6@1j5i4y4*7K9%4y4W2j5#2)9J5c8Y4g2F1j5X3!0^5i4K6u0V1P5h3!0#2M7W2)9J5k6s2m8Z5L8$3&6W2i4K6u0V1M7r3q4J5N6q4)9J5k6r3W2Q4x3X3b7K6x3K6q4T1j5X3j5@1y4r3x3K6x3r3x3`.
(注:原文链接需要在VPN条件下才能浏览)
翻译转自安全客~7dfK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2S2L8Y4q4#2j5h3&6C8k6g2)9J5k6h3y4G2L8g2)9J5c8Y4m8G2M7%4c8Q4x3V1k6A6k6q4)9J5c8U0V1$3y4K6x3H3
以三星为例,如何对TrustZone进行逆向工程和漏洞利用(上篇)
译文声明 本文是翻译文章,文章原作者Daniel Komaromy,文章来源:medium.com
一、前言 本文主要讲解了如何对三星的TrustZone进行逆向工程和漏洞利用,受字数所限,将会分为上下两篇。在上篇中,主要涵盖了关于架构的基础知识。尽管这些基础知识都来源于公开的信息,并没有不为人知的内容,但它们却分布在各种出版物上,非常零碎,所以我想将其整合成完整且连贯的内容。本篇文章部分技术细节来源于Trustonic和三星的官方文档,部分来源于开源软件,还有一部分来源于此前研究者所公开的研究成果。 在本系列的后面,我还对逆向工程的成果进行了总结,并详细展现我所发现的漏洞。
二、简介 目前,已经有很多关于TrustZone的研究。在去年以前,大家主要侧重于对高通和华为产品的研究工作。此前这些关于可信执行环境(TEE)的研究都有一个共同的主题,就是其单点失效的特点(Single-point-of-failure Nature)。在这些可信执行环境中,普遍缺乏对特权的分隔,这也就意味着某一个漏洞会直接导致整个系统的沦陷,甚至是反复沦陷。 下面8篇漏洞详情,就是反复沦陷最好的证明,大家可以参考阅读:d2fK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2T1L8r3q4U0K9$3S2S2N6q4)9J5k6h3y4G2L8g2)9J5c8X3c8G2j5%4y4Q4x3V1k6#2M7#2)9J5k6o6p5@1i4K6u0r3L8h3q4@1k6i4u0A6j5h3I4K6i4K6u0r3N6i4y4Q4x3X3b7I4y4q4)9J5k6q4u0G2M7$3g2F1j5X3g2J5k6#2)9J5k6q4u0W2k6X3I4W2j5%4c8A6L8$3&6K6i4K6u0V1L8$3&6Q4x3X3c8f1M7Y4g2K6N6r3W2F1k6#2)9J5k6q4c8J5N6i4y4@1h3X3!0F1k6g2)9J5k6i4m8V1k6R3`.`. a87K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3u0A6N6s2y4Q4x3X3c8H3L8r3g2S2M7$3g2Q4x3X3g2T1L8r3!0Y4M7%4m8G2N6q4)9J5k6h3S2#2i4K6u0r3x3U0l9I4y4g2)9J5c8U0l9^5i4K6u0r3k6Y4g2D9L8q4)9J5k6s2c8J5N6i4y4@1P5X3!0F1k6g2)9J5k6r3g2^5M7r3I4G2K9i4c8Q4x3X3c8X3L8%4u0Q4x3X3c8E0M7$3@1^5z5e0M7@1i4K6u0W2K9s2c8E0L8l9`.`. c81K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2T1L8r3q4U0K9$3S2S2N6q4)9J5k6h3y4G2L8g2)9J5c8X3c8G2j5%4y4Q4x3V1k6#2M7#2)9J5k6o6p5#2i4K6u0r3L8h3q4@1k6i4u0A6j5h3I4K6i4K6u0r3N6i4y4Q4x3X3b7I4y4g2)9J5k6q4y4Z5k6h3&6Q4x3X3c8m8N6s2c8S2j5$3E0A6L8X3N6Q4x3X3c8k6L8%4g2J5i4K6u0V1g2s2u0#2M7%4c8W2k6q4)9J5k6p5y4G2M7X3g2Q4x3X3c8q4P5s2m8D9L8$3W2@1K9h3&6Y4i4K6u0V1g2s2u0#2M7%4c8*7L8$3&6W2i4K6u0V1e0$3&6Q4x3X3c8m8L8X3c8J5L8$3W2V1i4K6u0V1N6%4m8Q4x3X3g2H3k6r3j5`. f17K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3y4K6k6h3y4Q4x3X3g2B7M7q4)9J5c8Y4m8K6K9U0p5@1i4K6u0r3f1q4y4v1x3U0l9I4y4q4)9#2k6V1A6G2M7$3S2Q4y4h3k6b7j5h3y4e0k6h3x3J5x3o6p5@1i4K6u0V1N6U0q4Q4x3X3g2H3k6r3j5`. eb9K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3u0A6N6s2y4Q4x3X3c8H3L8r3g2S2M7$3g2Q4x3X3g2T1L8r3!0Y4M7%4m8G2N6q4)9J5k6h3S2#2i4K6u0r3x3U0l9I4y4W2)9J5c8U0l9#2i4K6u0r3M7i4y4W2k6g2)9J5k6s2m8J5K9i4k6A6L8r3g2Y4k6g2)9J5k6r3g2K6j5$3q4D9j5i4c8A6L8$3&6Q4x3X3c8$3N6h3I4F1k6i4u0S2j5X3W2D9K9i4c8&6i4K6u0W2K9s2c8E0L8l9`.`. c3aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2K6L8r3W2V1k6i4y4Z5j5i4u0W2i4K6u0W2L8X3g2@1i4K6u0r3c8$3g2W2K9#2m8%4L8V1E0W2k6h3&6Q4x3V1k6F1K9h3y4C8i4K6u0V1M7%4c8W2M7r3S2W2L8Y4y4Z5L8%4N6Q4x3X3c8V1L8$3g2K6i4K6u0V1M7$3!0E0k6h3!0F1k6g2)9J5k6s2g2F1L8r3!0U0K9#2)9J5k6s2W2G2N6i4u0Q4x3X3c8H3K9r3!0F1k6g2)9J5k6s2N6A6N6r3S2Q4x3X3c8F1L8%4y4W2 f3cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0K9h3y4J5L8%4y4G2k6Y4c8J5L8X3c8Q4x3X3g2U0L8#2)9J5k6h3W2D9i4K6u0r3f1s2u0W2M7%4y4Q4x3U0f1J5x3p5E0A6N6q4)9J5c8V1u0D9N6h3g2t1j5i4c8Q4x3U0f1J5x3p5W2x3i4K6t1#2x3U0m8p5k6h3y4C8M7#2)9J5c8V1N6S2L8p5u0W2L8X3W2S2L8h3W2F1K9g2)9J5k6i4m8V1k6R3`.`. ef6K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4c8Z5k6i4u0G2L8%4c8Q4x3X3g2F1K9h3&6B7j5g2)9J5c8X3c8A6M7$3y4D9L8%4y4#2M7X3g2K6i4K6u0r3g2q4u0g2f1#2c8z5e0@1&6q4i4K6g2X3x3g2)9J5k6e0m8Q4x3X3b7I4x3e0t1^5x3U0l9I4y4g2)9J5k6i4m8V1k6R3`.`. 然而,三星所使用的可信执行环境则有所不同。三星的环境是由Trustonic开发,Trustonic是一个专注于研究可信操作系统的公司,他们对可信执行环境解决方案的研发已经进行了15年之久。尽管在去年,Trustonic已经将他们的TEE OS更名为Kinibi,但我还是更习惯使用“T-Base”作为可信执行环境的名称。同样,此前Trustonic公司曾使用过MobiCore和Giesecke&Devrient这两个名称,尽管如今已经更名,但还是有一些地方会使用旧名称,请各位读者注意这一点。 最近,我在Ekoparty安全大会上就这一主题发表了演讲,我的演讲主要聚焦于如何对T-base微内核的逆向工程,以及T-Base的内部工作原理,并没有侧重于讲解Trustlets提供的实际功能和攻击面。这里的Trustlets是指在可信执行环境中运行的“可信应用程序”,基本上都是安全的操作系统中的用户空间进程。 我演讲的视频请参见:3b1K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2&6L8%4g2@1N6h3u0W2i4K6u0W2j5$3!0E0i4K6u0r3N6$3q4@1j5$3S2Q4x3@1k6$3i4K6y4p5e0o6u0y4L8K6S2i4j5$3#2E0h3X3!0Q4c8e0y4Q4z5o6m8Q4z5o6t1`. 我演讲的PPT请参见:51bK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6H3N6i4m8H3P5h3E0A6N6s2c8W2L8W2)9J5c8Y4c8T1j5i4y4W2i4@1f1K6i4K6R3H3i4K6R3J5 在我发表演讲的时候,三星还没有完成全部漏洞的修复工作,这也是为什么我会将演讲的重点放在逆向工程的原因之一。终于,他们已经在2018年1月的安全通告中,完成了最后一个漏洞的修复。终于,我们可以放心地讨论这些漏洞,我也要感谢大家的耐心等待。 根据我的经验,如果你发现某个架构设计得很差,那么随之而来的很可能就是一些重大的漏洞,特别是在嵌入式领域。
三、三星的KNOX和T-Base 由于我的研究都是基于三星的环境下完成的,那么我要解决的第一个问题,就是可信执行环境如何与三星的KNOX安全架构结合在一起。这一点非常重要,因为在早期版本的TrustZone中,它几乎只用于进行数字版权管理(DRM),所以从终端用户的角度来看,对其进行攻击的意义并不是太大。而现在,时代已经改变。 针对TrustZone技术,三星公司已经发布了非常多的文档。其中,有两篇文档已经详细说明了其所具有的功能,我在这里就不再赘述,大家可以参考阅读:e40K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3c8W2N6X3g2D9L8%4m8W2M7W2)9J5k6i4y4S2L8i4y4#2L8X3N6Q4x3X3g2U0L8$3#2Q4x3V1k6@1k6h3y4Z5i4K6u0V1K9h3&6K6K9h3N6Z5N6s2y4Q4x3V1k6C8L8X3!0^5i4K6u0r3M7r3I4S2N6r3k6G2M7X3#2Q4x3X3c8K6k6h3y4#2M7X3W2@1P5b7`.`. ee8K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3c8W2N6X3g2D9L8%4m8W2M7W2)9J5k6i4y4S2L8i4y4#2L8X3N6Q4x3X3g2U0L8$3#2Q4x3V1k6@1k6h3y4Z5i4K6u0V1K9h3&6K6K9h3N6Z5N6s2y4Q4x3V1k6H3j5i4W2Q4x3V1k6V1k6i4k6A6j5$3g2Q4x3X3c8K6K9h3c8W2i4K6u0V1M7$3g2U0N6i4u0A6N6s2V1`. 可信执行环境主要有下面三种用途:
将安全敏感功能移入可信执行环境。这样一来,即使安卓环境受到了威胁,也不会对可信执行环境产生影响。例如:KeyStore证书、数字版权管理、证书管理、可信PIN、可信UI、移动设备管理远程认证。
可信执行环境会对安卓系统中的功能进行监管,以缓解对Trustlets的漏洞利用尝试。例如:TIMA任意内核模块认证绕过、基于Trustlets的Kill-Switch勒索病毒。
仅允许从可信执行环境访问硬件设备,从而缓解针对硬件的攻击。例如:指纹传感器、用于非接触式支付的磁信号安全传输技术(MST)等。 上述的所有内容,都有一个共同的特点:每一个功能都是由一个(或多个)Trustlet实现。这就充分说明,如果要对实际功能方面进行研究,我们应该关注Trustlet。但如果我们想要了解这些Trustlet的安全性(例如:在安全内核和不安全内核之间,它们是如何相互隔离的),我们就需要深入了解T-Base。 在这里,我想要说明的是,尽管本文中涉及一些Trustlet的实际功能,但更多是用于向大家展现这些漏洞的存在。
四、T-Base的结构 如果你想阅读厂商关于T-Base的介绍(更侧重于产品营销目的),请参考:554K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2@1M7Y4g2K6N6r3!0F1K9h3y4Q4x3X3g2U0L8$3#2Q4x3V1k6K6L8$3I4#2N6r3W2G2L8Y4y4Q4x3V1k6@1M7Y4g2K6N6r3!0F1K9h3y4Q4x3X3c8K6k6h3y4#2M7X3g2V1i4K6u0V1M7r3I4S2N6r3k6G2M7X3#2K6i4K6u0V1N6s2y4H3i4K6u0r3i4@1f1K6i4K6R3H3i4K6R3J5 在最一开始,我们可以轻而易举地通过各种资料来熟知T-Base的结构——既有抽象层面的图示,又有大量的可用信息,同时还有三星和Trustonic共同公开的源代码可以参考。 这一切的核心,是安卓进程(应用程序)通过世界共享内存(World Shared Memory)与Trustlet通信。剩下的只有安卓、Linux内核和T-Base内核所提供的抽象层与安全边界层。 我们从T-Base架构的一张经典图示开始,来了解T-Base的结构。
4.1 ATF:ARM可信固件 首先,我们需要在硬件层面上,连接安全的世界(与不安全的世界。这一点是通过ARM上的SMC指令(Secure Monitor Call)来实现的,它会将执行过程从安全世界切换到不安全世界,就像是SVC将执行过程从EL0切换到EL1一样。但是,我们并没有真正地使用这样的指令跳转到一个安全世界EL1中的Handler,而是执行跳转到所谓的监视模式(Monitor Mode,ARM的EL3)之中。就像是一个代理,其目标是将安全世界与不安全世界之间的SMC组织起来。在Trustonic中,它并不是T-Base的一部分,而是单独实现的。关于ARM EL的更多信息,请参考:d1bK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3W2F1k6X3!0U0k6h3&6@1k6i4u0Q4x3X3g2S2M7X3#2Q4x3X3g2U0L8$3#2Q4x3V1k6Z5k6h3I4H3i4K6u0r3K9h3&6V1k6i4S2Q4x3X3g2B7M7%4m8Q4x3@1k6@1L8%4m8A6j5#2)9K6c8q4)9J5c8X3y4G2L8g2)9J5k6h3q4J5L8g2)9J5k6h3c8G2j5#2)9J5k6h3c8V1K9e0l9@1z5o6S2V1i4K6u0r3b7@1S2p5d9p5A6u0d9V1N6Q4x3X3g2Z5N6r3#2D9i4@1f1K6i4K6R3H3i4K6R3J5 三星(包括其他使用Trustonic的厂商,例如部分使用联发科芯片的小米手机)就在使用ATF(ARM可信固件)来实现监控模式。上述实现基本上是参考了ARM的开源文档。此外,Quarkslab针对ATF逆向方面写了一篇非常不错的文章,大家可以参考阅读:f82K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2M7i4g2S2M7X3E0K6L8r3q4T1i4K6u0W2j5$3!0E0i4K6u0r3M7X3g2$3k6i4u0K6k6g2)9J5k6r3g2F1k6$3W2F1k6h3g2J5K9h3&6Y4i4K6u0V1M7$3q4E0M7%4g2F1k6#2)9J5k6s2x3$3i4K6u0V1M7$3u0G2L8%4c8Q4x3X3c8H3j5i4u0@1i4K6u0V1K9g2)9J5k6h3S2@1L8h3H3`. d13K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2M7i4g2S2M7X3E0K6L8r3q4T1i4K6u0W2j5$3!0E0i4K6u0r3M7X3g2$3k6i4u0K6k6g2)9J5k6r3g2F1k6$3W2F1k6h3g2J5K9h3&6Y4i4K6u0V1M7$3q4E0M7%4g2F1k6#2)9J5k6s2x3$3i4K6u0V1M7$3u0G2L8%4c8Q4x3X3c8H3j5i4u0@1i4K6u0V1K9h3W2Q4x3X3g2Z5N6r3#2D9 需要注意的一点是,Linux内核不仅要使用SMC调用(通过ATF)来到达T-Base,并且T-Base内核还借助于SMC调用来实现与ATF的通信。上述内容实际上是一个黑盒问题,我们并不知道其具体原理,将会在下一篇文章中进一步学习探讨。 在这里,我要补充一句,不仅ATF会借助SMC调用来到达T-Base,有些SMC调用也可以让ATF实现命令。其中一部分是开源ATF代码中包含的命令,一部分是厂商自定义的命令。但这些并不是此次研究的重点。
4.2 T-Base:微内核 在图中的右侧,就是我们的安全世界,T-Base也在安全世界中。起初,我们认为共包含三个部分:微内核、安全驱动和Trustlet。但在后续研究中,我们意识到这个假设是错误的。图中的“运行管理(Runtime Management)”,实际上既不是Trustlet,也不是驱动,更不是微内核。关于这一点会在本篇文章的后面进行介绍。现在,我们假设在T-Base操作系统中,如果一件事不是由Trustlet和安全驱动来完成,那就一定是微内核完成的。 因此,在我们研究Trustlet之前,我们想首先了解如何通过微内核来实现对Trustlet的管理(例如加载)。 为了充分掌握原理,我们必须对微内核进行逆向工程。三星将T-Base固件存储在一个不显眼的位置——打包在sboot映像中。Gal Beniamini已经发表过一种用来提取该映像的方法,详情请参考他博客文章中“Kinibi Revocation”一节:e94K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4L8$3!0Y4L8r3g2H3M7X3!0B7k6h3y4@1P5X3g2J5L8#2)9J5k6h3u0D9L8$3N6K6M7r3!0@1i4K6u0W2K9s2g2Q4x3V1j5J5x3o6p5%4i4K6u0r3x3o6N6Q4x3V1k6@1M7Y4g2K6N6q4)9J5k6r3W2K6M7%4g2W2M7#2)9J5k6r3g2^5M7r3I4G2K9i4c8A6L8X3N6Q4x3X3c8@1M7Y4g2K6N6s2A6G2L8X3g2Q4x3X3c8@1k6h3g2K6i4K6u0W2K9s2c8E0L8q4!0q4c8W2!0n7b7#2)9^5b7#2!0q4y4g2)9&6b7#2!0m8z5q4!0q4y4W2)9&6b7#2!0m8b7#2!0q4y4#2!0m8c8W2)9^5y4#2!0q4y4W2)9&6y4W2)9^5y4#2!0q4y4#2!0m8b7W2!0m8x3q4!0q4y4g2)9&6x3q4)9^5c8g2!0q4z5g2)9&6c8q4!0m8x3W2!0q4c8W2!0n7b7#2)9^5b7#2!0q4y4q4!0n7z5g2)9&6c8W2!0q4y4q4!0n7b7#2)9&6b7g2!0q4z5q4!0m8c8W2!0m8y4W2!0q4y4#2!0n7b7W2)9^5y4W2!0q4z5q4!0n7c8W2)9&6b7W2!0q4z5q4!0m8x3g2)9^5b7#2!0q4y4q4!0n7b7W2)9^5b7W2!0q4y4#2!0n7b7W2)9^5c8q4!0q4x3#2)9^5x3q4)9^5x3R3`.`. 尽管我们必须进行逆向才能知道微内核实现Trustlet管理的具体方式,但我们可以通过公开的文档了解到微内核相当多的管理接口。 T-Base将其称为MobiCore控制协议(MCP)接口(MCI)。这是建立在SMC调用之上的,接下来我们就做具体的分析。 至此,如果你已经阅读了Gal的文章,那么想必就一定知道,在三星S8之前,T-Base并没有在Trustlet加载过程中被用于回滚保护。
4.3 T-Base:SMC快速调用 如果你已经习惯了其他的可信执行环境实现,你可能会希望每个管理功能(例如:加载Trustlet、与Trustlet共享内存、打开到Trustlet的连接等)都能是另一个微内核实现的管理程序调用,可以通过将正确的参数传递给SMC调用来直接触发,就像Linux中的ioctl调用一样。 实际上,Trustonic采取了一种完全不同的方式,保证了微内核“微”的这一特点。这一实现,可以从Linux内核源代码中详细了解,具体请参阅drivers/gud/gud-exynos8890/MobiCoreDriver/*.c。 (附注:源代码中,驱动程序文件夹名称为“gud”,就是因为原来的公司名称是“Giesecke and Devrient”。) 在Linux内核中,总共有5个SMC快速调用。其中,MC_FC_INIT用于配置队列,MC_FC_INFO可以从T-Base中获取版本信息等信息,MC_FC_SWAP_CPU可用于将T-Base移动到特定的CPU核心中,MC_FC_YIELD和MC_FC_NSIQ用于调度T-Base的运行。 fastcall.c源代码如下:
/* fast call init */
union mc_fc_init {
union mc_fc_generic as_generic;
struct {
u32 cmd;
u32 base;
u32 nq_info;
u32 mcp_info;
} as_in;
struct {
u32 resp;
u32 ret;
u32 flags;
u32 rfu;
} as_out;
};
/* fast call info parameters */
union mc_fc_info {
union mc_fc_generic as_generic;
struct {
u32 cmd;
u32 ext_info_id;
u32 rfu[2];
} as_in;
struct {
u32 resp;
u32 ret;
u32 state;
u32 ext_info;
} as_out;
};
#ifdef TBASE_CORE_SWITCHER
/* fast call switch Core parameters */
union mc_fc_swich_core {
union mc_fc_generic as_generic;
struct {
u32 cmd;
u32 core_id;
u32 rfu[2];
} as_in;
struct {
u32 resp;
u32 ret;
u32 state;
u32 ext_info;
} as_out;
};
#endif
fastcall2.c源代码如下:
intmc_fc_nsiq(void){
union mc_fc_generic fc;
int ret;
memset(&fc, 0, sizeof(fc));
fc.as_in.cmd = MC_SMC_N_SIQ;
mc_fastcall(&fc);
ret = convert_fc_ret(fc.as_out.ret);
if (ret)
mc_dev_err("failed: %dn", ret);
return ret;
}
intmc_fc_yield(void){
union mc_fc_generic fc;
int ret;
memset(&fc, 0, sizeof(fc));
fc.as_in.cmd = MC_SMC_N_YIELD;
mc_fastcall(&fc);
ret = convert_fc_ret(fc.as_out.ret);
if (ret)
mc_dev_err("failed: %dn", ret);
return ret;
}
这些命令都是通过_smc()函数来执行,该函数的作用是将参数存储在寄存器中,并生成一个SMC。 所以我们知道,如果我们想根据VBAR的设置来寻找T-Base微内核的SMC处理程序,那我们应该只能找到这一简单的实现,后面必须要对微内核中未记录的解决方案进行逆向工程,来确定代码实际处理MCP命令的位置所在。 当然,上述过程也不是完整的,Linux内核需要在T-Base被响应时得到通知。实际上,这一点是通过中断来实现的:内核驱动在系统上注册一个终端,T-Base通过MC_FC_INIT命令获知到中断的发生。
4.4 T-Base:MobiCore控制协议 MCP是基于共享缓冲区的协议,因此SMC唯一可以做的,就是设置MCP队列,通知T-Base队列中有新的输入,并安排在安全世界中运行。其中,有两个队列:命令队列是不安全世界可以加载MCP命令的地方;通知队列是不安全世界可以加载Trustlet标识符的地方,以便通知特定的Trustlet有一条命令在等待它。 MCP命令的作用在于:我们可以加载/挂起/恢复Trustlet,并且可以映射/取消映射其他共享内存到Trustlet实例的地址空间。MCP命令列表可以在Linux内核源代码中找到,具体请参见drivers/gud/gud-exynos8890/MobiCoreDriver/mci/mcimcp.h。
/** Possible MCP Command IDs
* Command ID must be between 0 and 0x7FFFFFFF.
*/
enum cmd_id {
/** Invalid command ID */
MC_MCP_CMD_ID_INVALID = 0x00,
/** Open a session */
MC_MCP_CMD_OPEN_SESSION = 0x01,
/** Close an existing session */
MC_MCP_CMD_CLOSE_SESSION = 0x03,
/** Map WSM to session */
MC_MCP_CMD_MAP = 0x04,
/** Unmap WSM from session */
MC_MCP_CMD_UNMAP = 0x05,
/** Prepare for suspend */
MC_MCP_CMD_SUSPEND = 0x06,
/** Resume from suspension */
MC_MCP_CMD_RESUME = 0x07,
/** Get MobiCore version information */
MC_MCP_CMD_GET_MOBICORE_VERSION = 0x09,
/** Close MCP and unmap MCI */
MC_MCP_CMD_CLOSE_MCP = 0x0A,
/** Load token for device attestation */
MC_MCP_CMD_LOAD_TOKEN = 0x0B,
/** Check that TA can be loaded */
MC_MCP_CMD_CHECK_LOAD_TA = 0x0C,
/** Map multiple WSMs to session */
MC_MCP_CMD_MULTIMAP = 0x0D,
/** Unmap multiple WSMs to session */
MC_MCP_CMD_MULTIUNMAP = 0x0E,
};
尽管该功能非常简单,但不意味着以安全的方式来实现该功能也是非常简单的。事实上,几乎所有的安卓可信执行环境厂商,都存在安全问题,更多详情可以参见UCSB研究人员发表的《BOOMERANG》文章:50fK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0M7#2)9J5k6i4g2U0M7$3u0Q4x3X3g2W2k6s2g2Q4x3V1k6Q4y4@1g2$3K9h3N6F1j5g2)9J5c8Y4m8#2j5X3I4A6j5$3q4@1K9h3!0F1M7#2)9J5c8U0t1H3x3e0N6Q4y4h3k6z5c8q4y4e0i4K6g2X3b7X3!0G2L8h3g2J5j5h3&6Y4i4K6u0W2M7r3c8X3i4@1f1K6i4K6R3H3i4K6R3J5 从Linux内核的角度来看,这些功能是通过实现mc_user_fops操作(该操作在drivers/gud/gud-exynos8890/MobiCoreDriver/user.c中定义)的/dev/mobicore设备节点过程中暴露的。
4.5 T-Base:Trustlet和安全驱动 接下来,让我们一起来看看Trustlet。首先要提到的是,在去年,Gal Beniamini的一篇博客文章(3f1K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4L8$3!0Y4L8r3g2H3M7X3!0B7k6h3y4@1P5X3g2J5L8#2)9J5k6h3u0D9L8$3N6K6M7r3!0@1i4K6u0W2K9s2g2Q4x3V1j5J5x3o6p5%4i4K6u0r3x3o6N6Q4x3V1k6@1M7Y4g2K6N6q4)9J5k6r3W2K6M7%4g2W2M7#2)9J5k6r3g2^5M7r3I4G2K9i4c8A6L8X3N6Q4x3X3c8@1M7Y4g2K6N6s2A6G2L8X3g2Q4x3X3c8@1k6h3g2K6i4K6u0W2K9s2c8E0L8q4!0q4c8W2!0n7b7#2)9^5z5g2!0q4y4q4!0n7z5q4!0m8c8q4!0q4y4g2!0m8c8W2!0n7z5g2c8Q4x3X3c8n7j5i4y4W2 Trustlet的实现给出了非常棒的观点,我觉得大家有必要首先阅读一下。 更详细的内容,请继续阅读本文。 根据Tim Newsham此前的研究(6c2K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4c8Z5k6h3&6W2N6%4y4Z5i4K6u0W2j5X3I4G2k6%4y4H3L8%4c8Q4x3X3g2Z5N6g2)9J5c8U0t1H3x3e0g2Q4x3V1j5H3x3W2)9J5c8X3c8A6M7$3q4K6M7$3g2E0j5X3I4A6L8X3N6Q4x3X3c8E0L8$3u0A6j5$3!0J5k6g2)9J5k6s2c8J5N6i4y4@1L8r3g2@1M7#2)9J5k6h3S2@1L8h3I4Q4c8f1k6Q4b7V1y4Q4z5o6W2Q4c8f1k6Q4b7V1y4Q4z5p5y4Q4c8e0k6Q4z5o6S2Q4z5e0q4Q4c8e0c8Q4b7V1u0Q4b7f1y4Q4c8e0N6Q4z5f1k6Q4b7e0g2Q4c8e0W2Q4z5o6q4Q4z5e0y4Q4c8f1k6Q4b7V1y4Q4z5p5y4f1M7Y4g2K6N6r3I4W2N6q4!0q4y4q4!0n7b7g2)9^5b7#2!0q4z5q4!0n7c8W2)9&6b7W2!0q4y4g2)9^5z5q4!0n7y4W2!0q4y4W2)9&6y4W2)9^5y4#2!0q4y4q4!0n7b7W2!0n7y4W2!0q4y4g2)9^5c8W2!0m8c8W2!0q4y4q4!0n7b7W2!0m8y4g2!0q4y4g2)9&6b7#2!0m8z5q4!0q4z5q4!0m8c8g2!0n7c8g2!0q4y4g2!0m8y4q4)9^5y4#2!0q4y4#2)9&6b7g2)9^5y4q4)9J5c8Y4y4&6M7%4c8W2L8g2)9J5c8X3q4H3M7q4)9J5c8X3#2U0f1X3g2Y4K9i4y4@1M7Y4W2Q4c8e0k6Q4z5o6S2Q4z5e0k6Q4x3V1k6V1j5i4c8S2i4K6u0r3j5i4m8H3i4K6u0r3L8h3y4d9k6h3N6A6M7%4c8J5P5g2!0q4y4q4!0n7z5q4!0m8c8q4!0q4y4W2)9^5z5g2!0n7c8g2!0q4y4g2)9^5z5q4!0n7x3q4!0q4c8W2!0n7b7#2)9^5b7#2!0q4y4W2)9^5z5q4)9&6y4W2!0q4z5q4)9^5x3q4)9^5y4g2!0q4y4q4!0n7b7W2)9^5c8g2!0q4y4q4!0n7z5q4)9^5z5g2!0q4y4W2)9&6z5q4)9&6c8V1k6a6g2p5q4Q4c8e0k6Q4z5e0S2Q4b7e0m8Q4c8e0g2Q4z5o6y4Q4z5p5k6Q4c8e0c8Q4b7U0S2Q4b7f1c8Q4c8e0S2Q4b7e0y4Q4z5o6g2Q4c8e0S2Q4b7V1c8Q4b7V1c8Q4c8e0c8Q4b7V1q4Q4z5o6k6K6K9h3@1J5K9h3#2Y4i4@1f1%4i4K6W2m8i4K6R3@1M7%4W2K6N6r3g2E0i4K6u0W2K9h3#2Y4i4@1f1%4i4K6W2m8i4K6R3@1b7g2m8b7i4@1f1%4i4K6W2n7i4@1q4q4i4@1f1#2i4@1u0p5i4K6V1#2i4@1f1@1i4@1t1^5i4K6S2n7i4@1f1$3i4K6R3&6i4@1u0q4i4@1f1#2i4K6R3^5i4@1t1H3i4@1f1K6i4K6R3H3i4K6R3J5 我们还需要知道MobiCore加载器格式(MCLF,Truslet和安全驱动的文件格式):在内核源代码中,请查看诸如gud/gud-exynos8890/MobiCoreDriver/mci/mcloadformat.h这样路径下的源文件。这是一个由Gassan Idriss编写的IDA加载程序,可供参考:792K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6Y4K9r3q4K6M7$3q4F1K9g2)9J5c8X3#2U0L8r3k6Q4x3X3c8A6k6r3q4Q4x3X3c8D9L8$3q4V1k6i4u0Q4x3V1k6T1L8r3!0T1i4K6u0r3L8h3q4K6N6r3g2J5i4K6u0r3L8h3y4D9k6W2)9#2k6X3I4G2j5h3c8W2M7W2)9J5k6i4m8&6i4@1f1K6i4K6R3H3i4K6R3J5i4@1f1$3i4@1q4p5i4@1p5@1i4@1f1#2i4@1p5@1i4K6V1$3i4@1g2r3i4@1u0o6i4K6S2o6g2r3W2E0 Newsham还写了另一套工具(b7eK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4m8S2M7%4c8W2j5X3W2F1i4K6u0W2j5$3!0E0i4K6u0r3k6h3p5%4b7V1M7$3j5$3A6Q4c8f1k6Q4b7V1y4Q4z5f1u0Z5N6s2c8H3i4K6y4m8i4K6u0r3i4K6u0r3M7r3q4K6N6r3g2T1K9h3&6Q4x3X3g2U0L8$3#2Q4x3V1k6p5f1s2N6U0L8i4u0w2x3W2!0q4c8W2!0n7b7#2)9^5z5g2!0q4c8W2!0n7b7#2)9^5b7#2!0q4y4#2)9&6y4q4!0m8z5q4!0q4y4q4!0n7b7g2)9^5c8g2!0q4y4g2!0n7x3q4)9^5y4V1#2o6e0p5k6Q4c8e0S2Q4b7V1c8Q4b7f1y4Q4c8e0k6Q4z5p5c8Q4b7e0u0Q4c8e0k6Q4z5o6S2Q4z5e0m8q4e0p5k6Q4c8e0y4Q4z5o6m8Q4z5o6t1`. 在Trustlet中区分驱动非常简单,可以根据MCLF中的版本字段来判断。或者还有一种更快的方法:名称以“ffffffff00”开头的是Trustlet,名称以“ffffffffd0”开头的是安全驱动。另一方面,由于这些名称是以他们的UUID命名的,而不是一个有意义的名字,因此想要知道哪些二进制文件中隐藏了什么功能并不容易。我们可以使用逆向工程的方式来实现这一点。 尽管其加载过程是在不安全世界中进行的解析,但MCLF格式在安卓内核源代码中还是有意义的,但更令人惊讶的是,所谓的tlApi和drApi也在某些来源中被定义。我不知道这是否是一个错误的定义,并且也不是在每个发布的三星内核源代码中都能找到该路径,但至少我在GitHub的源代码中发现了一个存在的样例。 这些是Trustlet与安全驱动分别用来与T-Base微内核通信的API。其中包括与不安全世界中应用程序进行交互的功能、允许安全世界中进程(Trustlet/安全驱动)相互通信的功能,以及对通常由内核处理的功能的调用(例如映射内存地址空间)。 正如Tim Newsham和Gal Beniamini的博客文章中所述,Trustlet通过一个调用门(Call-Gate,类似于ELF的GOT,除了对所有API调用都有单个跳转目标之外)调用这些API。也就是说,这些调用并没有编译成Trustlet二进制文件。由此,我们就又产生了另一个资料都未能解答的疑问——这些API实际上都在哪里,并且是如何实现的?我们可以推测,这些API实际上会以某种方式被SVC调用包装,并在T-Base微内核中实现系统调用处理程序。但我们并不清楚其中的细节。同样,我们也没有tlApi或drApi中所有调用的信息。此外,Tim的博客文章是几年之前写的,其中所列出的API调用列表也是不完整的。 关于安全驱动,除了这些头文件之外,我没有找到太多的公开资料。就目前而言,理解了安全驱动能够访问各种硬件就已经足够了。此外,加密驱动会与加密引擎进行通信。安全SPI驱动一方面会通过SPI接口与指纹传感器进行通信,另一方面通过SPI接口与安全支付的嵌入式安全元件(Samsung Pay)进行通信。上述所提及内容,均在三星官方文档(65aK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3c8W2N6X3g2D9L8%4m8W2M7W2)9J5k6i4y4S2L8i4y4#2L8X3N6Q4x3X3g2U0L8$3#2Q4x3V1k6@1k6h3y4Z5i4K6u0V1K9h3&6K6K9h3N6Z5N6s2y4Q4x3V1k6H3j5i4W2Q4x3V1k6V1k6i4k6A6j5$3g2Q4x3X3c8K6K9h3c8W2i4K6u0V1M7$3g2U0N6i4u0A6N6s2W2Q4c8f1k6Q4b7V1y4Q4z5o6W2Q4c8e0c8Q4b7U0S2Q4b7f1c8Q4c8e0k6Q4z5f1y4Q4z5o6W2Q4c8e0S2Q4b7f1k6Q4b7e0k6Q4c8e0N6Q4b7V1u0Q4z5o6k6Q4c8e0S2Q4b7f1k6Q4b7U0c8Q4c8e0k6Q4z5e0S2Q4z5p5g2Q4c8e0y4Q4z5o6m8Q4z5o6t1`. 关于Trustlet和tlApi,我们可以找到一些公开信息,例如Trustonic的Jan-Erik Ekberg的演示(615K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6#2M7$3#2A6L8r3g2Q4x3X3g2S2N6q4)9J5c8Y4y4A6N6r3g2K6i4K6u0r3k6r3g2X3j5i4g2D9N6q4)9J5c8X3k6A6L8r3g2K6i4K6u0r3j5h3&6V1M7X3!0A6k6s2y4W2j5%4g2J5K9i4c8&6M7%4W2E0M7r3!0K6K9i4g2E0i4K6u0r3M7s2u0W2M7$3g2F1N6r3q4@1K9h3!0F1M7K6t1H3x3e0g2Q4x3V1k6q4K9$3u0W2M7X3N6Q4y4h3k6m8L8X3c8J5L8$3W2V1b7h3&6V1g2s2u0#2M7%4c8W2k6p5g2^5k6h3y4#2N6r3W2G2L8V1g2F1N6X3W2J5L8$3&6E0k6h3&6@1M7#2)9J5k6i4m8V1k6W2!0q4c8W2!0n7b7#2)9^5z5g2!0q4x3#2)9^5x3q4)9^5x3W2!0q4y4W2!0m8x3q4!0n7z5g2!0q4y4W2)9^5c8q4!0m8c8g2!0q4y4q4!0n7b7W2)9&6y4W2m8b7g2q4!0q4y4q4!0n7z5q4)9^5b7g2!0q4z5g2)9&6c8q4!0m8x3W2!0q4y4#2)9&6b7g2)9^5y4q4!0q4y4q4!0n7z5q4)9^5x3q4!0q4y4g2!0n7b7#2!0m8x3q4!0q4y4W2)9^5z5q4!0m8b7g2!0q4y4g2)9&6b7W2!0n7c8g2!0q4c8W2!0n7b7#2)9^5b7#2!0q4y4W2)9^5z5q4)9&6x3g2!0q4y4q4!0n7b7W2!0m8b7#2!0q4y4g2)9^5c8W2!0m8c8W2!0q4y4q4!0n7b7W2!0m8y4g2!0q4y4#2)9&6b7#2)9^5b7W2!0q4y4g2)9^5z5q4!0n7x3q4!0q4c8W2!0n7b7#2)9&6b7b7`.`. Trustlet的基本行为非常简单。在IPC部分(与安全驱动通信)有些复杂,但就接口的Trustlet而言,只有tlApi调用tlApi_callDriver(),其工作原理与Linux的ioctl有些相似,它将一个命令ID和一个指向命令结构的指针作为参数。这里也是,并没有在Linux内核源代码中体现,但我们在GitHub上却至少可以找到一个源代码是使用了这样的头文件。 如果你已经阅读了Jan-Erik的幻灯片,你应该已经了解到有一个名为GP(Global Platform)的标准化可信执行环境,它为不同的可信执行环境创建了一个通用的API。Trustonic支持GP标准,因此他们也有相应的API可以实现通用标准。他们所做的,就是增加了一些特性,将相应内容变成T-Base特定的API。然而比较不错的是,三星似乎在Trustlet中使用了传统的API,所以我们不用担心这一点。
五、T-Base与安卓 现在,我们来研究安卓层面。这里仍然有Trustonic编写的代码,他们创建了一个用户控件守护进程mcDriverDaemon,向用户空间的应用程序开放接口。由于某种原因,以前版本的代码曾经开源过,因此理解这个驱动程序的驱动就变得非常简单。 这个守护进程通过libMcClient.so访问内核设备节点,其命令清晰地映射到MCP命令中,请参考:dfbK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6f1M7Y4g2K6N6r3!0F1K9h3y4Q4x3V1k6@1M7Y4g2K6N6r3!0F1K9h3y4Q4x3X3c8@1k6h3g2Q4x3X3c8#2M7$3g2J5i4K6u0V1M7%4m8S2j5$3g2Q4c8e0y4Q4z5o6m8Q4z5o6t1`. Trustonic这一设计目的在于,只有mcDriverDaemon能够访问设备节点,并且通过UNIX本地套接字开放接口。Trustonic将该接口命名为TLC(Trustlet连接器)。 在三星的具体场景下,这一情况更为复杂。一方面,设备节点使用DAC和MAC(SELinux)进行限制,但仍有许多特权进程可以对其进行访问,其中有一些无需通过mcDriverDaemon即可对其进行操作。同样,UNIX本地套接字只能由特权进程访问。事实上,三星想要分为直接(libtlc_direct_comm.so)和代理(libtlc_proxy_comm.so)这两种方式,但有一些进程同时使用了这两种方式。 至此,我们的研究过程还并不完整。很显然,三星使用这样的配置,使得安卓系统中一些TrustZone支持的功能能够完全在特权模式下进行,例如system_server。但还有一种功能,可以将特权进程扩展到应用程序中,完全无需权限,或是可以通过常规的应用程序来获取到权限。 这是通过将Binder接口添加到各种特权进程中来实现的。安卓会借助API来允许进程在其Binder接口上进行访问控制,因此我们非常希望三星也能够实现这一点。但是,我们必须要深入进行逆向工程,因为目前没有相关文档或相关的现有技术。 Gal曾经写过一个otp_server代理。同样,还有很多其他的代理。举例来说,这个例子是针对Samsung Pay场景下实现的:9d4K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2T1L8r3q4U0K9$3S2S2N6q4)9J5k6h3y4G2L8g2)9J5c8X3c8G2j5%4y4Q4x3V1k6W2N6g2)9J5k6o6p5%4i4K6u0r3L8h3q4@1k6i4u0A6j5h3I4K6i4K6u0r3k6i4g2Q4x3X3b7I4y4#2)9J5k6p5#2S2i4K6u0V1d9r3!0%4i4K6u0V1f1$3q4E0M7%4g2F1k6#2)9J5k6q4y4W2j5%4g2J5k6i4y4Q4x3X3c8k6L8%4g2J5i4K6u0V1g2$3q4D9L8r3g2@1i4K6u0V1b7h3&6V1i4K6u0V1d9r3!0%4i4K6u0V1g2r3!0Q4x3X3c8n7M7X3g2S2K9#2)9J5k6p5W2@1i4K6u0W2M7r3c8X3i4@1f1K6i4K6R3H3i4K6R3J5i4@1f1#2i4K6W2o6i4@1p5^5i4@1f1$3i4K6R3^5i4K6V1I4i4@1f1@1i4@1u0n7i4@1q4o6i4@1f1%4i4K6W2m8i4K6R3@1i4@1f1%4i4@1p5H3i4K6V1@1i4@1f1%4i4@1p5&6i4@1t1$3i4@1f1@1i4@1t1^5i4@1q4p5i4@1g2r3i4@1u0o6i4K6S2o6i4@1f1$3i4K6R3^5i4K6V1I4i4@1f1@1i4@1t1^5i4K6V1K6i4@1f1$3i4@1t1K6i4@1p5^5i4@1f1@1i4@1u0m8i4K6S2q4i4@1f1@1i4@1u0p5i4@1u0r3i4@1f1%4i4K6V1@1i4@1p5^5N6r3I4U0i4K6g2X3M7$3g2J5N6X3g2J5i4@1g2r3i4@1u0o6i4K6S2o6i4@1f1%4i4K6W2n7i4@1q4q4i4@1f1#2i4K6R3&6i4K6S2p5i4@1f1$3i4K6W2m8i4K6R3J5i4@1f1$3i4K6V1%4i4@1t1$3i4@1f1^5i4@1u0r3i4K6V1^5i4@1f1$3i4@1t1J5i4@1p5I4i4@1f1$3i4K6W2o6i4K6R3&6i4@1f1#2i4@1t1H3i4K6W2p5i4@1f1^5i4@1q4r3i4K6V1#2i4@1f1^5i4@1u0r3i4K6R3%4i4@1f1#2i4K6R3#2i4@1t1$3i4@1f1@1i4@1u0n7i4K6V1$3i4@1f1$3i4K6R3K6i4K6R3#2i4@1f1#2i4K6R3$3i4@1t1#2i4@1f1K6i4K6R3H3i4K6R3J5
六、与Trustlet的通信 在对这一架构的细节进行研究的过程中,我们注意到一个明显的漏洞。 尽管我们已经知道如何在安卓中设置WSM(TCI缓冲区)来向一个Trustlet发送命令,但是我们并不知道该命令的固定格式,也没有找到任何用于实现常见任务的指导(或者相关的库)。那从事实上看,每一个Trustlet都有自己的方式吗? 尽管目前,公开资料中并没有用于Trustlet通信的通用命令结构,但是Trustonic可能会与合作商分享开发人员指南。那对于我们来说,就只能通过逆向工程来实现了。 剧透警告:在最后,通过对Trustlet进行逆向,我发现三星Trustlet的命令看上去是使用了通用头部格式,但实际上不一定是通用的。并且,对于Trustlet之间的命令有效载荷,它并不会扩展到任意种类的标准结构。
七、小结 接下来,让我们回顾一下该结构的各个层级:
三星Sboot遵循ATF模型。Sboot会加载EL3固件(ATF)和操作系统运行在安全世界的EL0+EL1(T-Base)。在加载完成后,bootloader会将处理器切换成不安全世界模式,并加载应用程序,当然也会加载安卓系统。
ATF会捕获到全部世界中EL1的SMC调用,并在二者之间进行代理。
Linux内核会设置用作MCP命令队列和通知队列的共享缓冲区,并通过快速调用(在寄存器中传递带有参数的SMC指令)来初始化与T-Base微内核的通信。
Linux内核使用另一个快速调用来通知(进行调度)T-Base。T-Base使用Linux内核中注册的中断,在处理命令完成后通知不安全世界。
Linux内核实现了MCP,这些命令允许通过Trustlet实例来加载并共享内存,并通过/dev/mobicore和/dev/mobicore-user设备的ioctl接口对外开放。它包括在WSM范围之内的完整性检查,用于确保用户空间无法请求可能导致不安全世界内部Linux内核损坏/内核特权提升的内存区域。(此前发现,这种健全性的检查是不充分的。)
libMcClient.so库负责ioctl接口的用户空间实现。
用户空间进程通过不同的libtlc_*共享库来实现对库的利用。拥有足够特权的进程,可以直接使用能够加载libMcClient.so的变体,其他进程需要通过mcDriverDaemon来获得访问权限。在这里,通过普通的UNIX套接字暴露了MCP接口,但后面增加了健全性检查,就可以防止客户端进行类似于Linux内核的非法MCP行为。
套接字仍然受MAC和DAC机制的限制,因此非特权应用程序无法访问它们。而与之相反,三星增加了各种代理进程(比如tlc_server),通过Binder进一步暴露了mcDriverDaemon接口,从而允许具有足够权限的应用程序通过访问特定的Binder界面的方式来与T-Base进行交互,以及加载Trustlet并与之通信。
八、T-Base映像提取 要提取所有嵌入到Sboot映像中的T-Base固件(例如:微内核、运行时间管理器、tlLibrary、加密驱动等),需要使用字符串标记“t-base”来查找提取表:
ROM:00147000 tbase_extract_table DCB "t-base ",0 ; descriptor struct:
ROM:00147000 ; char name[8]
ROM:00147000 ; int offset
ROM:00147000 ; int size
ROM:00147000 ; char padding[0x10]
ROM:00147000 ;
ROM:00147000 ; real start offset: 0x132000
ROM:00147000 ;
ROM:00147000 ; Mtk: 0->0x147000 -> the Microkernel image itself -> go back 0x15000 from "t-base"
ROM:00147000 ; Image_h: 0x147000 -> 0x148000 -> so that's this
ROM:00147000 ; Rtm: 0x148000 -> RTM is the Run-Time Manager (aka S0CB)
ROM:00147000 ;
ROM:00147000 ; drcrypt: 0x167000 -> MCLF file (Crypto Driver)
ROM:00147000 ; tlproxy: 0x17A000 -> MCLF file (SFS Trustlet)
ROM:00147000 ; sth2: 0x17B000 -> MCLF file (SFS Driver)
ROM:00147000 ; mclib: 0x183000 -> tlLib (runtime library for Trustlets and Drivers)
ROM:00147008 DCD 0
ROM:0014700C DCD 0x5D000
ROM:00147010 ALIGN 0x20
ROM:00147020 aMtk DCB "mtk ",0
ROM:00147028 DCD 0
ROM:0014702C DCD 0x15000
ROM:00147030 ALIGN 0x20
ROM:00147040 aImage_h DCB "image_h",0
ROM:00147048 DCD 0x15000
ROM:0014704C DCD unk_1000
ROM:00147050 ALIGN 0x20
ROM:00147060 aRtm DCB "rtm ",0
ROM:00147068 DCD 0x16000
ROM:0014706C DCD 0x1F000
ROM:00147070 ALIGN 0x20
ROM:00147080 aDrcrypt DCB "drcrypt",0
ROM:00147088 DCD 0x35000
ROM:0014708C DCD 0x13000
ROM:00147090 ALIGN 0x20
ROM:001470A0 aTlproxy DCB "tlproxy",0
ROM:001470A8 DCD 0x48000
ROM:001470AC DCD 0x1000
ROM:001470B0 DCD 0
ROM:001470B4 DCD 0
ROM:001470B8 DCD 0
ROM:001470BC DCD 0
ROM:001470C0 aSth2 DCB "sth2 ",0
ROM:001470C8 DCD 0x49000
ROM:001470CC DCD unk_8000
ROM:001470D0 ALIGN 0x20
ROM:001470E0 aMclib DCB "mclib ",0
ROM:001470E8 DCD 0x51000
ROM:001470EC DCD unk_C000
ROM:001470F0 ALIGN 0x1000
ROM:00148000 S0CB_HDR DCB "S0CB",0 ; Rtm offset points here
ROM:00148005 DCB 0x10, 0, 0
ROM:00148008 DCD unk_C000
ROM:0014800C DCD dword_D000
ROM:00148010 DCD 0
ROM:00148014 DCD 0x11960
ROM:00148018 DCD 0xB295
ROM:0014801C DCD 0x3F
ROM:00148020 DCD 0x6A
ROM:00148024 aMccb DCB "MCCB",0
ROM:00148029 DCD 0
ROM:0014802D DCD 0
九、T-Base SMC 目前,我已经确定了以下T-Base与通过ATF调用的SMC的对应关系: 0x1:从不安全世界中进行快速调用,并通过ATF返回到不安全世界中; 0xB2000002:将VBAR值发送给ATF(因此ATF知道SMC处理程序的位置); 0xB2000003:写入字符(用于通过ATF记录消息); 0xB2000004:将T-Base初始化状态发送给ATF。
ROM:00133054 tbase_smc_send_VBAR ; CODE XREF: config_tbase_and_tell_aft_the_vbar+E↑p
ROM:00133054 LDR R0, =0xB2000002
ROM:00133058 MOV R1, #1
ROM:0013305C LDR R2, =0x7F00000 ; normal VBAR address
ROM:00133060 SMC #0
ROM:00133064 BX LR
ROM:00133064 ; End of function tbase_smc_send_VBAR
ROM:00133064
ROM:00133068
ROM:00133068 ; =============== S U B R O U T I N E =======================================
ROM:00133068
ROM:00133068 ; Attributes: noreturn
ROM:00133068
ROM:00133068 tbase_smc_fastcall_status_then_ret_to_nonSW
ROM:00133068 ; CODE XREF: sub_1343AA:loc_1354C8↓p
ROM:00133068 ; translate_MSMBase_to_VA+46↓p
ROM:00133068 LDR R0, =0xB2000004
ROM:0013306C MOV R1, #1
ROM:00133070 MOV R2, #1
ROM:00133074 SMC #0
ROM:00133078 LDR R0, =0x2000001
ROM:0013307C SMC #0
ROM:00133080
ROM:00133080 loc_133080 ; CODE XREF: tbase_smc_fastcall_status_then_ret_to_nonSW:loc_133080↓j
ROM:00133080 B loc_133080
ROM:00133080 ; End of function tbase_smc_fastcall_status_then_ret_to_nonSW
ROM:00133080
ROM:00133084
ROM:00133084 ; =============== S U B R O U T I N E =======================================
ROM:00133084
ROM:00133084
ROM:00133084 tbase_smc_fastcall_status ; CODE XREF: sub_1343AA+31C6↓p
ROM:00133084 LDR R0, =0xB2000004
ROM:00133088 MOV R1, #1
ROM:0013308C MOV R2, #3
ROM:00133090 SMC #0
ROM:00133094 BX LR
ROM:00133094 ; End of function tbase_smc_fastcall_status
ROM:00133094
ROM:00133098
ROM:00133098 ; =============== S U B R O U T I N E =======================================
ROM:00133098
ROM:00133098
ROM:00133098 tbase_smc_fastcall_print
ROM:00133098 MOV R2, R0
ROM:0013309C LDR R0, =0xB2000003
ROM:001330A0 MOV R1, #1
ROM:001330A4 SMC #0
ROM:001330A8 BX LR
ROM:001330A8 ; End of function tbase_smc_fastcall_print
(...)
十、T-Base系统调用 .tbase_mem_data:07F0D86C ; ===========================================================================
.tbase_mem_data:07F0D86C
.tbase_mem_data:07F0D86C ; Segment type: Pure data
.tbase_mem_data:07F0D86C AREA .tbase_mem_data, DATA, ALIGN=0
.tbase_mem_data:07F0D86C ; ORG 0x7F0D86C
.tbase_mem_data:07F0D86C syscall_table DCD svc_0_nop+1 ; DATA XREF: invoke_syscall_from_table+40↑o
.tbase_mem_data:07F0D86C ; invoke_syscall_from_table:syscall_table_ptr↑o
.tbase_mem_data:07F0D870 DCD svc_1_init_process+1
.tbase_mem_data:07F0D874 DCD svc_2_nop+1
.tbase_mem_data:07F0D878 DCD svc_3_nop+1
.tbase_mem_data:07F0D87C DCD svc_4+1 ; Did not find this invoked anywhere in {RTM,tlLib}
.tbase_mem_data:07F0D880 DCD svc_5_start_process+1
.tbase_mem_data:07F0D884 DCD svc_exit+1
.tbase_mem_data:07F0D888 DCD svc_mmap+1
.tbase_mem_data:07F0D88C DCD svc_8_munmap+1
.tbase_mem_data:07F0D890 DCD svc_9_start_thread+1
.tbase_mem_data:07F0D894 DCD svc_A_stop_thread+1
.tbase_mem_data:07F0D898 DCD svc_B_return_0xD+1
.tbase_mem_data:07F0D89C DCD svc_C_modify_thread_registers+1
.tbase_mem_data:07F0D8A0 DCD svc_D_mprotect+1
.tbase_mem_data:07F0D8A4 DCD svc_E_resume_thread+1
.tbase_mem_data:07F0D8A8 DCD svc_F+1
.tbase_mem_data:07F0D8AC DCD svc_10_set_thread_prio+1
.tbase_mem_data:07F0D8B0 DCD svc_11_ipc+1
.tbase_mem_data:07F0D8B4 DCD svc_12_int_attach+1
.tbase_mem_data:07F0D8B8 DCD svc_13_int_detach+1
.tbase_mem_data:07F0D8BC DCD svc_14_sigwait+1
.tbase_mem_data:07F0D8C0 DCD svc_15_signal+1
.tbase_mem_data:07F0D8C4 DCD svc_16+1 ; Did not find this invoked anywhere in {RTM,tlLib}
.tbase_mem_data:07F0D8C8 DCD svc_tbase_smc_fastcall_input+1
.tbase_mem_data:07F0D8CC DCD svc_18_log_char+1
.tbase_mem_data:07F0D8D0 DCD svc_19_get_secure_timestamp+1
.tbase_mem_data:07F0D8D4 DCD svc_1A_control+1 ; includes a lot, such as:
.tbase_mem_data:07F0D8D4 ; - driver shmem map/unmap
.tbase_mem_data:07F0D8D4 ; - get/set exception info
.tbase_mem_data:07F0D8D4 ; - get MCP queue info
.tbase_mem_data:07F0D8D4 ; - get IPCH phys address values
.tbase_mem_data:07F0D8D4 ; - cache control
.tbase_mem_data:07F0D8D4 ; - virt2phys, phys2virt translation
.tbase_mem_data:07F0D8D4 ; - set custom fastcall, call custom fastcall
.tbase_mem_data:07F0D8D4 ;
.tbase_mem_data:07F0D8D4 ; Known sub-handlers:
.tbase_mem_data:07F0D8D4 ;
.tbase_mem_data:07F0D8D4 ; -0x8F: getting/setting fastcall configuration values
.tbase_mem_data:07F0D8D4 ; - 0xC: get S0CB PA
.tbase_mem_data:07F0D8D4 ; - 0xA: notify (nSW - trigger interrupt)
.tbase_mem_data:07F0D8D4 ; - 0xB: notify driver (drTriggerIntr)
.tbase_mem_data:07F0D8D4 ; - 0xD: get fc_init perm flags
.tbase_mem_data:07F0D8D4 ; - 0x1: set exception info
.tbase_mem_data:07F0D8D4 ; - 0x2: get fault info
.tbase_mem_data:07F0D8D4 ; - 0x4,0x5,0x6,0x7: get MCP queue info
.tbase_mem_data:07F0D8D4 ; (mci_buffer_addr, nq_length, mcp_queue_addr, mcp_queue_len)
.tbase_mem_data:07F0D8D4 ; - 0x9: map mcp cmd queue (in kernel)
.tbase_mem_data:07F0D8D4 ; -0x90 -> more control
.tbase_mem_data:07F0D8D4 ; - 5: read info for exception
.tbase_mem_data:07F0D8D4 ; - 7: translate VA to PA
.tbase_mem_data:07F0D8D4 ; -0x91 virt-to-phys and also virt-to-phys64
.tbase_mem_data:07F0D8D4 ; -0x92 -> I-cache clean/invalidate, D-cache clean/invalidate
.tbase_mem_data:07F0D8D4 ; -0x81:map, 0x83: unmap, 0x85:map.
.tbase_mem_data:07F0D8D4 ; - Difference in 81/85: map in
十一、RTM IPC 请注意,在这里我们称RTM为“S0CB”,是由于其文件格式的魔术值(Magic Value)。根据Sboot固件中的提示,更加准确的一个名称应该是RTM(Run Time Manager,运行时间管理器)。 这是T-Base中一个强大的用户空间进程,始终最先启动,并负责启动和管理所有其他进程(Trustlet)。与Linux上的init类似,它负责三个功能:
实现MCP;
当请求从不安全世界到达时,通知Trustlet;
实现T-Base的IPC机制。 其中,MCP命令都可以从公开渠道获知。对于IPC,前12个IPC命令可以在这里找到源代码:68cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6K6k6h3q4J5j5$3S2U0L8$3c8W2i4K6u0W2j5$3!0E0i4K6u0r3j5$3!0V1k6i4y4W2j5i4u0U0K9q4)9J5c8Y4k6A6k6i4N6Q4x3V1j5@1x3U0b7&6y4K6V1&6y4W2)9J5c8W2!0q4x3#2)9^5x3q4)9^5x3W2!0q4y4g2)9&6b7#2!0m8z5q4!0q4z5q4!0n7c8W2)9&6z5g2!0q4z5g2)9^5y4#2)9^5b7#2!0q4c8W2!0n7b7#2)9^5b7#2!0q4y4W2)9^5z5q4)9&6x3g2!0q4y4g2)9^5c8W2)9^5x3W2!0q4z5q4)9^5x3q4)9^5x3#2!0q4y4q4!0n7b7g2)9^5y4W2!0q4y4#2)9&6b7W2!0n7z5q4!0q4y4g2)9^5y4g2!0n7x3#2!0q4y4#2)9&6b7g2)9^5y4q4!0q4y4g2)9&6x3g2!0n7c8q4!0q4y4g2)9&6x3q4)9^5c8q4!0q4y4#2!0n7b7g2!0m8y4W2!0q4y4g2!0m8c8g2)9&6b7g2!0q4c8W2!0n7b7#2)9^5b7#2!0q4y4g2!0m8c8W2!0n7z5g2!0q4y4q4!0n7b7g2)9^5c8g2!0q4y4g2)9^5y4g2!0n7y4W2!0q4y4q4!0n7c8q4)9&6z5g2!0q4z5g2)9^5x3#2!0m8z5q4!0q4y4g2)9^5z5q4)9^5y4W2!0q4c8W2!0n7b7#2)9^5b7#2!0q4y4g2)9^5y4g2!0n7y4#2!0q4y4q4!0n7c8q4)9&6x3#2!0q4y4g2!0m8y4W2)9^5x3W2!0q4y4q4!0n7z5q4)9^5b7W2!0q4c8W2!0n7b7#2)9&6b7b7`.`.
/** Possible message types/event types of the system. */
typedef enum {
MSG_NULL = 0, // Used for initializing state machines
/***************/
MSG_RQ = 1, /**< Request; client -> server; */
MSG_RS = 2, /**< Response; server -> client */
MSG_RD = 3, /**< Ready; server -> IPCH */
MSG_NOT = 4, /**< Notification; client -> IPCH; */
MSG_CLOSE_TRUSTLET = 5, /**< Close Trustlet; MSH -> IPCH; IPCH -> all servers */
MSG_CLOSE_TRUSTLET_ACK = 6, /**< Close Trustlet Ack; servers -> IPCH */
MSG_MAP = 7, /**< Map; driver <-> IPCH; */
MSG_ERR_NOT = 8, /**< Error Notification; EXCH/SIQH -> IPCH; */
MSG_CLOSE_DRIVER = 9, /**< Close driver; MSH -> IPCH; IPCH -> driver */
MSG_CLOSE_DRIVER_ACK = 10, /**< Close driver Ack; driver -> IPCH; IPCH -> MSH */
MSG_GET_DRIVER_VERSION = 11, /**< GetDriverVersion; client <--> IPCH */
MSG_GET_DRAPI_VERSION = 12, /**< GetDrApiVersion; driver <--> IPCH */
MSG_SET_NOTIFICATION_HANDLER = 13, // Driver <-> IPCH
MSG_DRV_NOT = 15, // Driver -> Trustlet
MSG_SET_FASTCALL_HANDLER = 16, // Driver <-> IPCH
MSG_GET_CLIENT_ROOT_AND_SP_ID = 17, // Driver <-> IPCH
MSG_CALL_FASTCALL = 25, // DRIVER -> IPCH -> Kernel
MSG_GET_CLI_UUID = 26, // Driver <-> IPCH
MSG_RQ_2 = 27, // Client -> Server
MSG_MAP_VA_DIRECT = 31, // DRIVER <-> IPCH
MSG_MAP_PY_DIRECT = 32, // DRIVER <-> IPCH
MSG_UNMAP_PY_DIRECT = 33, // DRIVER <-> IPCH
MSG_GET_MEM_TYPE = 34, // DRIVER <-> IPCH
MSG_UNMAP_VA_DIRECT = 35 // DRIVER <-> IPCH
} message_t;
十二、tlApi ROM:07D0BE38 tlApi_syscall_table DCD tlApiNOP+1 ; 0
ROM:07D0BE38 DCD tlApiGetVersion+1 ; 1
ROM:07D0BE38 DCD tlApiGetMobicoreVersion+1; 2
ROM:07D0BE38 DCD tlApiGetPlatformInfo+1; 3
ROM:07D0BE38 DCD tlApiExit+1 ; 4
ROM:07D0BE38 DCD tlApiLogvPrintf+1 ; 5
ROM:07D0BE38 DCD tlApiWaitNotification+1; 6
ROM:07D0BE38 DCD tlApiNotify+1 ; 7
ROM:07D0BE38 DCD tlApi_callDriver+1 ; 8
ROM:07D0BE38 DCD tlApiWrapObjectExt+1; 9
ROM:07D0BE38 DCD tlApiUnwrapObjectExt+1; 10
ROM:07D0BE38 DCD tlApiGetSuid+1 ; 11
ROM:07D0BE38 DCD tlApiSecSPICmd+1 ; 12
ROM:07D0BE38 DCD tlApiCrAbort+1 ; 13
ROM:07D0BE38 DCD tlApiRandomGenerateData+1; 14
ROM:07D0BE38 DCD tlApiGenerateKeyPair+1; 15
ROM:07D0BE38 DCD tlApiCipherInitWithData+1; 16
ROM:07D0BE38 DCD tlApiCipherUpdate+1 ; 17
ROM:07D0BE38 DCD tlApiCipherDoFinal+1; 18
ROM:07D0BE38 DCD tlApiSignatureInitWithData+1; 19
ROM:07D0BE38 DCD tlApiSignatureUpdate+1; 20
ROM:07D0BE38 DCD tlApiSignatureSign+1; 21
ROM:07D0BE38 DCD tlApiSignatureVerify+1; 22
ROM:07D0BE38 DCD tpiApiMessageDigestInitWithData+1; 23
ROM:07D0BE38 DCD tlApiMessageDigestUpdate+1; 24
ROM:07D0BE38 DCD tlApiMessageDigestDoFinal+1; 25
ROM:07D0BE38 DCD tlApiGetVirtMemType+1; 26
ROM:07D0BE38 DCD tlApiDeriveKey+1 ; 27
ROM:07D0BE38 DCD tlApiMalloc+1 ; 28
ROM:07D0BE38 DCD tlApiRealloc+1 ; 29
ROM:07D0BE38 DCD tlApiFree+1 ; 30
(...)
ROM:07D0BE38 DCD tlApiGetIDs+1 ; 43
(...)
ROM:07D0BE38 DCD tlApiRandomGenerateData_wrap+1; 83
ROM:07D0BE38 DCD tlApiCrash+1 ; 84
ROM:07D0BE38 DCD tlApiEndorse+1 ; 85
ROM:07D0BE38 DCD tlApiTuiGetScreenInfo+1; 86
ROM:07D0BE38 DCD tlApiTuiOpenSession+1; 87
ROM:07D0BE38 DCD tlApiTuiCloseSession+1; 88
ROM:07D0BE38 DCD tlApiTuiSetImage+1 ; 89
ROM:07D0BE38 DCD tlApiTuiGetTouchEvent+1; 90
ROM:07D0BE38 DCD tlApiTuiGetTouchEventsLoop+1; 91
ROM:07D0BE38 DCD tlApiDrmProcessContent+1; 92
ROM:07D0BE38 DCD tlApiDrmOpenSession+1; 93
ROM:07D0BE38 DCD tlApiDrmCloseSession+1; 94
ROM:07D0BE38 DCD tlApiDrmCheckLink+1 ; 95
ROM:07D0BE38 DCD tlApiDeriveKey_wrapper+1; 96
ROM:07D0BE38 DCD tlApiUnwrapObjectExt_wrapper+1; 97
ROM:07D0BE38 DCD tlApiGetSecureTimestamp+1; 98
十三、drApi ROM:07D0C114 ; int drApi_syscall_table[62]
ROM:07D0C114 drApi_syscall_table DCD drApiGetVersion+1 ; 0
ROM:07D0C114 ; DATA XREF: get_syscall_fn+30↑o
ROM:07D0C114 ; ROM:off_7D0A9F8↑o
ROM:07D0C114 DCD drApiExit+1 ; 1
ROM:07D0C114 DCD drApiMapPhys+1 ; 2
ROM:07D0C114 DCD drApiUnmap+1 ; 3
ROM:07D0C114 DCD drApiMapPhysPage4KBWithHardware+1; 4
ROM:07D0C114 DCD drApiMapClient+1 ; 5
ROM:07D0C114 DCD drApiMapClientAndParams+1; 6
ROM:07D0C114 DCD drApiAddrTranslateAndCheck+1; 7
ROM:07D0C114 DCD drApiGetTaskid+1 ; 8
ROM:07D0C114 DCD drApiTaskidGetThreadid+1; 9
ROM:07D0C114 DCD drApiGetLocalThreadId+1; 10
ROM:07D0C114 DCD drApiStartThread+1 ; 11
ROM:07D0C114 DCD drApiStopThread+1 ; 12
ROM:07D0C114 DCD drApiResumeThread+1 ; 13
ROM:07D0C114 DCD drApiThreadSleep+1 ; 14
ROM:07D0C114 DCD drApiSetThreadPriority+1; 15
ROM:07D0C114 DCD drApiIntrAttach+1 ; 16
ROM:07D0C114 DCD drApiIntrDetach+1 ; 17
ROM:07D0C114 DCD drApiWaitForIntr+1 ; 18
ROM:07D0C114 DCD drApiTriggerIntr+1 ; 19
ROM:07D0C114 DCD drApiIpcWaitForMessage+1; 20
ROM:07D0C114 DCD drApiIpcCallToIPCH+1; 21
ROM:07D0C114 DCD drApiIpcSignal+1 ; 22
ROM:07D0C114 DCD drApiIpcSigWait+1 ; 23
ROM:07D0C114 DCD drApiNotify+1 ; 24
ROM:07D0C114 DCD drApiSystemCtrl+1 ; 25
ROM:07D0C114 DCD sub_7D0A2CE+1 ; 26
ROM:07D0C114 DCD drApiVirt2Phys+1 ; 27
ROM:07D0C114 DCD drApiCacheDataClean+1; 28
ROM:07D0C114 DCD drApiCacheDataCleanAndInvalidate+1; 29
ROM:07D0C114 DCD drApiNotifyClient+1 ; 30
ROM:07D0C114 DCD drApiThreadExRegs+1 ; 31
ROM:07D0C114 DCD drApiInstallFc+1 ; 32
ROM:07D0C114 DCD drApiIpcUnknownMessage+1; 33
ROM:07D0C114 DCD drApiIpcUnknownException+1; 34
ROM:07D0C114 DCD drApiGetPhysMemType+1; 35
ROM:07D0C114 DCD drApiGetClientRootAndSpId+1; 36
ROM:07D0C114 DCD drApiCacheDataCleanRange+1; 37
ROM:07D0C114 DCD drApiCacheDataCleanAndInvalidateRange+1; 38
ROM:07D0C114 DCD drApiMapPhys64+1 ; 39
ROM:07D0C114 DCD drApiMapPhys64_2+1 ; 40
ROM:07D0C114 DCD drApiVirt2Phys64+1 ; 41
ROM:07D0C114 DCD drApiGetPhysMemType64+1; 42
ROM:07D0C114 DCD drApiUpdateNotificationThread+1; 43
ROM:07D0C114 DCD drApiRestartThread+1; 44
ROM:07D0C114 DCD drApiGetSecureTimestamp+1; 45
ROM:07D0C114 DCD drApiFastCall+1 ; 46
ROM:07D0C114 DCD drApiGetClientUuid+1; 47
ROM:07D0C114 DCD sub_7D0A2AC+1 ; 48
ROM:07D0C114 DCD drApiMapVirtBuf+1 ; 49
ROM:07D0C114 DCD drApiUnmapPhys2+1 ; 50
ROM:07D0C114 DCD drApiMapPhys2+1 ; 51
ROM:07D0C114 DCD drApiUnmapVirtBuf2+1; 52
ROM:07D0C114 DCD sub_7D07D76+1 ; 53
ROM:07D0C114 DCD sub_7D0A558+1 ; 54
ROM:07D0C114 DCD sub_7D0A574+1 ; 55
ROM:07D0C114 DCD sub_7D0A5D6+1 ; 56
ROM:07D0C114 DCD sub_7D0A738+1 ; 57
ROM:07D0C114 DCD sub_7D0A1BA+1 ; 58
ROM:07D0C114 DCD sub_7D0A1C8+1 ; 59
ROM:07D0C114 DCD sub_7D0A5F4+1 ; 60
ROM:07D0C114 DCD sub_7D0A60C+1 ; 61
十四、沙盒机制
内核和RTM都会维持其自身到Trustlet或驱动的进程实例映射,并维持进程的虚拟地址空间映射。
内核会对SVC调用者的类型进行检查,限制于驱动。RTM也会对IPC调用者的类型进行检查,同样限制于驱动。上述并不是一个核心机制,但必须针对每个案例正确执行。这一点,类似于Linux上的access_ok()检查。
这二者共同防止了将其他Trustlet的虚拟内存或任何物理内存(包括不安全世界)映射到驱动的可能性。但驱动仍然不能映射RWX内存,也不能在自己的代码页映射任何内容。
驱动程序可以使用SVC,从内核获取并得到发出当前请求Trustlet的UUID。这样可以用来过滤哪些客户端(Trustlet)应该被允许访问驱动的功能。
驱动可以使用SVC,将不安全世界或安全世界的物理内存映射到其地址空间,也可以使用SVC来注册自定义的快速调用处理器,使其能够直接从安全世界的EL1执行代码。实际上,这使得驱动拥有和安全世界EL1一样的特权。
十五、漏洞利用缓解措施(Trustlet和驱动)
分为RX代码页和RW数据页;
使栈/bss段/堆之间没有界限;
映射到Trustlet的WSM和映射到驱动的Trustlet内存,应该存储于独立的内存区域中;
关闭Stack Canaries保护机制,关闭ASLR保护机制。
原文链接: [1]bc2K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0k6h3c8A6N6h3#2Q4x3X3g2U0L8$3#2Q4x3V1k6@1j5i4y4*7K9%4y4W2j5#2)9J5c8Y4g2F1j5X3!0^5i4K6u0V1P5h3!0#2M7W2)9J5k6s2m8Z5L8$3&6W2i4K6u0V1M7r3q4J5N6q4)9J5k6r3W2Q4x3X3b7K6x3K6q4T1j5X3j5@1y4r3x3K6x3r3x3`. [2]cccK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0k6h3c8A6N6h3#2Q4x3X3g2U0L8$3#2Q4x3V1k6@1j5i4y4*7K9%4y4W2j5#2)9J5c8Y4g2F1j5X3!0^5i4K6u0V1P5h3!0#2M7W2)9J5k6s2m8Z5L8$3&6W2i4K6u0V1M7r3q4J5N6q4)9J5k6r3W2A6i4K6u0V1j5h3f1$3y4X3f1%4y4K6W2T1x3h3b7$3
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2018-3-4 21:50
被挽梦雪舞编辑
,原因: