On Unix-like operating systems, a process that accesses invalid memory receives the SIGSEGV signal. On Microsoft Windows, a process that accesses invalid memory receives the STATUS_ACCESS_VIOLATION exception.
1.最常见的SEGV: 访问0地址
#include <stdio.h>
int main()
{
int *p = 0;
printf("%d", *p); /* SEGV: try to access address 0 */
return 0;
}
2.修改const 变量
int main(void)
{
char *s ="hello zeku"; /* s in .rodata section */
*s ='o'; /* SEGV: write .radata section */
return 0;
}
#include <stdio.h>
const int g = 10;
int main()
{
int *p = (int *)&g;
(*p)++; /* SEGV: try to modify const var */
printf("%d", *p);
return 0;
}
3_1 尝试运行在.data section
#include <stdio.h>
int g = 10; /* .data section, r+w, not x */
typedef void (*F_P)();
void f()
{
printf("hello zeku\n");
}
int main()
{
F_P fp = f;
fp();
F_P fp1 = (F_P)&g;
fp1(); /* SEGV: try to execute in .data section */
return 0;
}
3_2 尝试运行在stack
#include <stdio.h>
typedef void (*F_P)();
int main (void)
{
int m = 5; /* stack: rw, not x*/
int n = 6;
F_P fp = (F_P)&m;
fp(); /*SEGV: excute in stack */
return 0;
}
4. 修改代码段
#include <stdio.h>
void f()
{
printf("hello zeku\n");
}
int main()
{
int *p = (int *)&f;
(*p)++; /*SEGV: try to write .text section*/
return 0;
}
5. 栈溢出
int main(void)
{
main(); /* SEGV: stack overflow */
return 0;
}
扩展:
进程收到SIGSEGV信号后,我们给SIGSEGV注册回调函数,打印backtrace.
refer to: sigaction/backtrace/backtrace_symbols