技術日誌

DB,Java,セキュリティ,機械学習など。興味のあることを雑多に学ぶ

qemu monitorを使ってメモリ上にロードされている実行中のアプリケーションの機械語をダンプ

qemu monitorを使う記事の続きです。

前回記事はこちらになります。

yuyubu.hatenablog.com

本記事ではwalkアプリケーションを起動した状態でqemu monitorを使ってメモリ上にマッピングされたwalkの実行ファイルを探し当てるところまでをやります。

f:id:yuyubu:20180702234149p:plain
コンソール1によって起動されたwalkアプリケーション

qemu monitorを使ってアプリケーションの実行コードがロードされている場所をのぞいて見ましょう。hariboteOSではGDTの格納内容は以下のようになっています。

index content
1003 taska用(アプリはないので使っていない)
1004 idle用(アプリはないので使っていない)
1005 1個目に確保されるアプリのLDTへの参照
1006 2個目に確保されるプリのLDTへの参照
... 省略

1エントリの登録内容はこんな感じ。

struct SEGMENT_DESCRIPTOR {
    short limit_low, base_low;
    char base_mid, access_right;
    char limit_high, base_high;
};
構造体上での表現


63       55       47       39       31       23       15       7        0
+--------+--------+--------+--------+--------+--------+--------+--------+
|base_hi |limit_hi|   ar   |base_mid|     base_low    |    limit_low    |
+--------+--------+--------+--------+--------+--------+--------+--------+



CPUの仕様上のデスクリプタ
※limit_highの上位4bitはアクセス属性の続きになります。だから実際はCPUは上の構造体を以下の形式で扱います。

63       55       47       39       31       23       15       7        0
+--------+----+----+--------+--------+--------+--------+--------+--------+
|base_hi |ar  |l_hi|   ar   |base_mid|     base_low    |    limit_low    |
+--------+----+----+--------+--------+--------+--------+--------+--------+


※入りきらない変数名は省略しています

GDTは前回記事のinfo registersコマンドの出力にある通り、

GDT=     00270000 0000ffff

この場所に格納されています。

アプリケーションのLDTが登録されている場所に近い1000×8(0x1F40)以降のエントリをダンプして見ます GDTのindexが8倍されているこが腑に落ちない人は以下の記事にまとめてあるので参考にしてください。

yuyubu.hatenablog.com

 (qemu) xp /10xg 0x271F40
 0000000000271f40: 0x000089032c500067 0x000089032d0c0067
 0000000000271f50: 0x000089032dc80067 0x00008200508c000f
 0000000000271f60: 0x000082005148000f 0x000082005204000f
 0000000000271f70: 0x0000820052c0000f 0x00008200537c000f
 0000000000271f80: 0x000082005438000f 0x0000820054f4000f

これを表に起こして見ます。

idx description base_hi ar l_hi ar base_mid base_low limit_low base limi ar
0 0x000089032c500067 00 0 0 89 03 2c50 0067 00032c50 00067 089
1 0x000089032d0c0067 00 0 0 89 03 2d0c 0067 00032d0c 00067 089
2 0x000089032dc80067 00 0 0 89 03 2dc8 0067 00032dc8 00067 089
3 0x00008200508c000f 00 0 0 82 00 508c 000f 0000508c 0000f 082
4 0x000082005148000f 00 0 0 82 00 5148 000f 00005148 0000f 082
5 0x000082005204000f 00 0 0 82 00 5204 000f 00005204 0000f 082
6 0x0000820052c0000f 00 0 0 82 00 52c0 000f 000052c0 0000f 082
7 0x00008200537c000f 00 0 0 82 00 537c 000f 0000537c 0000f 082
8 0x000082005438000f 00 0 0 82 00 5438 000f 00005438 0000f 082
9 0x0000820054f4000f 00 0 0 82 00 54f4 000f 000054f4 0000f 082

5番目のエントリのLDT00005204を表示。なおこれはコンソール1で実行したアプリケーションのLDTになります。

(qemu) xp /2xg 0x00005204
0000000000005204: 0x0040fa06200001e6 0x0040f3063000cfff
idx description base lim ar
1 0x0040fa06200001e6 00062000 001e6 4fa
2 0x0040f3063000cfff 00063000 0cfff 4f3

とりあえずコードセグメント00062000をダンプ

