GDBでレジスタ確認


(水樹奈々 禁断のレジスタンス)

アニメ『クロスアンジュ 天使と竜の輪舞』(2014)
動画はこのアニメの主題歌です。
普通の人が魔法みたいなことができて、できない人が異常とみなされ追放される世界です。主人公は姫様なのに魔法が使えないので異常者として追放されます。見るアニメが多すぎて、このアニメはまだ数話しか見てません。全話みないと何ともいえないですが、主題歌の動画は何度も見てます。

レジスタンス(resistance)と綴りからして違いますが、今回はレジスタ(register)です。
GDBでレジスタ見ていきますが、まず簡単なC言語のサンプルプログラムを作ります。

takk@deb9:~$ cat sample.c
int add(int a, int b)
{
  return a + b;
}

int main()
{
  int c;
  c = add(0x11223344,0x55667788);
}
takk@deb9:~$

足し算するだけのプログラムです。ビルドしてGDBを起動します。

takk@deb9:~$ gcc -g sample.c
takk@deb9:~$ gdb a.out
~省略~
(gdb)

breakしてrunします。

(gdb) b main
Breakpoint 1 at 0x67c: file sample.c, line 9.
(gdb) r
Starting program: /home/takk/a.out

Breakpoint 1, main () at sample.c:9
9         c = add(0x11223344,0x55667788);
(gdb)

ステップでadd関数内に入ります。

(gdb) s
add (a=287454020, b=1432778632) at sample.c:3
3         return a + b;
(gdb)

さて、このときのレジスタを確認してみましょう。

(gdb) info register
rax            0x555555554674   93824992233076
rbx            0x0      0
rcx            0x0      0
rdx            0x7fffffffe5e8   140737488348648
rsi            0x55667788       1432778632
rdi            0x11223344       287454020
rbp            0x7fffffffe4d0   0x7fffffffe4d0
rsp            0x7fffffffe4d0   0x7fffffffe4d0
r8             0x555555554710   93824992233232
r9             0x7ffff7de8cb0   140737351945392
r10            0x0      0
r11            0x7ffff7b97300   140737349513984
r12            0x555555554530   93824992232752
r13            0x7fffffffe5d0   140737488348624
r14            0x0      0
r15            0x0      0
rip            0x55555555466a   0x55555555466a <add+10>
eflags         0x202    [ IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
(gdb)

引数a、bは、レジスタrdiとrsiに割り当てられているようです。
個別に変数とレジスタの内容を確認してみます。

(gdb) p/x a
$1 = 0x11223344
(gdb) p/x $rdi
$2 = 0x11223344
(gdb) p/x b
$3 = 0x55667788
(gdb) p/x $rsi
$4 = 0x55667788
(gdb)

disassembleコマンドで、ディスアセンブル表示してみます。

(gdb) disas
Dump of assembler code for function add:
   0x0000555555554660 <+0>:     push   %rbp
   0x0000555555554661 <+1>:     mov    %rsp,%rbp
   0x0000555555554664 <+4>:     mov    %edi,-0x4(%rbp)
   0x0000555555554667 <+7>:     mov    %esi,-0x8(%rbp)
=> 0x000055555555466a <+10>:    mov    -0x4(%rbp),%edx
   0x000055555555466d <+13>:    mov    -0x8(%rbp),%eax
   0x0000555555554670 <+16>:    add    %edx,%eax
   0x0000555555554672 <+18>:    pop    %rbp
   0x0000555555554673 <+19>:    retq
End of assembler dump.
(gdb)

edi(rdi)が第1引数のa、esi(rsi)が第2引数のbでしたね。
先ほどのレジスタ名とは違うように見えますが、扱うビット数が異なるだけです。
接頭辞rの場合64bit
eだと32bit
接頭辞なしは16bit
lなら下位8bitです。

(gdb) p/x $rax = 0x1020304050607080
$5 = 0x1020304050607080
(gdb) p/x $rax
$6 = 0x1020304050607080
(gdb) p/x $eax
$7 = 0x50607080
(gdb) p/x $ax
$8 = 0x7080
(gdb) p/x $al
$9 = 0x80
(gdb)

ステップ実行して、第1引数と第2引数が足されることを確認します。

(gdb) n
4       }
(gdb) disas
Dump of assembler code for function add:
   0x0000555555554660 <+0>:     push   %rbp
   0x0000555555554661 <+1>:     mov    %rsp,%rbp
   0x0000555555554664 <+4>:     mov    %edi,-0x4(%rbp)
   0x0000555555554667 <+7>:     mov    %esi,-0x8(%rbp)
   0x000055555555466a <+10>:    mov    -0x4(%rbp),%edx
   0x000055555555466d <+13>:    mov    -0x8(%rbp),%eax
   0x0000555555554670 <+16>:    add    %edx,%eax
=> 0x0000555555554672 <+18>:    pop    %rbp
   0x0000555555554673 <+19>:    retq
End of assembler dump.
(gdb) p/x $eax
$10 = 0x6688aacc
(gdb)

レジスタeaxに、レジスタedxの値が加算されて、0x6688aaccになりました。

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA