g++ -g3 -std=c++11 ./main.cpp -o main
g++ -g3 -std=c++11 -shared -fPIC hook.cpp -o libhook.so
g++ -g3 -std=c++11 ./main_hook.cpp -o main_hook
# terminal A
LD_PRELOAD=./libstop_the_world.so:./libhook.so ./main
# teminal B
sudo gdb
attach $PID
source ./gdb-trace.py
trace-functions .*_hook
# terminal A
fg
# terminal B
c
c
gdb
を利用する場合にはrdynamic
関係なしに、共有ライブラリから実行ファイルの関数を呼び出すことが可能- gdbが実行ファイルからシンボルテーブルを作成しているので,共有ライブラリがそれを見つけることができるということ?
main_hook
の場合、実行ファイルにhookするコマンドのシンボルを実行前に探すことができるので、下記の手順のようにわざわざattachする必要なしにhook可能- 実行ファイルをリンクするときに
-rdynamic
を付加とすると、共有ライブラリから実行ファイルのシンボル情報を動的に取得できるようになる - ちなみに,仮に,
main.cpp
でaddXXX_hook
を呼び出すようにして、-L. -lhook
を下記のコマンドに付加した際に、-rdynamic
が無いと共有ライブラリ側からaddXXX
が見つからずにエラーとなる
finish
直後は
p
or p $0
で返り値がわかる
アーキテクチャ依存で下記でもよい
x86
: print $eax
x86_64
: print $rax
frameからリターンしている状態、つまり、関数を抜けていることに注意(info args
の表示内容が異なる)
現在のframe(関数)の返り値を上書きできる
つまり、代替関数を呼んでreturnすると関数の置き換えができる
- info argsは引数となっている変数の現在の値を出力する
- frame内で処理を進めていき,変数の中身が変化するとそれに対応して変化する
- c++ - How to set a breakpoint in GDB where the function returns? - Stack Overflow
- returnする直前にbreakpointを貼るのは難しいので、一旦finishしてからreverseする方法が無難
明示的に下記のような言語指定をしないと、gdb.executeなどでコマンドを実行する際に、余計な文字列も出力されてしまう
set language c++