使用sprintf时溢出咋会影响到变量的值
关于第一个问题,这其实只是 C 语言的基础问题,查看相关文档可解决。sprintf 本身不是安全的,它会无条件往第一个参数的地址写数据,无论这块数据空间是谁的。当然,在格式化串的时候也可能发生问题只是概率较低,目前想来可能有问题的就这两处,首先当然你应当去找 Strline3 的责任。关于第二个问题,其实用 Linux 的话,标准库函数直接 man 就好了。不行去问问 stackoverflow 也是好的,顺带提高英语读写技能。顺便说一下:也许会有很多人说你这程序写得不好,全局变量乱飞什么的。这其实也是事实,只不过很多时候程序能用,没太多人去纠结这些细节。但你现在程序有问题了,再来看的时候,会发现你这个函数里面冒出来的变量好像全是全局量,这对你查问题其实非常不利。
■网友
如果你的程序是运行在x86的windows的话,那么sprintf用的是cdecl这个calling convention。sprintf要求第一个参数是缓冲区的指针,而且他在输入的时候是不检查缓冲区的大小的。在这里推荐使用VC++的sprintf_s函数。如果你的StrlineX是一个数组,不管是全局变量也好,函数的局部变量也好(这个更危险),那StrlineX的“后面”肯定是别的变量了。于是如果你提供给sprintf函数的缓冲区的尺寸不够,那他就会把你的东西慢慢覆盖到你接下来的所有变量里面。也就是说,如果你这么声明的话:char a;char b;char c;在某些编译选项下面,\u0026amp;a==\u0026amp;b, \u0026amp;a==\u0026amp;c这种情况是会出现的。VC++在debug下面会在变量中间放(通常是12个字节的)某些值,退出函数的时候他会检查一下这些值是不是被改写了,如果是证明你搞错了什么事情,就挂了。这是release没事但是debug有事的其中一种常见原因——因为release通常没有检查,而且函数的本地变量用完即弃,刚好你也没有写得太远。
■网友
1. 关于第一个问题:ConstMode是个全局变量,它在进程的地址空间中属于数据区。对于sprintf函数,第一个参数是个指针,指向一个缓冲区,存入输出的内容。结合你的程序逻辑和执行情况,排除ConstMode被并发地从其它程序流程修改,那么唯一的可能就是Strline3在紧临数据区中ConstMode的地方,导致输出到Strline3这个缓冲区后,超出限制,继续覆盖后续的本来属于ConstMode的内存区域。(我猜想很有可能ConstMode和Strline3这两个变量都是定义为全局变量,并且,在程序链接后,Strline3分配在ConstMode地址之前,导致了这种可能性,如果你能把程序定义这两个变量的部分给出,更有助于分析)2. 关于第二个问题:1.了解程序进程地址空间概念,知道全局变量,临时变量的区别是如何体现在进程空间上的。 这对于了解缓冲区溢出,堆溢出的原理很重要。你这个程序的原因就是,缓冲区长度分配有限 ,这个缓冲区目前看很有可能是定义为全局变量(即在数据段),它的长度在程序开始时就固定 了,这就百分百可以触发缓冲区溢出问题。这显然就不是合理的做法,更合理的做法是根据要输 出数据的长度,动态地在堆区域分配(malloc或new). 如果对进程地址空间有了概念,很多这种问题能避免,或者帮助分析。某一操作系统书籍中关于进程内存空间章节的描述,编译,链接的一些知识,《程序员的自我修养—链接、装载与库》是不错的入门书2. 学习必要的汇编知识,了解函数的栈帧的结构,这对于分析缓冲区溢出问题也是必备的。(不 过,你的例子并不是在栈区的溢出,而是在数据区的溢出) 任一本汇编书籍中的关于函数部分的论述章节
■网友
《深入理解计算机系统》绝对是你想要的那一本:深入理解计算机系统(原书第2版) (豆瓣)
■网友
sprintf不会检查缓冲区长度,在一些编译选项下会造成超过长度bug,也就是你提出的问题,如果是windows下vc++的话,尽量用安全函数,sprintf_s
推荐阅读
- 『先进』长江流域最先进洗舱站在宁投运 油可分离回收,水能循环使用
- 汽车|冬天怎样让车内温度快速升高?座椅加热的最佳使用方式二,外循环的作用总结
- 汽车|迈凯伦Artura不再使用迈凯伦祖传V8引擎了?
- python的html5lib这个库咋使用啊我在网上也没有找到相关文档
- win7中本地连接跟无线网卡同时使用时是怎么样的模式
- 可不可能利用网盘的秒传功能使用伪造的MD5(或其他信息)值进行文件分享
- 贾玲|贾玲爆肥后现身工作室,脸大到肉都溢出来了,身体健康引担忧
- 为啥很多企业给用户发邮件会使用noreply/no-reply@xx.xx的邮箱
- win10激活的问题
- 全网通的mate8能不能插美国手机卡,在美国使用
