STM32 & RT-Thread的逆向入门

backahasten@0xFA

​                现在,各种MCU的价格越来越低,同等条件下能买到的ROM和RAM资源也多了。对一些复杂逻辑的应用,相比于花费大量的时间去扣底层还不如使用操作系统加快开发速度,使用了操作系统之后,针对固件的逆向会比无os的固件逆向有一些不同。

​                RT-Thread是国产实时操作系统的典范,我个人的特别喜欢。RT-Thread有很多的BSP可以适配众多的芯片和架构,在本文还是使用最常见的stm32来进行介绍。

​                硬件上我是用了正点原子核RT-Thread联合开发的潘多拉开发板,在本文中没有使用潘多拉的硬件,我比较偷懒的使用了开发板配套的例子去做逆向。

启动

​                我一直相信一句话,不会开发也就不会安全,开发能力决定着安全能力的天花板。在逆向STM32 & RT-Thread的过程中也是这个样子的。我们打开一个bin文件,第一件事就是找到main函数,这个main函数并不是stm32的main函数而是操作系统的main函数。例如在stm32 & keil开发中,RT-Thread使用$Sub$$main调用初始化操作系统,如果是不带操作系统的裸开发,这个函数就是逻辑的main函数了。

​                详细的启动过程可以在https://www.rt-thread.org/document/site/tutorial/quick-start/stm32f103-simulator/stm32f103-simulator/中找到,为了本文的完整,我们复制过来一些代码。

//components.c 中定义
/* re-define main function */
int $Sub$$main(void)
{
    rt_hw_interrupt_disable();
    rtthread_startup();
    return 0;
}

这里面调用了两个函数,第一个函数关闭了中断,开始初始化操作系统。

int rtthread_startup(void)
{
    rt_hw_interrupt_disable();
    /* board level initalization
     * NOTE: please initialize heap inside board initialization.
     */
    rt_hw_board_init();
    /* show RT-Thread version */
    rt_show_version();
    /* timer system initialization */
    rt_system_timer_init();
    /* scheduler system initialization */
    rt_system_scheduler_init();
#ifdef RT_USING_SIGNALS
    /* signal system initialization */
    rt_system_signal_init();
#endif
    /* create init_thread */
    rt_application_init();
    /* timer thread initialization */
    rt_system_timer_thread_init();
    /* idle thread initialization */
    rt_thread_idle_init();
    /* start scheduler */
    rt_system_scheduler_start();
    /* never reach here */
    return 0;
}

rtthread_startup();函数中,进行各个组件的初始化,其他我们不用管,重点看其中的rt_application_init();函数,这个函数用于线程任务的初始化,在其中,我们就可以脱离操作系统代码的范畴,进入到真正的逻辑代码的位置。

操作

​                我们使用潘多拉开发板的例子29_iot_web_server,这个例子复杂程度中等,可以充分的分析各个点。keil编译之后,会的带axf文件和Hex文件,其中axf带有符号表,而hex文件只有基础的组织结构,由于嵌入式的特点,为了节约资源,烧录进芯片里的固件基本都不会带符号表。为了仿造真实情况下拿到的固件,我们使用jlink的工具打开hex文件之后保存成bin文件。之后使用ida pro打开。

