技术解析

Linux 下 c 程序的内存问题
0
2021-06-28 04:57:58
idczone
最近碰到了个进程异常中止的问题,core 文件的 gdb 结果看来好像函数的代码区内存被滥用了,类似于如下
(gdb) disass /mr Delete
Dump of assembler code for function Delete():
151 {
→. 0x556ec6b0 <+0>:. 00. 00. add. %al,(%eax)
0x556ec6b2 <+2>:. 00 00. add. %al,(%eax)
...
}
之后的值都是 0x00,统计了下前后总共有 4096 字节的代码区内存被置为 0x00,网上查了下没有提到关于代码转为机器码后的存放问题,是和静态变量它们放在一起还是单独的区域,求各位了解的大佬赐教>:-<
这种情况一般是程序其他地方溢出覆盖了不该覆盖的地方导致的。

我原本也是这样想的,但是刚刚查资料提到说程序执行时的代码段区域是只读的,只读区域应该不能被覆盖吗吧

多了个“吗”

资料参考地址是 www.cnblogs.com/fengyv/p/3789252.html

Delete 是什麼

就是一个普通的函数,

事实是可以的。这部分所谓的只读意思是,告诉你不能修改,但是如果你硬要修改是有办法的。毕竟代码同样会被加载到内存上而内存本来就是可读写的。
一般来说,下一条指令要执行的机器码错误多半是由于跳转的地址错误,调用函数实际上要执行 call 指令,而 call 指令是要把 IP ( X86 上是 EIP )寄存器存放到栈空间里的,如果函数里面错误的修改了栈空间里 IP ( EIP )的内容,那么在函数退出的时候 ret 指令就会把错误的值还原到 IP ( EIP ),这样你就会看到下一条执行的指令不正确了。
所以一般来说类似 delete 这种函数执行的时候如果出现这样的问题,多半是因为栈空间进行了错误的写入。仔细检查是否有越界的情况产生。

好的,我再检查下,非常感谢

正常情况下,如果没有修改代码段的属性,对代码段进行写操作会产生 segmentation fault,除非进行了特殊操作,比如 mprotect

哦哦,即使那段代码没执行到的话,修改也会产生 segmentation fault 的吗

不需要执行,在写的时候就会触发 segmentation fault

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服