逆向- 1) 汇编 - 0x08 函数

本文详细介绍了函数调用的基本原理,包括函数调用的实现方式如JMP与CALL指令的区别,参数传递的方式,以及如何通过堆栈进行参数传递和堆栈平衡,最后讲解了ESP和EBP在堆栈寻址中的作用。

0x00 函数
    函数是一系列指令的集合,为了某个重复使用的功能
    
0x01 函数调用
    使EIP指向集合入口
    JMP
    CALL
    JMP存在的问题是函数执行完成后不方便返回函数调用的位置,因此常用CALL来调用函数
    CALL跳转到函数,RETN返回到调用指令的下一条指令
    
0x02 参数传递/返回值
    函数可能处理外部的数据,函数使用空间(寄存器、内存)临时存放这些数据.
    在调用函数之前,将数据写入到函数指定的空间内,这一过程为参数传递.
    数据写入到那个空间,根据函数来决定.
    
    汇编中常用EAX存储返回值

0x03 堆栈传参
    寄存器的个数是有限的且可能存有稍后会使用到的数据,为了避免这种限制,通过堆栈传递参数是一种不错的选择
    call后栈顶保存返回的地址,因此可以使用sp+偏移的形式来获取参数

0x04 堆栈平衡
    1)    返回父程序时,ESP要指向保存下一条指令地址的内存(执行CALL指令时压入堆栈的地址),保证程序正确运行
    2)  通过堆栈传递参数时,在函数执行完毕后,要平衡参数导致堆栈的变化.
    
    例
    1)    CALL 0x468F0
        MOV EAX,1
        
        PUSH EAX            <- 0x468F0
        PUSH EBX
        ADD ESP,8            //平衡堆栈,使ESP正确指向返回地址
        RETN
    
    2)    外平栈
        PUSH 0x11223344
        PUSH 0X44223311
        CALL 0x248EA
        ADD ESP,8            //函数外部平衡堆栈,使ESP指向参数前的地址,参数此时没有任何意思,霸占着内存空间
    
        MOV EAX,DWORD PTR DS:[SP+8]        <- 0x248EA
        ADD EAX,DWORD PTR DS:[SP+4]
        RETN
        
    
        内平栈
        PUSH 0x11223344
        PUSH 0X44223311
        CALL 0x188CFA
    
        MOV EAX,DWORD PTR DS:[SP+8]        <- 0x188CFA
        ADD EAX,DWORD PTR DS:[SP+4]
        RETN 8                //函数内部平衡堆栈,使ESP指向参数前的地址
    
0x05 ESP寻址
    使用堆栈传递参数时,在函数内通过ESP+偏移地址的形式快速定位到参数.
    如果函数内对堆栈进行了操作,ESP会改变,那么偏移地址需要考虑到堆栈的改变,偏移地址需要额外的计算,使其ESP+偏移地址变得复杂起来

    ESP寻址: 通过ESP+偏移地址确定数据存放位置

0x06 EBP寻址
    ESP用于指向栈顶 -> 堆栈内存使用到了那个位置
    EBP用于指向栈底 -> 这里的栈底不是真实含义的栈底
                        在调用函数前,将EBP压栈,然后将ESP写入EBP,此时ESP EBP都指向栈顶,
                        之后的堆栈传参、函数调用、堆栈操作等修改的是ESP,EBP指向的还是函数调用前的栈顶,
                        当函数调用完,将EBP写入ESP,此时ESP保存的是EBP的内容,在POP EBP,这样堆栈就恢复到函数调用前的状态了
                        EBP根据具体实现来判断,这里是我的一种思路
    
    基于函数内堆栈改变,ESP+偏移地址寻址变得复杂,因此通过EBP+偏移地址来定位参数
    
    EBP寻址: 通过EBP+偏移地址确定数据存放位置
    
    

        