​                打开文件之后,正确载入逆向,显示如下:(使用IDA PRO逆向ARM M核心的方法请参考我之前的文章

选中的地址 0x8000495为芯片的上电PC载入地址,找到地址之后,如下:

由于最开始是硬件PC设置,没有软件引用关系,ida pro没有识别,在0x8000494处按C,进行反汇编:

发现可以看到stm32的启动代码,进入函数0x800188:

发现0x800018C处的函数没有识别,依旧按C:

发现识别出来一个函数的跳转,继续跟踪,进入:

发现有四个函数,具体函数的意义是什么,没有符号表不得而知。

这里介绍一个小技巧,我们现在处于上帝模式,我们有axf文件,axf文件中有符号表,并且,这一段程序在操作系统中,所有的stm32都是一样的,我们现在反汇编axf文件,与bin文件互相参照,可以更好的分析启动过程。打开axf文件,找到位置:

选中的函数,也就是第二个函数,是有关操作系统线程的设置,选择进入:

发现又是一堆函数,我们依旧参考axf文件:

第六个函数跳转是任务的设置,选择进入:

在这里我们可以发现任务main函数的设置,进入函数0x802485C

还有两个函数,参考一下axf: 

上面的是任务进入的设置,下面是main函数的逻辑,进入main函数:

按F5转变成伪代码:

这就是任务main函数的逻辑,接下来就可以进行下一步的分析了。

实际上,还有另外一个方法,直接搜索字符串main:

同样可以找到main函数的位置。但是由于任务名称可能修改,从启动代码 逐步分析是最可靠的方法。

没有符号表依然很难受,我在那篇文章中也介绍了恢复符号表的方法,有需要大家可以参考。

STM32 & RT-Thread的逆向入门的更多相关文章

  1. STM32 + RT Thread OS 学习笔记[二]

    串口通讯例程 通过上面的练习,对STM32项目开发有了一个直观印象,接下来尝试对串口RS232进行操作. 1.   目标需求: 开机打开串口1,侦听上位机(使用电脑串口测试软件)发送的信息,然后原样输 ...

  2. STM32 + RT Thread OS 串口通讯

    1.   创建项目 a)   禁用Finsh和console b)   默认情况下,项目文件包含了finsh,它使用COM1来通讯,另外,console输出(rt_kprintf)也使用了COM1.因 ...

  3. STM32 + RT Thread OS 学习笔记[三]

    RTGUI 据说RTGUI是多线程的,因此与RT-Thread OS的耦合度较高,有可能要访问RT-Thread的线程控制块.如果要移植到其它OS,估计难度较大.目前还处于Alpha状态,最终将会包含 ...

  4. STM32 + RT Thread OS 学习笔记[四]

    1.  补注 a)      硬件,打通通讯通道 若学习者购买了学习板,通常可以在学习板提供的示例代码中找到LCD的相关驱动代码,基本上,这里的驱动的所有代码都可以从里面找到. 从上面的示意图可见,M ...

  5. 【Data URL】【RE】【bugku】逆向入门writeup

    在写wp之前先来了解一下Data URL是什么 Data URL 在浏览器向服务端发送请求来引用资源时,一般浏览器都有同一时间并发请求数不超过4个的限制.所以如果一个网页需要引用大量的服务端资源,就会 ...

  6. RT Thread 通过ENV来配置SFUD,操作SPI Flash

    本实验基于正点原子stm32f4探索者板子 请移步我的RT Thread论坛帖子. https://www.rt-thread.org/qa/forum.php?mod=viewthread& ...

  7. STM32学习之路之入门篇

    2006年ARM公司推出了基于ARMV7架构的cortex系列的标准体系结构,以满足各种技术得不同性能要求,包含了A,R,M三个分工明确的系列 其中A系列面向复杂的尖端应用程序,用于运行开放式的复杂操 ...

  8. STM32 LoRaWAN探索板B-L072Z-LRWAN1入门指南

    UM2159用户手册 基于STM32L0的超低功耗LoRa探索套件入门指南 前言 LoRa 探索套件(B-L072Z-LRWAN1)是一款RF探索开发板,采用了Murata公司的LoRa模块CMWX1 ...

  9. Android Native 程序逆向入门(一)—— Native 程序的启动流程

    八月的太阳晒得黄黄的,谁说这世界不是黄金?小雀儿在树荫里打盹,孩子们在草地里打滚.八月的太阳晒得黄黄的,谁说这世界不是黄金?金黄的树林,金黄的草地,小雀们合奏着欢畅的清音:金黄的茅舍,金黄的麦屯,金黄 ...

随机推荐

  1. 加快Chrome网页开启速度

    谷歌浏览器一直是众多大神心中的最爱,但是对于启动速度还是有一些纠结,这里找到一个好方法可以加快一些启动的速度,亲测有效. 1.地址栏输入chrome://flags: 2.启用"覆盖软件渲染 ...

  2. 【WPF学习】第三十九章 理解形状

    在WPF用户界面中,绘制2D图形内容的最简单方法是使用形状(shape)——专门用于表示简单的直线.椭圆.矩形以及多变形的一些类.从技术角度看,形状就是所谓的绘图图元(primitive).可组合这些 ...

  3. ELK同步kafka带有key的Message

    需求 kafka中的message带有key,带有相同key值的message后入kafka的意味着更新message,message值为null则意味着删除message. 用logstash来同步 ...

  4. HDU_1556_线段树

    http://acm.hdu.edu.cn/showproblem.php?pid=1556 直接用了技巧来做. #include<iostream> #include<cstdio ...

  5. Comb结合android开发

    https://blog.csdn.net/qq_29665509/article/details/79272441 参考comb官方文档 https://blog.csdn.net/qq_29665 ...

  6. Go语言实现:【剑指offer】对称的二叉树

    该题目来源于牛客网<剑指offer>专题. 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. Go语言实现: 方法一:递归 / ...

  7. qt creator源码全方面分析(2-10-3)

    目录 Plugin Meta Data 主键 插件描述键 依赖 可选依赖项 测试依赖项 命令行参数 Test.json示例 插件版本说明 Plugin Meta Data 插件的元数据文件是一个JSO ...

  8. Kafka中数据的流向

    1: 多个消费者消费同一个Topic数据相同的数据 2: 多个消费者消费同一个Topic数据不同数据 3: 各个消费者按组协调消费 1: 多个消费者消费同一个Topic数据相同的数据 (1)使用一个全 ...

  9. drf序列化高级、自定义只读只写、序列化覆盖字段、二次封装Response、数据库查询优化(断关联)、十大接口、视图家族

    目录 自定义只读 自定义只写 序列化覆盖字段 二次封装Response 数据库关系分析 断外键关联关系 ORM操作外键关系 ORM四种关联关系 基表 系列化类其他配置(了解) 十大接口 BaseSer ...

  10. CNN目标检测系列算法发展脉络——学习笔记(一):AlexNet

    在咨询了老师的建议后,最近开始着手深入的学习一下目标检测算法,结合这两天所查到的资料和个人的理解,准备大致将CNN目标检测的发展脉络理一理(暂时只讲CNN系列部分,YOLO和SSD,后面会抽空整理). ...