C语言局部常量与全局常量
局部常量
是编译器限制局部常量无法修改 编译器发现左值为 const 修饰的变量则抛出错误
- 局部变量和局部常量存储在运行线程栈区
- 栈区内存属性为可读可写
结合以上信息得出 局部常量也可以修改。
通过指针修改局部常量
/* 通过以下代码就能实现修改局部变量 */
const int a = 10; // 定义局部变量
int* p = &a;
*p = 20;
#include <stdio.h>
int main() {
// 局部常量
const int HP = 10;
// 局部常量存储在栈区 栈区内存默认是可读可写
// HP = 10
// 编译器限制
/* 修改局部常量方法一 */
// int* p = &HP;
// *p = 20;
// printf("%d", HP);
/* 修改局部常量方法二 */
_asm {
mov eax, 0x64
mov dword ptr[ebp - 8], eax
}
printf("%d", HP);
return 0;
}
全局常量
内存保护属性
- 全局常量对应内存地址属性为只读 (ONLY READ)
- 只读内存尝试写入时会发生异常
- 通过API修改对应内存属性为可读可写 (PAGE_READWRITE)
修改内存属性: 如下代码
#include <stdio.h>
#include <Windows.h>
const int g_num = 1;
int main() {
/*
函数原型
BOOL VirtualProtect(
[in] LPVOID lpAddress, 修改内存地址
[in] SIZE_T dwSize, 修改内存大小
[in] DWORD flNewProtect, 修改内存属性
[out] PDWORD lpflOldProtect 默认内存属性
);
*/
// 默认数据
DWORD dwOld = 0;
// 修改属性
VirtualProtect(&g_num, sizeof(g_num), PAGE_READWRITE, &dwOld);
int* p = &g_num;
*p = 100;
// 恢复属性
VirtualProtect(&g_num, sizeof(g_num), dwOld, &dwOld);
return 0;
}
物理页属性探测
如下代码
#include <stdio.h>
#include <windows.h>
// 全局常量 -> 内存属性只读(ONLY READ)
const int g_num = 1;
int main() {
// 0x%016llx 可能把%x替换成0x%016llx
printf("Addr -> %x Data -> %d", &g_num, g_num);
system("pause");
int* p = g_num;
*p = 0x100;
printf("Addr -> %x Data -> %d", &g_num, g_num);
system("pause");
return 0;
}
操作过程
-
双机内核调式环境
-
挂靠指定进程
第一步
Break

第二步
!process 0 0 ProcessName
第三步
.process /i Kprocess切换进程

上如所示挂靠成功
-
获取对应物理页属性
!pte VirtualAddress
-
修改RW位
PTE at FFFFF68000008BD8
contains A46000006CCD4025

eq FFFFF68000008BD8 a4600000`6ccd4027

完成测试
文章讲述了C语言中的局部常量和全局常量的概念,强调了局部常量虽然在栈区默认可读可写,但可以通过指针修改;而全局常量内存属性为只读,需使用API如VirtualProtect进行修改。还介绍了物理页属性探测的过程。
929

被折叠的 条评论
为什么被折叠?