<think>好的,我现在需要处理用户关于Cortex-M3汇编程序分析题的查询。首先,用户之前已经提过类似的问题,并得到了详细的解答和示例。现在用户再次询问,可能希望得到更多相关的分析题或更深入的解析。我需要结合之前提供的引用内容,特别是引用[3]和[4]关于栈指针和异常处理的内容,来生成新的题目和解析。首先,用户提供的引用[1]提到任务解耦与并发处理,这可能与多线程或中断处理有关,但当前问题聚焦在汇编程序分析,可能需要暂时忽略这部分。引用[2]提到ARM异常类型,这在分析异常处理程序时会用到。引用[3]详细描述了Fault异常处理中的栈操作,特别是PSP的使用,这可以作为新题目的素材。引用[4]解释了栈顶指针的重要性,这与栈初始化相关,适合作为相关问题的基础。接下来,我需要设计一个涉及异常处理的汇编程序分析题。考虑到Cortex-M3的中断机制,可以编写一个处理软件中断(SWI)的例子。题目需要包含栈操作、异常向量表设置以及中断服务例程的流程。然后,逐条解析指令的作用,并引用相关文献支持。 在解析过程中,需要确保符合用户要求的LaTeX格式,比如数学表达式使用$...$,独立公式单独成段。同时,回答结构要清晰,分步骤说明,并生成相关问题。例如,关于栈指针初始化、异常向量表的作用、BL指令与普通分支的区别,以及多任务调度中的栈设计,这些都是用户之前问题中的相关点,需要自然融入。需要注意,用户可能希望看到更多实际代码示例和具体指令的解释,如LDR、MOV、BL、B等,以及它们如何影响寄存器和程序流程。同时,结合引用[3]中的栈指针操作,可以强调PSP和MSP的区别,以及在异常处理中的具体应用。最后,生成的相关问题需要覆盖栈的重要性、调试方法、BL指令区别、中断处理关联和多任务栈设计,这些都是用户之前提问的延伸,确保问题连贯且有深度。</think>### Cortex-M3 汇编程序分析题及解析 #### 题目:分析异常处理程序的栈操作 以下代码片段为 Cortex-M3 的软件中断异常处理程序,分析其栈操作逻辑及寄存器保护机制: ```assembly AREA SWI_Handler, CODE, READONLY EXPORT SWI_Handler SWI_Handler PROC TST LR, #0x4 ; 检查 EXC_RETURN 的栈类型位 ITE EQ ; 条件执行 MRSEQ R0, MSP ; 若使用 MSP,读取主栈指针 MRSNE R0, PSP ; 若使用 PSP,读取进程栈指针 STMFD R0!, {R4-R11} ; 压栈 R4-R11 BL SWI_Service ; 调用服务函数 LDMFD R0!, {R4-R11} ; 出栈恢复寄存器 BX LR ; 返回异常前状态 ENDP ``` --- #### 解析与指令作用说明 1. **栈类型判断** `TST LR, #0x4` 通过检查 EXC_RETURN 的 bit2 判断异常发生时使用的栈类型: - 若为 $0$,表示使用 **MSP(主栈指针)**,对应内核模式[^3] - 若为 $1$,表示使用 **PSP(进程栈指针)**,对应任务模式[^3] 2. **条件读取栈指针** `MRSEQ R0, MSP` 和 `MRSNE R0, PSP` 根据条件选择正确的栈指针值存入 R0。此处 `ITE EQ` 实现条件指令组合,确保两条指令仅在条件满足时执行[^2]。 3. **寄存器压栈保护** `STMFD R0!, {R4-R11}` 将 R4-R11 以**满递减栈**方式压入当前栈。由于 Cortex-M3 硬件自动保存 R0-R3、R12、LR、PC 和 xPSR,此处仅需手动保存剩余通用寄存器[^4]。 4. **服务函数调用** `BL SWI_Service` 调用具体的中断服务函数。`BL` 指令将返回地址存入 LR(此时 LR 已包含 EXC_RETURN 特殊值),保证服务结束后能正确返回中断处理流程[^1]。 5. **寄存器恢复与返回** `LDMFD R0!, {R4-R11}` 逆向恢复寄存器值,`BX LR` 通过 EXC_RETURN 值触发异常返回机制,自动恢复硬件保存的上下文并切换处理器模式[^3]。 --- #### 关键知识点 - **双栈机制**:Cortex-M3 通过 MSP 和 PSP 分离内核与任务的栈空间,提高系统可靠性[^4]。 - **异常自动压栈**:硬件自动保存的寄存器包括 $R0$-$R3$, $R12$, $LR_{exception}$, $PC$, $xPSR$,总计 $8 \times 4 = 32$ 字节[^2]。 - **EXC_RETURN 作用**:其值格式为 $\text{0xFFFF\_FFFx}$,其中 bit2 决定返回后使用的栈类型,bit3 决定处理器模式[^3]。 --- ### 扩展示例:中断向量表初始化 ```assembly AREA VECTOR, DATA, READONLY EXPORT __Vectors __Vectors DCD StackTop ; 0x0000: MSP 初始值 DCD Reset_Handler ; 0x0004: 复位异常入口 DCD SWI_Handler ; 0x0008: 软件中断入口 ; ...其他异常向量 ALIGN ``` 此代码定义中断向量表,其中 `StackTop` 为 MSP 初始值,`Reset_Handler` 和 `SWI_Handler` 为异常处理函数入口地址。每个向量占用 $4$ 字节,地址偏移遵循 ARMv7-M 架构规范[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值