CTF竞赛题解之stm32逆向入门
字数 1158 2025-08-12 11:33:49

STM32逆向分析入门教程

一、STM32逆向基础

1. STM32固件文件格式

Intel HEX文件是STM32逆向中常见的固件格式,包含以下关键信息:

  • 程序加载地址:通常为0x08000000
  • 程序入口地址:可通过文件中的:04000005记录获取
  • 文件结束标记::00000001FF

2. STM32内存布局

STM32F103C8T6芯片的内存布局如下:

  • Flash Memory: 0x8000000 ~ 0x801FFFF (128KB)
  • SRAM: 0x20000000 ~ 0x20004FFF (20KB)
  • Peripherals: 0x40000000 ~ 0x40023400

二、IDA逆向分析步骤

1. IDA初始配置

  1. 选择处理器类型:ARM小端
  2. 选择架构:ARMv7-M
  3. 设置加载地址为0x8000000

2. 定位程序入口

STM32程序入口可通过以下方式定位:

  1. 查找RESET中断向量地址:0x8000004
  2. 将该地址处的数据转换为4字节形式
  3. 获取RESET处理函数地址(如0x8000101)
  4. 跳转到该地址并按C键生成代码

3. 修复中断向量表

使用IDApython脚本修复中断向量表:

for i in range(0x8000000,0x80000eb,1):
    del_items(i)
for i in range(0x8000000,0x80000eb,4):
    create_dword(i)

4. 添加缺失的内存段

在IDA中手动添加缺失的内存段:

  1. 选择"Edit" -> "Segments" -> "Create Segment"
  2. 添加Flash、SRAM和Peripherals段

三、中断处理函数分析

1. EXTI中断处理函数

STM32的外部中断处理函数通常位于中断向量表中,例如:

  • EXTI_4中断处理函数地址可通过中断向量表找到
  • 函数功能通常包括:
    • 设置中断/事件线(如EXTI_LINE = 16)
    • 处理按键逻辑
    • 更新状态变量

2. 中断处理函数示例

int EXTI_4() {
    int result; // r0
    EXTI_LINE = 16;
    switch ( sum ) {
        case 1:
            unk_20000006 = 116;
            return sum++ + 1;
        case 2:
            unk_20000010 = 95;
            return sum++ + 1;
        case 4:
            unk_2000000E = unk_20000001;
            return sum++ + 1;
        default:
            result = 0;
            sum = 0;
            break;
    }
    return result;
}

四、密码锁题目分析

1. 题目描述

  • 设备:STM32F103C8T6 MCU密码锁
  • 按键:4个按键(1,2,3,4)对应GPIO_PA1-PA4
  • 输出:通过串口(PA9-TX)发送flag
  • flag格式:SCTF{正确的按键密码}

2. 解题步骤

  1. 分析中断处理函数中的按键处理逻辑
  2. 跟踪状态变量(sum)的变化
  3. 根据case语句确定按键顺序
  4. 组合得到正确密码:1442413

五、进阶题目分析

1. 加密函数逆向

_BYTE *sub_8000314() {
    _BYTE *v0; // r4
    char *v1; // r5
    int v2; // r6
    char v3; // t1
    
    v0 = (_BYTE *)sub_80003F0(48);
    v1 = &byte_8000344;
    v2 = 0;
    while ( v2++ != 0 ) {
        v3 = *v1++;
        *v0++ = (v3 ^ 0x1E) + 3;
        sub_8000124(v1);
    }
    return v0;
}

2. 解密脚本

li = [0x7D, 0x77, 0x40, 0x7A, 0x66, 0x30, 0x2A, 0x2F, 0x28, 0x40, 
      0x7E, 0x30, 0x33, 0x34, 0x2C, 0x2E, 0x2B, 0x28, 0x34, 0x30, 
      0x30, 0x7C, 0x41, 0x34, 0x28, 0x33, 0x7E, 0x30, 0x34, 0x33, 
      0x33, 0x30, 0x7E, 0x2F, 0x31, 0x2A, 0x41, 0x7F, 0x2F, 0x28, 
      0x2E, 0x64]
      
print(''.join(chr((i ^ 0x1E) + 3) for i in li))

六、参考资料

  1. STM32芯片手册:https://www.alldatasheet.com/
  2. STM32中文参考手册V10.pdf
  3. 中断向量表位置:0x8000004固定地址

七、总结

STM32逆向分析的关键点:

  1. 正确配置IDA的内存布局和处理器类型
  2. 通过中断向量表定位程序入口
  3. 分析中断处理函数中的业务逻辑
  4. 跟踪关键状态变量的变化
  5. 必要时编写解密脚本还原加密数据
STM32逆向分析入门教程 一、STM32逆向基础 1. STM32固件文件格式 Intel HEX文件是STM32逆向中常见的固件格式,包含以下关键信息: 程序加载地址:通常为0x08000000 程序入口地址:可通过文件中的 :04000005 记录获取 文件结束标记: :00000001FF 2. STM32内存布局 STM32F103C8T6芯片的内存布局如下: Flash Memory: 0x8000000 ~ 0x801FFFF (128KB) SRAM: 0x20000000 ~ 0x20004FFF (20KB) Peripherals: 0x40000000 ~ 0x40023400 二、IDA逆向分析步骤 1. IDA初始配置 选择处理器类型:ARM小端 选择架构:ARMv7-M 设置加载地址为0x8000000 2. 定位程序入口 STM32程序入口可通过以下方式定位: 查找RESET中断向量地址:0x8000004 将该地址处的数据转换为4字节形式 获取RESET处理函数地址(如0x8000101) 跳转到该地址并按C键生成代码 3. 修复中断向量表 使用IDApython脚本修复中断向量表: 4. 添加缺失的内存段 在IDA中手动添加缺失的内存段: 选择"Edit" -> "Segments" -> "Create Segment" 添加Flash、SRAM和Peripherals段 三、中断处理函数分析 1. EXTI中断处理函数 STM32的外部中断处理函数通常位于中断向量表中,例如: EXTI_ 4中断处理函数地址可通过中断向量表找到 函数功能通常包括: 设置中断/事件线(如EXTI_ LINE = 16) 处理按键逻辑 更新状态变量 2. 中断处理函数示例 四、密码锁题目分析 1. 题目描述 设备:STM32F103C8T6 MCU密码锁 按键:4个按键(1,2,3,4)对应GPIO_ PA1-PA4 输出:通过串口(PA9-TX)发送flag flag格式:SCTF{正确的按键密码} 2. 解题步骤 分析中断处理函数中的按键处理逻辑 跟踪状态变量(sum)的变化 根据case语句确定按键顺序 组合得到正确密码:1442413 五、进阶题目分析 1. 加密函数逆向 2. 解密脚本 六、参考资料 STM32芯片手册:https://www.alldatasheet.com/ STM32中文参考手册V10.pdf 中断向量表位置:0x8000004固定地址 七、总结 STM32逆向分析的关键点: 正确配置IDA的内存布局和处理器类型 通过中断向量表定位程序入口 分析中断处理函数中的业务逻辑 跟踪关键状态变量的变化 必要时编写解密脚本还原加密数据