(qemu) xp /486bc 0x00062000
0000000000062000: '\x00' '\xd0' '\x00' '\x00' 'H' 'a' 'r' 'i'
0000000000062008: '\x00' '\x00' '\x00' '\x00' '\x00' '\x04' '\x00' '\x00'
0000000000062010: '\x07' '\x00' '\x00' '\x00' '\xe0' '\x01' '\x00' '\x00'
0000000000062018: '\x00' '\x00' '\x00' '\xe9' '\xb7' '\x01' '\x00' '\x00'
0000000000062020: '\x10' '\x04' '\x00' '\x00' 'U' '\x89' '\xe5' 'W'
0000000000062028: 'V' '\xbf' 'L' '\x00' '\x00' '\x00' 'S' '\xbe'
0000000000062030: '8' '\x00' '\x00' '\x00' 'R' '\xe8' 'M' '\x01'
0000000000062038: '\x00' '\x00' 'h' '\x80' '>' '\x00' '\x00' '\xe8'
0000000000062040: 'd' '\x01' '\x00' '\x00' 'h' '\x00' '\x04' '\x00'
0000000000062048: '\x00' 'j' '\xff' 'j' 'd' 'h' '\xa0' '\x00'
0000000000062050: '\x00' '\x00' 'P' '\xe8' '\xbd' '\x00' '\x00' '\x00'
0000000000062058: '\x89' 'E' '\xf0' 'j' '\x00' 'j' '_' 'h'
0000000000062060: '\x9b' '\x00' '\x00' '\x00' 'j' '\x18' 'j' '\x04'
0000000000062068: 'P' '\xe8' '\xf1' '\x00' '\x00' '\x00' '\x83' '\xc4'
0000000000062070: '0' 'h' '\x05' '\x04' '\x00' '\x00' 'j' '\x01'
0000000000062078: 'j' '\x03' 'j' '8' 'j' 'L' '\xff' 'u'
0000000000062080: '\xf0' '\xe8' '\xb1' '\x00' '\x00' '\x00' '\x83' '\xc4'
0000000000062088: '\x18' 'j' '\x01' '\xe8' ';' '\x01' '\x00' '\x00'
0000000000062090: 'h' '\x05' '\x04' '\x00' '\x00' 'j' '\x01' '\x89'
0000000000062098: '\xc3' 'j' '\x00' 'V' 'W' '\xff' 'u' '\xf0'
00000000000620a0: '\xe8' '\x92' '\x00' '\x00' '\x00' '\x83' '\xc4' '\x1c'
00000000000620a8: '\x83' '\xfb' '4' 't' 'W' '\x83' '\xfb' '6'
00000000000620b0: 't' 'E' '\x83' '\xfb' '8' 't' '6' '\x83'
00000000000620b8: '\xfb' '2' 't' '\'' '\x83' '\xfb' '\n' 't'
00000000000620c0: '\r' 'h' '\x05' '\x04' '\x00' '\x00' 'j' '\x01'
00000000000620c8: 'j' '\x03' 'V' 'W' '\xeb' '\xb0' '\xff' 'u'
00000000000620d0: '\xf0' '\xe8' '\xe7' '\x00' '\x00' '\x00' 'X' '\x8d'
00000000000620d8: 'e' '\xf4' '[' '^' '_' ']' '\xe9' '+'
00000000000620e0: '\x00' '\x00' '\x00' '\x83' '\xfe' 'O' '\x7f' '\xd4'
00000000000620e8: '\x83' '\xc6' '\x08' '\xeb' '\xcf' '\x83' '\xfe' '\x18'
00000000000620f0: '~' '\xc5' '\x83' '\xee' '\x08' '\xeb' '\xc0' '\x81'
00000000000620f8: '\xff' '\x93' '\x00' '\x00' '\x00' '\x7f' '\xb3' '\x83'
0000000000062100: '\xc7' '\x08' '\xeb' '\xae' '\x83' '\xff' '\x04' '~'
0000000000062108: '\xa4' '\x83' '\xef' '\x08' '\xeb' '\x9f' '\xba' '\x04'
0000000000062110: '\x00' '\x00' '\x00' '\xcd' '@' 'W' 'V' 'S'
0000000000062118: '\xba' '\x05' '\x00' '\x00' '\x00' '\x8b' '\\' '$'
0000000000062120: '\x10' '\x8b' 't' '$' '\x14' '\x8b' '|' '$'
0000000000062128: '\x18' '\x8b' 'D' '$' '\x1c' '\x8b' 'L' '$'
0000000000062130: ' ' '\xcd' '@' '[' '^' '_' '\xc3' 'W'
0000000000062138: 'V' 'U' 'S' '\xba' '\x06' '\x00' '\x00' '\x00'
0000000000062140: '\x8b' '\\' '$' '\x14' '\x8b' 't' '$' '\x18'
0000000000062148: '\x8b' '|' '$' '\x1c' '\x8b' 'D' '$' ' '
0000000000062150: '\x8b' 'L' '$' '$' '\x8b' 'l' '$' '('
0000000000062158: '\xcd' '@' '[' ']' '^' '_' '\xc3' 'W'
0000000000062160: 'V' 'U' 'S' '\xba' '\x07' '\x00' '\x00' '\x00'
0000000000062168: '\x8b' '\\' '$' '\x14' '\x8b' 'D' '$' '\x18'
0000000000062170: '\x8b' 'L' '$' '\x1c' '\x8b' 't' '$' ' '
0000000000062178: '\x8b' '|' '$' '$' '\x8b' 'l' '$' '('
0000000000062180: '\xcd' '@' '[' ']' '^' '_' '\xc3' 'S'
0000000000062188: '\xba' '\x08' '\x00' '\x00' '\x00' '.' '\x8b' '\x1d'
0000000000062190: ' ' '\x00' '\x00' '\x00' '\x89' '\xd8' '\x05' '\x00'
0000000000062198: '\x80' '\x00' '\x00' '.' '\x8b' '\r' '\x00' '\x00'
00000000000621a0: '\x00' '\x00' ')' '\xc1' '\xcd' '@' '[' '\xc3'
00000000000621a8: 'S' '\xba' '\x09' '\x00' '\x00' '\x00' '.' '\x8b'
00000000000621b0: '\x1d' ' ' '\x00' '\x00' '\x00' '\x8b' 'L' '$'
00000000000621b8: '\x08' '\xcd' '@' '[' '\xc3' 'S' '\xba' '\x0e'
00000000000621c0: '\x00' '\x00' '\x00' '\x8b' '\\' '$' '\x08' '\xcd'
00000000000621c8: '@' '[' '\xc3' '\xba' '\x0f' '\x00' '\x00' '\x00'
00000000000621d0: '\x8b' 'D' '$' '\x04' '\xcd' '@' '\xc3' 'U'
00000000000621d8: '\x89' '\xe5' ']' '\xe9' 'D' '\xfe' '\xff' '\xff'
00000000000621e0: 'w' 'a' 'l' 'k' '\x00' '*'

