More Related Content
PDF
10年効く分散ファイルシステム技術 GlusterFS & Red Hat Storage PDF
ネットワーク ゲームにおけるTCPとUDPの使い分け PDF
コンテナの作り方「Dockerは裏方で何をしているのか?」 PDF
新入社員のための大規模ゲーム開発入門 サーバサイド編 PDF
Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料) PDF
UnboundとNSDの紹介 BIND9との比較編 PDF
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp PDF
What's hot
PDF
Jetson活用セミナー ROS2自律走行実現に向けて PDF
なぜディスクレスハイパーバイザに至ったのか / Why did we select to the diskless hypervisor? #builde... PPTX
PDF
PPTX
PPTX
PDF
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~ PDF
PPTX
PDF
PDF
PDF
PPTX
Cisco Modeling Labs (CML)を使ってネットワークを学ぼう!(DevNet編) PPTX
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料) PPTX
cluster-monitoringで困ったこと学んだこと PPTX
PDF
PPTX
Amazon EKS への道 ~ EKS 再入門 ~ PDF
PPTX
Viewers also liked
PPTX
マテリアルとマテリアルインスタンスの仕組みと問題点の共有 (Epic Games Japan: 篠山範明) #UE4DD PDF
カスタムメモリマネージャと高速なメモリアロケータについて PPTX
PPTX
マジシャンズデッド ポストモーテム ~マテリアル編~ (株式会社Byking: 鈴木孝司様、成相真治様) #UE4DD PPTX
PPTX
Unreal Engine 4のビジュアルスクリプトシステム”Blueprint”を使ったMod制作Tipsのご紹介 PDF
Windows をより安全にする SafeSEH on MinGW PDF
PDF
Similar to SEH on mingw32
PDF
PDF
【学習メモ#8th】12ステップで作る組込みOS自作入門 PDF
PDF
PDF
ODP
PDF
PDF
2011.09.18 v7から始めるunix まとめ PDF
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リー PDF
PDF
StackExchangeで見たシステムプログラミング案件 PDF
C++コンパイラ GCCとClangからのメッセージをお読みください PDF
PDF
Sapporocpp#2 exception-primer PPTX
PDF
PDF
KEY
Functional Pearl + Brainfuck PPTX
PDF
error handling using expected SEH on mingw32
- 1.
- 2.
発表者について
● 名前:@kikairoya
● 南九州から来ました
● もうすぐ大阪人になります
● 触手の下僕として働くことになりました
● C++ とか出来ます
- 3.
- 4.
- 5.
- 6.
- 7.
SEHのシンタックス
● __exceptを使う場合
__try {
/* try block */
} __except (filter-expr) {
/* except block */
}
● __finally を使う場合
__try {
/* try block */
} __finally {
/* finally block */
}
- 8.
SEHの処理手順
● 関数呼び出しごとに例外ハンドラを登録
● 例外処理(ハンドラの呼び出し)は二段階
● まずはスタックをどこまで巻き戻すか探索
__exceptのフィルタ式を呼び出して判定
● 巻き戻し先が決まってから実際に巻き戻す
finally blockをスタックの先端から順に実行
- 9.
- 10.
例外ハンドラの登録
● EXCEPTION_REGISTRATION構造体をスタッ
ク上に構築
● prev メンバに[fs:0]の値をコピー
● [fs:0]に構造体のアドレスをコピー
struct EXCEPTION_REGISTRATION {
EXCEPTION_REGISTRATION *prev;
PEXCEPTION_HANDLER handler;
unsigned char user_data[VAR_LENGTH];
};
- 11.
スタックの構造
fn2のローカル変数
fn2のer.prev
fn2のer.handler
fn1のフレームポインタ
fn2からの戻りアドレス
fn2の引数
fn1のローカル変数
fn1のer.prev
fn1のer.handler
fn0のフレームポインタ
fn1からの戻りアドレス
fn1の引数
esp
[fs:0]
ebp
- 12.
巻き戻し先の探索
● 関数呼び出しごとに例外ハンドラを登録
● 例外処理(ハンドラの呼び出し)は二段階
● まずはスタックをどこまで巻き戻すか探索
__exceptのフィルタ式を呼び出して判定
● 巻き戻し先が決まってから実際に巻き戻す
finally blockをスタックの先端から順に実行
- 13.
巻き戻し先の探索
例外発生
コンテキストを保存してjmp
kernel呼出し
ハンドラ探索
} __except (filter-expr) {
ハンドラA
ハンドラB
ハンドラC
call
call
return 1
call
return 1
call
filterA
filterB
filterC
call
return 0
call
return 0
call
return 1
探索終了
これ
- 14.
SEHの実現方法
● 関数呼び出しごとに例外ハンドラを登録
● 例外処理(ハンドラの呼び出し)は二段階
● まずはスタックをどこまで巻き戻すか探索
__exceptのフィルタ式を呼び出して判定
● 巻き戻し先が決まってから実際に巻き戻す
finally blockをスタックの先端から順に実行
- 15.
巻き戻し実行
ハンドラA
ハンドラB
ハンドラC
RtlUnwind
call
return 1
call
return 1
call
finally blockの実行
call
return
call
return
jmp
finaly blockの実行
ハンドラCの続きexcept blockの実行
正常処理に復帰
jmp
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
RtlUnwindの呼出し
void WINAPIRtlUnwind(
PVOID TargetFrame,
PVOID TargetIp,
PEXCEPTION_RECORD ExceptionRecord,
PVOID ReturnValue
);
● TargetFrameに巻き戻し先の
EXCEPTION_REGISTRATION を指定
● TargetIpに巻き戻し完了後の復帰点を指定
● 残りはnullptr
- 24.
- 25.
RtlUnwindの呼出し
asm volatile(
"pushl $0nt" // ReturnValue
"pushl $0nt" // ExceptionRecord
"pushl $1fnt" // TargetIp
"pushl %0nt" // TargetFrame
"call _RtlUnwind@16nt"
"1: nopnt"
:
: "a"(reg)
: "ecx", "edx", "ebx", "esi", "edi",
"esp", "cc", "memory"
);
- 26.
- 27.
スタックの巻き戻し
● 実装のキモ
● finally blockの実行とデストラクタの呼出しを行
う必要がある
● __finallyだけなら__tryでsetjmp した地点に
longjmp するだけ
● デストラクタを呼ぶにはC++例外を投げる必要
がある
- 28.
巻き戻し実行(/EHsc相当)
ハンドラA
ハンドラB
ハンドラC
RtlUnwind
call
return 1
call
return 1
call
finally blockの実行
call
return
call
return
jmp
finaly blockの実行
ハンドラCの続きexcept blockの実行
正常処理に復帰
jmp
- 29.
- 30.
スタックの巻き戻し(throw)
void throw_seh_unwinder(constseh_jmp_buf &b) {
asm volatile (
"movl %0, %%ebpnt" // フレームポインタを切り替え
"pushl %1nt" // 戻りアドレスの偽装
"jmp _throw_seh_unwinder" // call
:
: "r"(b.ebp), "a"(b.eip),
"b"(b.ebx), "S"(b.esi), "D"(b.edi)
: "memory");
__builtin_unreachable();
}
extern "C" void throw_seh_unwinder() {
// 例外発生地点から呼ばれているように見える
throw seh_unwinder();
}
- 31.
巻き戻し実行(/EHa相当)
ハンドラA
ハンドラB
ハンドラC
RtlUnwind
call
return 1
call
return 1
call
例外発生地点から例外を投
げてtry blockでcatch
jmp
jmp
jmp
jmp
jmp
直前のtry blockから例外を
投げてtry blockでcatch
直前のtry blockから例外を
投げてtry blockでcatch
正常処理に復帰
jmp
ハンドラCの続き
- 32.
巻き戻し実行 (/EHa相当)
3段目のハンドラ:
*1からthrow して*2でcatch
そのままfinally block を実行
*3からハンドラにlongjmp
2段目のハンドラ:
*3からthrow して*4でcatch
そのままfinally block を実行
*5からハンドラにlongjmp
1段目のハンドラ:
*5からthrow して*6でcatch
そのままexcept block を実行
*7から正常ルートに復帰
__try {
__try {
__try {
// *1 Access Violation
*(int *)0 = 0;
} __finally {
// *2
} // *3
} __finally {
// *4
} // *5
} __except(1) {
// *6
} // *7
throw
throw
throw
longjmp
longjmp
- 33.
- 34.
- 35.
- 36.
- 37.