コントロールにマシンレベルのプログラムやデータの章-3.10 - コンピュータシステムの深い理解

免責事項:この記事はブロガーオリジナル記事です、続くBY-SAのCC 4.0を著作権契約、複製、元のソースのリンクと、この文を添付してください。
このリンク: https://blog.csdn.net/weixin_40199047/article/details/102678402

マシンレベルのプログラムや制御するためのデータで3.10

3.10.1は、ポインタを理解しました

統一的にポインタ、異なるデータ構造要素を参照します。
1)各ポインタは型に対応します(ポインタ型のマシンコード;. C言語の一部ではないプログラマがエラーに対処避けるために設けられた抽象化である)
2)各ポインタ値を有していますこの値は、指定された型のオブジェクトのアドレスです。特別なNULL(0)値はどこにも指していないポインタを表します。
3)「&」演算子は、ポインタを作成します
4)演算子は、間接的にポインタを参照するために使用されます
5)配列とポインタ密接参照としてポインタ変数のような(しかし、変更しない)アレイの名前とすることができます。たとえば、a[3]同等*(a+3)
配列参照とポインタ操作は、オブジェクトのサイズによってオフセットスケーリングする必要があります。
6)ポインタは、その値を変更することなく、唯一の種類を変更する、別のタイプの1つのタイプからキャストします1つの効果は、鋳造伸縮ポインタ演算を変更することです。
例えば:

char *p = 'c' ;
(int *)p + 7 的结果为 p + 28;
(int *)(p + 7) 的结果为 p + 7。

(さらにより優先さキャスト)
7)関数へのポインタがあるとこれは、これらの参照は、呼び出しプログラムのいくつかの他の一部とすることができるコードの参照として非常に強力なストレージと転送機能を提供します。
例えば:

int fun(int x, int *p);
/** 声明指针 fp ,将它赋值为这个函数 */
int (*fp)(int, int *);
fp = fun;
/** 函数调用 */
int y = 1;
int result = fp(3, &y);

関数ポインタの値は、第1の命令アドレスのマシンコード表現の関数です。

3.10.2アプリケーション:GDBデバッガを使用して

まず、実行objdumpのプログラムのバージョンを解体取得します。起動するには、次のコマンドラインGDB
linux> gdb prog
通常のアプローチは、関心の手続きの場所の近くにブレークポイントを設定することです。

コマンド 効果
quit やめますGDB
run プログラムを実行します(コマンドライン引数は、ここで与えられました)
kill プログラムを停止
break sth 機能ではsth入り口にブレークポイントを設定するには
break *0x400540 アドレスでの0x400540セットブレークポイント
delete 1 ブレークポイントを削除します1
delete すべてのブレークポイントを削除します。
stepi 実行1命令の
stepi 4 実行4命令の
nexti 同様にstepi、関数呼び出しの単位で
continue 続けます
finish 現在の関数が戻るまで実行
disas sth 分解機能sth
disas 0x400540 分解0x400540機能近く
disas 0x400540.0x40054d 指定された範囲内で分解
print /x $rip プログラムカウンタの進出力(%rip)
print $rip プログラムカウンタの小数点の出力(%rip)
print /t $rip プログラムカウンタのバイナリ出力(%rip)
print 0x100 出力0x100小数
print /x 555 出力555
print /x ($rsp + 8) 進出力%rsp + 8
print *(long *) 0x7fff ffff e818 アドレスでの出力0x7fff ffff e818長整数
print *(long *) (%rsp + 8) アドレスでの出力%rsp + 8長整数
x/2g 0x7fffffffe818 アドレスをチェック0x7fffffffe818ダブルワード開始(8バイト)
x/20b sth 機能をチェックsthする前に20バイト
info frame 情報現在のスタックフレーム
info registers すべてのレジスタ
help 関連する取得しGDBた情報を

マップ 3 - 39    G D B 生活 作ります ショー 言います 明るいです ザ・ A 一部 G D B サポート サポート 機械 デバイス レベル シーケンス トーン テスト スタイル \ブルー{図3-39} \; GDBコマンドの例。これは、GDBのサポートマシンレベルのデバッグ方法のいくつかを示しています

3.10.3メモリバッファオーバーフローおよびクロスボーダー参照

バッファオーバーフローbuffer overflow)。文字列を格納するために、スタック上に割り当てられた文字列が、文字列は、配列に割り当てられた領域よりも長くなっています。
例:
ここで説明する絵を書きます
echo対応アセンブリ:
ここで説明する絵を書きます
情報は、国境を越えた損傷であろう:
ここで説明する絵を書きます
ここで説明する絵を書きます
バッファオーバーフローより致命的な使用のプログラムが実行する不本意であったであろう機能を実行できるようにすることです。これは、安全な、最も一般的なコンピュータネットワーク攻撃システムの一つです。

バッファオーバーフロー攻撃に対する3.10.4

1.スタックのランダム化

为了在系统中插入攻击代码,攻击者既要插入代码,也要插入指向这段代码的指针,这个指针也是攻击字符串的一部分。产生这个指针需要知道这个字符串放置的栈地址。
栈随机化的思想使得栈的位置在程序每次运行时都有变化。这类技术称为地址空间布局随机化Address-Space Layout Randomization),简称ASLR
通常攻击者使用空操作雪橇(nop sled,使程序”滑过“目标序列,即在实际攻击代码前插入一段很长的nop(读作“no op”no operation的缩写)指令。
示例:
n個 m 0 ,    2 m n \geq m \geq 0,\; 2^m 个字节的nop sled能破解 2 n 2^n 的栈随机化需要枚举 2 n m 2^{n-m} 次。

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

重点习题:
ここに画像を挿入説明
答案:
ここに画像を挿入説明

おすすめ

転載: blog.csdn.net/weixin_40199047/article/details/102678402