使用这个函数来模拟数组越界:
void buf_overflow(int n, char val)
{
volatile char buf[5];
volatile int a = 0x55;
buf[0] = 0x5a;
a++;
buf[n] = val;
myput_s_hex("buf[0] = ", buf[0]);
myputs("\n");
myput_s_hex("a is ", a);
myputs("\n");
}破坏其它变量
main 函数中调用:
buf_overflow(8, 'A'); i.buf_overflow
buf_overflow
0x08001e3c: b50e .. PUSH {r1-r3,lr} ; 只是为了分配空间,跟r1-3里面的值无关
0x08001e3e: 225a Z" MOVS r2,#0x5a
0x08001e40: f88d2000 ... STRB r2,[sp,#0] ; 写入[0]
0x08001e44: 2256 V" MOVS r2,#0x56
0x08001e46: 9202 .. STR r2,[sp,#8] ; 写入[8]
0x08001e48: f80d1000 .... STRB r1,[sp,r0]
0x08001e4c: f89d1000 .... LDRB r1,[sp,#0]
0x08001e50: a006 .. ADR r0,{pc}+0x1c ; 0x8001e6c
0x08001e52: f000f8df .... BL myput_s_hex ; 0x8002014
0x08001e56: a008 .. ADR r0,{pc}+0x22 ; 0x8001e78
0x08001e58: f000f906 .... BL myputs ; 0x8002068
0x08001e5c: a007 .. ADR r0,{pc}+0x20 ; 0x8001e7c
0x08001e5e: 9902 .. LDR r1,[sp,#8]
0x08001e60: f000f8d8 .... BL myput_s_hex ; 0x8002014
0x08001e64: a004 .. ADR r0,{pc}+0x14 ; 0x8001e78
0x08001e66: f000f8ff .... BL myputs ; 0x8002068
0x08001e6a: bd0e .. POP {r1-r3,pc}
破坏返回地址
buf_overflow(12, 'B');索引变为了12,就会破坏返回地址。
1、打断点

2、根据 SP 查看内存

3、发现 LR 的值被修改了

08001F42
1000000000000001111101000010
bit 0 为 0,ARM指令,但是只cortex-m是thumb指令,程序崩溃,进入 HardFault_Handler 异常处理函数
不知道为什么keil调试器总是崩溃
上面的是从前往后推的,制作错误,看现象。
如果是看到了错误,怎么知道哪里出错呢?
1、出错时,查看硬件自动保存的栈帧

2、发生错误时,栈帧里面的PC是出现错误的语句

3、通过搜索,发现代码是存在的。但是毫不相关,莫名奇妙的,一个正确的函数为什么会出错。

这种问题后面解决
那如果是几数呢,就是bit0为1,这样找不到语句,还是会出错。
buf_overflow(12, 'A');还有一种情况,凑巧了,跳转的语句是合法的地址,虽然能正常运行,但是项目的逻辑是错的。
可能出现循环。
如果那个值再大一点,破坏其他函数的栈,会更严重的破坏,导致程序在某个地方一直失败,但找不到原因。