ダンプ内容がwalk.hrbの実行バイナリと一致

$ hexdump -C walk.hrb
00000000  00 d0 00 00 48 61 72 69  00 00 00 00 00 04 00 00  |....Hari........|
00000010  07 00 00 00 e0 01 00 00  00 00 00 e9 b7 01 00 00  |................|
00000020  10 04 00 00 55 89 e5 57  56 bf 4c 00 00 00 53 be  |....U..WV.L...S.|
00000030  38 00 00 00 52 e8 4d 01  00 00 68 80 3e 00 00 e8  |8...R.M...h.>...|
00000040  64 01 00 00 68 00 04 00  00 6a ff 6a 64 68 a0 00  |d...h....j.jdh..|
00000050  00 00 50 e8 bd 00 00 00  89 45 f0 6a 00 6a 5f 68  |..P......E.j.j_h|
00000060  9b 00 00 00 6a 18 6a 04  50 e8 f1 00 00 00 83 c4  |....j.j.P.......|
00000070  30 68 05 04 00 00 6a 01  6a 03 6a 38 6a 4c ff 75  |0h....j.j.j8jL.u|
00000080  f0 e8 b1 00 00 00 83 c4  18 6a 01 e8 3b 01 00 00  |.........j..;...|
00000090  68 05 04 00 00 6a 01 89  c3 6a 00 56 57 ff 75 f0  |h....j...j.VW.u.|
000000a0  e8 92 00 00 00 83 c4 1c  83 fb 34 74 57 83 fb 36  |..........4tW..6|
000000b0  74 45 83 fb 38 74 36 83  fb 32 74 27 83 fb 0a 74  |tE..8t6..2t'...t|
000000c0  0d 68 05 04 00 00 6a 01  6a 03 56 57 eb b0 ff 75  |.h....j.j.VW...u|
000000d0  f0 e8 e7 00 00 00 58 8d  65 f4 5b 5e 5f 5d e9 2b  |......X.e.[^_].+|
000000e0  00 00 00 83 fe 4f 7f d4  83 c6 08 eb cf 83 fe 18  |.....O..........|
000000f0  7e c5 83 ee 08 eb c0 81  ff 93 00 00 00 7f b3 83  |~...............|
00000100  c7 08 eb ae 83 ff 04 7e  a4 83 ef 08 eb 9f ba 04  |.......~........|
00000110  00 00 00 cd 40 57 56 53  ba 05 00 00 00 8b 5c 24  |....@WVS......\$|
00000120  10 8b 74 24 14 8b 7c 24  18 8b 44 24 1c 8b 4c 24  |..t$..|$..D$..L$|
00000130  20 cd 40 5b 5e 5f c3 57  56 55 53 ba 06 00 00 00  | .@[^_.WVUS.....|
00000140  8b 5c 24 14 8b 74 24 18  8b 7c 24 1c 8b 44 24 20  |.\$..t$..|$..D$ |
00000150  8b 4c 24 24 8b 6c 24 28  cd 40 5b 5d 5e 5f c3 57  |.L$$.l$(.@[]^_.W|
00000160  56 55 53 ba 07 00 00 00  8b 5c 24 14 8b 44 24 18  |VUS......\$..D$.|
00000170  8b 4c 24 1c 8b 74 24 20  8b 7c 24 24 8b 6c 24 28  |.L$..t$ .|$$.l$(|
00000180  cd 40 5b 5d 5e 5f c3 53  ba 08 00 00 00 2e 8b 1d  |.@[]^_.S........|
00000190  20 00 00 00 89 d8 05 00  80 00 00 2e 8b 0d 00 00  | ...............|
000001a0  00 00 29 c1 cd 40 5b c3  53 ba 09 00 00 00 2e 8b  |..)..@[.S.......|
000001b0  1d 20 00 00 00 8b 4c 24  08 cd 40 5b c3 53 ba 0e  |. ....L$..@[.S..|
000001c0  00 00 00 8b 5c 24 08 cd  40 5b c3 ba 0f 00 00 00  |....\$..@[......|
000001d0  8b 44 24 04 cd 40 c3 55  89 e5 5d e9 44 fe ff ff  |.D$..@.U..].D...|
000001e0  77 61 6c 6b 00 2a 00                              |walk.*.|

hrbファイルの構造と照らし合わせて逆アセンブル

(qemu) xp /486bi 0x00062000
0x00062000:  00 d0                    addb     %dl, %al
0x00062002:  00 00                    addb     %al, (%eax)
0x00062004:  48                       decl     %eax
0x00062005:  61                       popal    
0x00062006:  72 69                    jb       0x62071
0x00062008:  00 00                    addb     %al, (%eax)
0x0006200a:  00 00                    addb     %al, (%eax)
0x0006200c:  00 04 00                 addb     %al, (%eax, %eax)
0x0006200f:  00 07                    addb     %al, (%edi)
0x00062011:  00 00                    addb     %al, (%eax)
0x00062013:  00 e0                    addb     %ah, %al
0x00062015:  01 00                    addl     %eax, (%eax)
0x00062017:  00 00                    addb     %al, (%eax)
0x00062019:  00 00                    addb     %al, (%eax)
0x0006201b:  e9 b7 01 00 00           jmp      0x621d7;!!!!! このジャンプ命令でアプリの実行開始番地に飛ぶ
・・・長すぎるので略・・・
0x000621d7:  53                       pushl    %ebx;!!!!ここにジャンプ!!!!!
0x000621d8:  ba 00 00 00 8b           movl     $0x8b000000, %edx
0x000621dd:  5c                       popl     %esp
0x000621de:  24 08                    andb     $8, %al
0x000621e0:  00 8b 24 08 cd 08        addb     %cl, 0x8cd0824(%ebx)
0x000621e6:  40                       incl     %eax
0x000621e7:  5b                       popl     %ebx
0x000621e8:  c3                       retl     
0x000621e9:  ba 0f 00 00 8b           movl     $0x8b00000f, %edx
0x000621ee:  44                       incl     %esp
0x000621ef:  04 cd                    addb     $0xcd, %al
0x000621f1:  40                       incl     %eax
0x000621f2:  c3                       retl     
0x000621f3:  40                       incl     %eax
0x000621f4:  c3                       retl     
0x000621f5:  c3                       retl     
0x000621f6:  55                       pushl    %ebp
0x000621f7:  89 fe                    movl     %edi, %esi
0x000621f9:  ff                       .byte    0xff
0x000621fa:  ff 77 61                 pushl    0x61(%edi)
0x000621fd:  ff 77 61                 pushl    0x61(%edi)
0x00062200:  00 00                    addb     %al, (%eax)
・・・ずっと00なので省略
0x00062420:  00 00                    addb     %al, (%eax)

walkは多分処理がリバースエンジニアリングできるほど簡単ではないのでとりあえず今日はこのくらいにしておきます。(hello worldあたりを題材にしておいたほうがよかったなぁ)

わからないこと

このセグメント内容をメモリにロードし終わった後、EIPの初期値を何にするかよくわかりません。0x0006201bまでのバイナリは実行コードではなさそうですし、jumpした番地以外の場所も実行できるプログラムなのか怪しいです。

おまけ

セグメントディスクリプタのエントリは分解された状態で格納されていますが、 これを人間にとって読みやすい形に整形する正規表現でも貼っておきます。

置換前
(0x(.{2})(.{1})(.{1})(.{2})(.{2})(.{4})(.{4}).*)

置換後
$1,$2$6$7,$4$8,$3$5

置換前:0x0040fa06200001e6
置換後:0x0040fa06200001e6,00062000,001e6,4fa

original,base,limit,access_right
の順のcsvになります。

参考