const 局部常量(栈上)突破限制
核心原理
- 内存位置:const修饰的局部常量存放在栈区,栈内存属性:可读、可写
- const 的本质:仅编译器层面的语法检查,不是硬件 / 内存读写保护
- 差异:修改局部常量编译器拦截;指针解引用修改内存可以绕过编译器检查
⚠️注意:全局const常量放在只读段 (.rdata),这种方法修改会直接程序崩溃,和栈上局部 const 不是一回事!
代码示例
c
#include <stdio.h>
int main(void)
{
int a = 0;
const int b = 0; // 栈上局部const常量
a = 1; // ✅正常修改普通局部变量
// b = 2; // ❌编译报错:表达式必须是可修改的左值
int* p = &b; // 取const常量地址,转成普通int指针
*p = 2; // 通过指针修改栈内存,绕过编译器const检查
printf("a = %d\n", a);
printf("b = %d\n", b); //b=2
printf("*p = %d\n", *p);
return 0;
}
汇编对照(x86)
c
; int a = 0
mov dword ptr [ebp-0Ch],0
; const int b = 0
mov dword ptr [ebp-18h],0
; *p = 2 指针修改
mov eax,dword ptr [ebp-10h]
mov dword ptr [eax],2
● 普通变量、栈 const 常量初始化汇编指令完全一样,只是栈偏移不同
● 编译器不会生成任何保护内存的硬件指令,仅在编译阶段拦截直接赋值
重点结论
- 局部const常量:栈内存可写,仅编译器语法限制,指针可修改
- 全局const常量:放在只读段,内存硬件保护,指针修改触发访问异常崩溃
- 工程规范:不推荐这种写法,破坏const语义,可读性差,属于逆向底层研究技巧,正式项目禁止使用
区分
| 类型 | 存放位置 | 能否用指针修改 |
|---|---|---|
| 普通局部变量 | 栈区 | ✅ 可以 |
| const 局部常量 | 栈区 | ✅ 可以(仅编译器拦截直接赋值) |
| const 全局常量 | .rdata 只读段 | ❌ 修改直接崩溃 |