一、笔记
1、p/格式 $变量显示显示某个寄存器的变量。格式可以是浮点型,字符串型。
2、x/格式 地址显示某个内存的内容。
x/10i $pc显示从PC所指地址开始的十条指令。
3、r15 pc
r14 lr
r13 sp
r12 ip暂时保存sp
r11 fp栈帧
LWP轻量级线程
4、p54:调用函数之后,栈上面依次保存了传给函数的参数、调用者的返回地址、上层栈帧指针和函数内部使用的自动变量。此外处理有些函数时,还会用栈来保存寄存器值。每个函数都独有这些信息,称为栈帧。此时需要适当的设置栈帧起始地址的帧指针FP,而栈指针SP一直指向栈的顶端。
5、下面函数执行,如果不输入参数就会发生递归调用的栈溢出。
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#define MAX (1UL << 20)
typedef unsigned long long u64;
typedef unsigned int u32;
u32 max_addend = MAX;
u64 sum_till_MAX(u32 n)
{
u64 sum = 0;
n++;
sum = n;
if( n < max_addend)
{
sum += sum_till_MAX(n);
}
return sum;
}
int main(int argc, char** argv)
{
u64 sum = 0;
if((argc == 2) && isdigit(*(argv[1])))
{
max_addend = strtoul(argv[1], NULL, 0);
}
if(max_addend > MAX || max_addend == 0)
{
fprintf(stderr, "INVALID!");
return 1;
}
sum = sum_till_MAX(0);
printf("sum(0..%lu) = %llu\n", max_addend, sum);
return 0;
}
6、p60:在GDB调试程序是可以用i proc mapping查看该进程的内存映射,显示被调试的进程相对应的maps信息。但是core文件需要用info files命令来获取。
7、p127:栈破坏有时会导致问题难以分析,特别是无法获取backtrace信息,追溯问题现象发生的路径就变得异常困难。此外存在栈破坏,可以说backtrace信息也不完整。
backtrace是根据栈中保存的函数返回地址来显示的。根据栈空间上的返回地址和调试信息得出的栈使用量,依次求出调用者函数。也就是说,调试器backtrace的地址来自进程的栈上。
info reg可以获得寄存器的信息。
8、P151:数组非法访问导致内存破坏,错误的操作数组导致的BUG之一就是缓冲区溢出,也就是说向已经分配的内存空间之外写入数据。特别是这类BUG发生在栈上的缓冲区中,就可能引发安全漏洞。此外,在计算数组的下标时,如果计算错误,就可能算出负下标,也可能引起缓冲区溢出。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char names[] = "book cat dog building vegetbale curry";
void func(void)
{
char buf[5];
strcpy(buf,names);
}
int main(void)
{
func();
return 0;
}
理解:如就是将数组拷贝超出预先分配在栈上的内容,拷贝到栈上去了,导致覆盖了原先栈上的函数返回地址。这样函数跳转到了错误的地址,这个地址不是操作系统分配给程序地址。
9、P165:死锁,一般程序停止响应要先确认是失去控制还是在等待。用PS命令可以确认(ps ax -L | grep astall),PS命令中如果为R表示进程在运行,如果是S表面在SLEEP,如果是预期之外的SLEEP,大多数情况是陷入了死锁。用GDB attach到该进程上,调查哪里在睡眠。(也可以使用杀死某个进程来调查某个不响应的程序)(钩子函数)
10、P307:内存泄漏,不断用secureCRT发送命令获取内存的变化情况,然后用EXCLE分析该数据,判断是否发生内存泄漏。/proc/meminfo中,Committed_AS可以作为进程的内存泄漏估计,其他需要统计的值是MEMFree、SwapFree、AnonPages和Cached的值。
可以用/proc/<PID>/mem快速读取进程的内存内容。
二、其他参考资源
1、优秀笔记
2、目录