逆向-#define和const的区别

逆向-#define和const的区别,第1张

逆向-#define和const的区别

        在实际中,使用const定义的栈变量,最终还是一个变量,只是在编译期间对语法进行了检查,发现代码有对const修饰的变量存在直接修改行为则报错.

        被const修饰过的栈变量本质上是可以被修改的.我们可以利用指针获取const修饰过的栈变量的地址,强制将const属性修饰去掉,就可以修改对应的数据内容了,如以下代码

#include 

int main()
{
    const int  n1 = 5;
    int* p = (int*)&n1;
    *p = 6;
    int n2 = n1;
    return 0;
}
对应的反汇编
push ebp                     //
mov ebp,esp                  //
sub esp,0ch                  // 开辟栈帧
mov dword ptr[ebp-4],5       //n1 = 5
lea eax,[ebp-4]         
mov [ebp-8],eax              //p = (int*)&n1
mov ecx,[ebp-8]    
mov dword ptr[ecx],6         //*p = 6
mov dword ptr[ebp-0ch],5     //n2 = n1
xor eax,eax
mov esp,ebp
pop ebp
retn

在上述代码中,由于const修饰的变量n1被赋值一个数字常量5,编译器在编译过程中发现n1的初始值是可知的,并且被修饰为const.之后所有使用n1的地方都被替换为这个可预知的值,故

int n2 = n1;对应的汇编代码并没有将n1赋值给n2,而是用常量值5代替.如果n1初始化为一个未知的值则编译器不会做此优化

在上述代码实例中指针确实可以将n1的值修改成6

#defineconst在编译期间查找替换在编译期间检查const修饰的变量是否被修改由系统判断是否被修改由编译器限制修改字符串定义在文件的只读数据区,数据常量编译为立即数寻址方式,成为二进制代码的一部分根据作用域决定所在的内存位置和属性

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5635458.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存