首页
社区
课程
招聘
[讨论]{已解决}C语言初始化话的问题,问号的都是不明白,麻烦大家了
发表于: 2008-10-23 20:30 3950

[讨论]{已解决}C语言初始化话的问题,问号的都是不明白,麻烦大家了

2008-10-23 20:30
3950
1:    #include "stdio.h"
2:    void main()
3:    {
0040D6F0 55                   push        ebp//保存堆栈指针
0040D6F1 8B EC                mov         ebp,esp//esp放入ebp,esp寄存器另作他用
0040D6F3 83 EC 48             sub         esp,48h//
0040D6F6 53                   push        ebx
0040D6F7 56                   push        esi
0040D6F8 57                   push        edi//保护一些寄存器
0040D6F9 8D 7D B8             lea         edi,[ebp-48h]//edi指向当前堆栈顶
0040D6FC B9 12 00 00 00       mov         ecx,12h//???????????
0040D701 B8 CC CC CC CC       mov         eax,0CCCCCCCCh//???????????????
0040D706 F3 AB                rep stos    dword ptr [edi]
4:        int* x;
5:        int m;
6:        x=&m;
0040D708 8D 45 F8             lea         eax,[ebp-8]
0040D70B 89 45 FC             mov         dword ptr [ebp-4],eax
7:    }
0040D70E 5F                   pop         edi
0040D70F 5E                   pop         esi
0040D710 5B                   pop         ebx
0040D711 8B E5                mov         esp,ebp
0040D713 5D                   pop         ebp
0040D714 C3                   ret
#####################################
源程序: #include "stdio.h"
    void main()
    {
         int* x;
       int m;
       x=&m;
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 197
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
其实我也不懂撒
rep stos    dword ptr [edi]  
DEORD是4字节
所以48h/4 =12
rep就是用0CCCCCCCCh初始化堆栈
2008-10-23 21:06
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
楼主潜水真厉害....
2008-10-23 21:16
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
不是我潜水厉害,是我一直没有学习汇编,论坛上的东西看不懂,现在在学汇编程序设计还有计算机组成,感觉能看懂一些了,于是乎,拿C语言来开刀。。。。
2008-10-23 21:51
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
5
很好,这种学习精神很好,梁肇新就特别”鼓吹“程序员从汇编一级,从机器的角度看待程序。
好,我来说说你不明白的地方。
直接写注释中了,自己看吧。我就是在你加问号的地方写了。
另外你原来的不太恰当的注释我给你更正了。

好好学习,祝你进步。希望对方你有帮助。

1:    #include "stdio.h"
2:    void main()
3:    {
0040D6F0 55                   push        ebp           //保存堆栈指针
0040D6F1 8B EC                mov         ebp,esp       //这两句是标准的函数入口点,是作用是建立一个用ebp作访问基址的标准堆栈帧结构。
                                                        //如果索引值为正,访问的是函数的参数,为负为局部变量,如 ss:[ebp + 8]就是访问函数的第一个参数
0040D6F3 83 EC 48             sub         esp,48h       //这个是在堆栈帧上为局部变量分配空间,可以看到编译器共分配了0x48个字节给局部变量(包括保存中间结果的临时变量)
0040D6F6 53                   push        ebx
0040D6F7 56                   push        esi
0040D6F8 57                   push        edi             //保护一些寄存器
0040D6F9 8D 7D B8             lea         edi,[ebp-48h]   //edi指向当前堆栈顶
0040D6FC B9 12 00 00 00       mov         ecx,12h         //这是全部局部变量所占用的存储空间,以DWORD为单位,所以是0x48 / 4 = 0x12
0040D701 B8 CCCCCCCC          mov         eax,0CCCCCCCCh  //这是将堆栈中局部变量存储区全部用0xCC填充,这种初始化是DEBUG模式下编译才会生成的
                                                          //至于为什么用0xCC,这个说过很多次了,因为0xCC是int3指令的机器码
                                                          //这样就可以在程序有漏洞,比如因溢出而”飞“到数据区执行时就会触发调试异常
                                                          //而调试器可以捕获该异常从而帮助程序员除错。
0040D706 F3 AB                rep stos    dword ptr [edi] // 上面已经说过了,用调试模式的值初始化局部变量
4:        int* x;
5:        int m;
6:        x=&m;
0040D708 8D 45 F8             lea         eax,[ebp-8]
0040D70B 89 45 FC             mov         dword ptr [ebp-4],eax
7:    }
0040D70E 5F                   pop         edi
0040D70F 5E                   pop         esi
0040D710 5B                   pop         ebx
0040D711 8B E5                mov         esp,ebp
0040D713 5D                   pop         ebp
0040D714 C3                   ret
#####################################
源程序: #include "stdio.h"
    void main()
    {
         int* x;
       int m;
       x=&m;
}
2008-10-24 02:37
0
雪    币: 247
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
rep stos    dword ptr [edi] //这是个循环指令 初始化刚才分配的空间
2008-10-24 09:42
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
谢谢5楼,其实我只是对这句话有点迷惑~
0040D701 B8 CCCCCCCC          mov         eax,0CCCCCCCCh
那么在程序开始定义指针时,其实指针指向的是0CCCCCCCCh
如果没有初始化,就会出现问题。
那么0CCCCCCCCh
中放的是什么呢?
2008-10-24 15:53
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
8
0xCCCCCCCC是示所有未初始化的变量由编译器提供的用来辅助调试的默认值。

不管变量是值类型还是指针类型。

如果你真的敢引用没有赋值的指针,那么程序会异常退出(运行时刻)或异常被调试器捕获(调试时刻)

如果你非要知道0xCCCCCCCC处有什么内容,可以告诉你,一般那里什么都没有。
这个地址位于内核空间,但一般情况下内核空间是从低端和高端两边开始分配的,也就是说0x80000000往上的一段空间和0xC0000000往下的一段内核空间是被使用的。可以用冰刃查看一下内核模块,从他们的基址就知道一些端倪了。

关于NT内核空间的布局,可以看看相关资料,我说得也不一定对。

系统引导时,一些必不可少的核心模块加载到内核低端,而之后加载模块,如设备驱动等,則从高端开始分配内存。而像0xCCCCCCCC这样的地址,一般都是没有映射过的内存空间。

还有,0xCC是DEBUG模式下编译才会有的,在release模式下,编译器不会对局部变量空间进行填充,所以没有初始化的变量,一般都认为初始值是“随机值”,准确地说是未知的值,切不可以为是0xCCCCCCCC。

而且,写一般的应用程序,不用跟内核空间打交道的。
只有做内核开发,如驱动、过滤等,才需要用到内核的知识。
2008-10-24 17:14
0
雪    币: 197
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
从OD的行为上看
当CALL过程中遇到CC  INT3时  相当于一个RET
2008-10-27 23:03
0
游客
登录 | 注册 方可回帖
返回
//