Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Windowsで関数フック
Search
ryoha
December 10, 2020
0
66
Windowsで関数フック
Windowsでフック用のライブラリを言語移植してる際に学んだこと。
ryoha
December 10, 2020
Tweet
Share
More Decks by ryoha
See All by ryoha
自由を求めてWindowsオーディオプログラミング
ryoha
0
440
Featured
See All Featured
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.2k
Become a Pro
speakerdeck
PRO
26
5.1k
4 Signs Your Business is Dying
shpigford
182
22k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
It's Worth the Effort
3n
184
28k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
52k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
How to train your dragon (web standard)
notwaldorf
89
5.8k
Building Applications with DynamoDB
mza
93
6.2k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
3
380
Transcript
Windowsで関数フック @ryoha
自己紹介 • 電気電子系学部二年 • 趣味 ◦ ビジュアルノベルゲーム ◦ プログラミング ▪
Web フロント ▪ デスクトップアプリ ▪ たまにWeb サーバー • 好きなプログラミング言語はTypeScript • 好きなOSはWindows • 最近はminhookというCのライブラリのRust移植をしようとしてる ◦ 今日の話はこれ
関数フックって? • > プログラム中の特定の箇所に、利用者が独自の処理を追加できるように する仕組み (Wikipedia フックのページより) • ユーザーが非公式のパッチを作るときに使ったりする ◦
英語のツールを日本語化したり ◦ 利用規約は読もう どうやってやるんだろう?っていうのが今日の話
基本に立ち返って 1. ノイマン型コンピュータでは記憶領域(メモリ)に命令を読み込み位置か ら逐次実行 2. メモリに乗ってる命令は機械語(これはアセンブリと一対一対応) 3. そのメモリ部分を書き換えたらいいじゃん!
もう少し細かい実装方針 • じゃあ割り込ませたい処理(機械語)をその部分に挿入して今までのは 後ろにずらしたらいいやろw ◦ 当然これじゃダメ ◦ 割り当てられてない部分のメモリを書き換えると関係ない処理に影響が出るか も •
だからフックしたい処理の冒頭を割り込ませたい処理へのJMP命令に 書き換えればいい • そして割り込ませたい処理が終わったら元の状態に戻して、削った冒 頭部分を実行した後フックしたい処理にもどればいい
立ちはばかるアドレス指定の話 • x86モードでは指定できるメモリアドレスはアドレス空間全体をカバーしてる • 厄介なのがx64モードでRIP相対アドレッシングで指定できるアドレスは、ア ドレス空間全体に対して狭い範囲に限られる ◦ -2GB ~ +2GB
しか指定できない つまりx64モードだと削った冒頭部分でRIP相対アドレッシングでアドレス指定し てたら元の冒頭部分が実行できないため近くに配置する必要がある。
リレー関数・トランポリン関数 • 割り込ませたい処理が長いとそれだけフック部分の近くに割り当てるのが 難しい • ライブラリとして提供することを考えたとき ◦ わざわざフック部分の近くに割り当ててもらうのは使い勝手が悪い ◦ フック冒頭の部分を処理に組み込んでもらうのは使い勝手が悪い
みたいな理由でリレー関数とトランポリン関数を導入します リレー関数は割り込ませたい処理にジャンプさせ、トランポリン関数はフックした い処理の冒頭部分を代行してその続きに戻らせます
1. 冒頭を削ってリレー関数にジャンプ 2. 割り込ませたい処理にジャンプ 3. おわったらもどる 4. 削った冒頭部分の処理をして削った部分の先に戻る
メインで使う具体的なWin32api • VirtualAlloc ◦ メモリ位置を指定してその近くにメモリ割り当てをしてもらう • VirtualProtect ◦ メモリのアクセス保護を変更する関数 •
FlushInstructionCache ◦ メモリを書き換えてもキャッシュに残ってたら意味がないからキャッシュを更新する
参考にしたサイト • IA-32 インテル® アーキテクチャ ソフトウェア・デベロッパーズ・マニュアル 中巻 A:命令セット・リファレンス A-M ◦ 日本語 ◦
神 ◦ https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/IA32_Arh_Dev_ Man_Vol2A_i.pdf • 移植元のCのライブラリ ◦ ドキュメント MinHook - The Minimalistic x86/x64 API Hooking Library - CodeProject ◦ 今日話した概念的なのは大体ここに乗ってる ◦ Cになれてないのもあってコード小さいのに読むのに丸一日かかった