|
本帖最后由 lzwml 于 2016-1-31 20:31 编辑
上报漏洞
上面的代码存在严重栈溢出缺陷。原因在于:
当初为了调试,许多函数都定义 char strout[256],并且函数之间存在调用关系,Keil为STM32F10x系列启动代码里默认分配栈大小为0x400(1K),所以只要存在4个函数调用就完全能造成溢出。
解决方法:定义一个全局变量 char strout[256]供所有函数调用,或者仅在调试模式下定义该变量。
漏洞潜伏原因:
如果代码以-O3方式编译(好像默认建立工程就是这个优化方式),此模式代码运行崩溃时机不一定,因为-O3方式使得某些代码不用消耗栈,【但此时依旧消耗了不少的栈,处于代码崩溃边缘】,但若来了中断,并且中断里有许多函数调用,很容易莫名其妙崩溃。
浮现方法:
将代码以 -O0 方式不优化运行,代码必定崩溃(当然是在我自己的工程),我的工程里调用lc_CheckLicence(),满足if (islic && val > 0) 条件,开始执行里面的内容后程序立马崩溃。
讲解-O3和-O0对函数递归调用的优化方式:
在死循环递归调用里,-O0必定在栈溢出时崩溃,-O3未必,它将函数调用方式改成类似C语言的 goto xx;
ARM指令里
B 以PC指针作为相对寻址,类似 goto,不需要用到栈,速度快,所以可能某些代码被-O3方式优化成 B 指令
BL 将当前PC指针保存到 LR寄存器,压栈SP指针,运行函数代码,需要用到栈
- C代码
- void fun()
- {
- fun();
- }
- -O0 的汇编
- void fun()
- {
- fun()
- BL fun // cal 到上面两行
- }
- -O3的汇编
- void fun()
- {
- fun()
- B xxx // jump to 到上面两行
- }
复制代码
|
|