3.10 in the machine-level programs and data to control
3.10.1 understood pointer
Pointer in a unified manner, a reference to a different data structure elements.
1) Each pointer corresponds to a type . (Not part of the pointer type machine code;. C language are an abstraction provided to help programmers avoid addressing errors)
2) each pointer has a value . This value is the address of the object of a specified type. Special NULL(0)
value represents the pointer does not point anywhere.
3) '&' operator to create pointers .
4) operator is used to indirectly reference pointer .
5) arrays and pointers closely . The name of the array can be like a pointer variable as a reference (but not modify). For example, a[3]
equivalent *(a+3)
.
Array reference and pointer operations require to be scaled offset by the object size.
6) The pointer to cast from one type to another type, changing only its type, without changing its value . One effect is to change the cast telescopic pointer arithmetic.
E.g:
char *p = 'c' ;
(int *)p + 7 的结果为 p + 28;
(int *)(p + 7) 的结果为 p + 7。
(Casts precedence than addition)
7) pointers to functions to be . This provides a very powerful storage and transfer function as the code references, these references may be some other part of the calling program.
E.g:
int fun(int x, int *p);
/** 声明指针 fp ,将它赋值为这个函数 */
int (*fp)(int, int *);
fp = fun;
/** 函数调用 */
int y = 1;
int result = fp(3, &y);
Function pointer value is a function of the machine code representation of the first instruction address.
3.10.2 application: using GDB debugger
First run OBJDUMP to get disassembled version of the program. The following command line to start GDB :
linux> gdb prog
The usual approach is to set a breakpoint in the vicinity of the place of interest procedures.
command | effect |
---|---|
quit |
drop outGDB |
run |
Run the program (command line arguments given here) |
kill |
Stop the program |
break sth |
In function sth to set a breakpoint at the entrance |
break *0x400540 |
In the address 0x400540 set breakpoint |
delete 1 |
Remove breakpoints1 |
delete |
Delete all breakpoints |
stepi |
Execution 1 of instructions |
stepi 4 |
Execution 4 of instructions |
nexti |
Similarly stepi , but in units of function calls |
continue |
Continue |
finish |
Run to the current function returns |
disas sth |
Disassembly functionsth |
disas 0x400540 |
Disassembly 0x400540 function nearby |
disas 0x400540.0x40054d |
Disassembly within a specified range |
print /x $rip |
Hexadecimal output of the program counter (%rip) value |
print $rip |
Decimal output of the program counter (%rip) value |
print /t $rip |
Binary output of the program counter (%rip) value |
print 0x100 |
Output 0x100 decimal |
print /x 555 |
Output 555 hexadecimal |
print /x ($rsp + 8) |
Hexadecimal output%rsp + 8 |
print *(long *) 0x7fff ffff e818 |
Output at address 0x7fff ffff e818 long integer |
print *(long *) (%rsp + 8) |
Output at address %rsp + 8 long integer |
x/2g 0x7fffffffe818 |
Check the address from 0x7fffffffe818 the double word start ( 8 bytes) |
x/20b sth |
Check function sth before 20 bytes |
info frame |
Information current stack frame |
info registers |
All registers |
help |
Obtain relevant GDB information |
3.10.3 memory buffer overflows and cross-border references
Buffer overflow buffer overflow
( ) . A character array allocated on the stack to store the string, but the string is longer than the space allocated for the array.
Example:
echo
corresponding assembly:
information will be cross-border damage:
buffer overflow of a more deadly use is to allow the program to perform functions that would have been unwilling to perform. This is one of the most common computer network attack system secure.
3.10.4 against buffer overflow attacks
1. Stack randomization
为了在系统中插入攻击代码,攻击者既要插入代码,也要插入指向这段代码的指针,这个指针也是攻击字符串的一部分。产生这个指针需要知道这个字符串放置的栈地址。
栈随机化的思想使得栈的位置在程序每次运行时都有变化。这类技术称为地址空间布局随机化(Address-Space Layout Randomization
),简称ASLR。
通常攻击者使用空操作雪橇(nop sled
),使程序”滑过“目标序列,即在实际攻击代码前插入一段很长的nop
(读作“no op”
,no operation
的缩写)指令。
示例:
个字节的nop sled
能破解
的栈随机化需要枚举
次。
2. 栈破坏检测
计算机的第二道防线是能够检测到何时栈已经被破坏。
GCC提供一种栈保护者机制,来检测缓冲区越界。其思想是在栈帧中任何局部缓冲区与栈状态之间存储一个特殊的金丝雀(canary
),也称为哨兵值(guard value
),是在程序每次运行时随机产生的。
echo
函数示例:
程序第三行通过段地址%fs:40
从内存读入金丝雀的值,保存在栈中;
程序第十一行取出该值与原地址的值作比较,不相等则栈异常。
tips
:
容易越界的参数尽可能放置在栈底,以保护其他参数。
示例:
图(b
)中,参数v
比数组参数buf
更靠近栈顶,vbuf
缓冲越界不会破坏v
。
3. 限制可执行代码区域
最后一招是消除攻击者向系统插入可执行代码的能力。
随机化、栈保护和限制哪部分内存可以存储可执行代码——是用于最小化程序缓冲区溢出攻击漏洞三种最常见的机制。
3.10.5 支持变长栈帧
前面所讲的各种函数的机器级代码,都有一个共同点,即编译器能够预先确定需要为栈帧分配多少空间。
下面示例为局部存储是变长的。
%rbp
称为帧指针(frame pointer
)有时称为基址帧(base pointer
);
leave
指令将栈帧指针恢复到它之前的值(第20行)。等价于:
movq %rbp, %rsp ;Set stack pointer to begining of frame
popq %rbp ;Restore saved %rbp and set stack ptr to end of caller's frame
重点习题:
答案: