2012-01-20 21 views
3

いくつかのx86 asmを使いこなしている間に、バグによってEIPが00000000、または存在しない別のメモリ位置に設定されたケースについて疑問に思っています。 SEHまたは同様のエラー処理メカニズムを使用してこれらのケースをキャッチし、実行を回復することは可能ですか?EIP = 00000000に設定された復旧

+0

このような状況で「実行を回復する」方法を知っていますか?私は起こりうるスタック破損シナリオから回復できる信頼できる行動を想像することはできません。 – Zuljin

+1

EIPが0のときにスタックが壊れていないと仮定することはできません。なぜなら、スタックの戻りアドレスの破損は、間違ったEIP値を引き起こす最も一般的な問題であるからです。 – Zuljin

+0

実際、私が考えていたケースはポインタへの条件付きジャンプでした。 'je [eax]'。 – Polynomial

答えて

2

これが起こる前にこれをキャッチする方法はありませんが、スタック(メモリはESPおよび/またはEBP)を調べることができます。コードへのポインタを確認してください。

これが原因の命令がcallだった場合は、ESPのdwordが違反者の直後を指す戻りアドレスになります。

jmpの場合は、よりスリムである可能性がありますが、引き続き実行可能なトレースを探すことができます。

ごみがretでゴミ箱ESPである場合、最悪の場合があります。通常、この時点でスタックは完全に偽です。他のレジスタの値をチェックすることはできますが、そのうちの1つに手がかりを与えるポインタが含まれていて、in this postのようにスタックフレーム全体のスタック領域をスキャンすることができます。どこかのプロセスに固有の、しかし、アンタッチャブル保存されている

+0

スタック内の最後の呼び出し元アドレスに戻った場合、おそらくすべてが破損する可能性があります、またはスタック割り当てのために実際のリターンアドレスの前にアドレスを持っている)、または潜在的なコードを悪夢に挿入する... – Necrolis

0

あなたの最も可能性の高い、そしておそらく最も安全な、「溶液」setjmp/longjmp(またはCONTEXT)を使用して、に戻っても安全であるプロセス状態のスナップショットです、 PEBがどのように格納されるかと同様に、FS/GS/ESセグメントのようなセグメントである。これにより、あまりに多くの可能性のある穴を残すことなく、すべてのレジスタを正しく復元することができます。

もちろん、これはゲームのようなもの(正確にどこが爆発するかによって異なります)でも、ワープロやマイナーな状態の損失が大きな問題ではないアプリの場合はうまくいくはずです他のすべてのファイルをクラッシュさせていた古いDev-C++ IDEを思い出させますが、復旧できない「致命的な」例外を私に保証していましたが...。

関連する問題