x86 では、GCC は を呼び出したいときに次の命令を生成します__stack_chk_fail
。
; start of the basic block
00000757 call sub_590 ; __stack_chk_fail@plt
0000075c add byte [ds:eax], al
0000075e add byte [ds:eax], al
; start point of another function
同様の動作が ARM でも発生します。
; start of the basic block
00001000 bl __stack_chk_fail@PLT
00001004 dd 0x0000309c ; data entry, NOT executable indeed!
静的解析ツールで CFG を構築する場合、CFG アルゴリズムは、__stack_chk_fails
呼び出された基本ブロックの最後の命令を特定できません。
CPU が実行すべきではない命令 (または場合によってはデータ エントリ) を実行するのを防ぐために、呼び出しの後にある種のリターン命令を用意することは合理的です。__stack_chk_fail
これらの場合、CFG ジェネレーター アルゴリズムは、それが通常の関数呼び出しであると想定し、別の関数のコード (前の例) またはデータ エントリ (後者の例) へのトラバースを続けますが、これはまったく望ましくありません。
それで、私の質問は、GCCが基本ブロックの終点にreturn (またはbranch ) 命令を挿入しないのはなぜですか?