GDB逆アセンブリ:生のバイナリデータのみを印刷します(columnとawkを使用)。

GDB逆アセンブリ:生のバイナリデータのみを印刷します(columnとawkを使用)。

gdb逆アセンブリ出力から生のバイナリデータのみを取得しようとしています。私の現在の出力は次のとおりです。

$ gdb -batch -ex "disassemble/r btif_set_adapter_property" libbluetooth_qti.so | column -ts $'\t'
Dump of assembler code for function _Z25btif_set_adapter_propertyPK13bt_property_t:
   0x0011e8c1 <+0>:                                                                  e9 f0 41 c8 b0                 jmp    0xb0da2ab6
   0x0011e8c6 <+5>:                                                                  04 46                          add    $0x46,%al
   0x0011e8c8 <+7>:                                                                  67 48                          addr16 dec %eax
   0x0011e8ca <+9>:                                                                  c0 ef 50                       shr    $0x50,%bh
   0x0011e8cd <+12>:                                                                 00 00                          add    %al,(%eax)
   0x0011e8cf <+14>:                                                                 21 78 44                       and    %edi,0x44(%eax)
   0x0011e8d2 <+17>:                                                                 07                             pop    %es
   0x0011e8d3 <+18>:                                                                 68 38 68 47 90                 push   $0x90476838
   0x0011e8d8 <+23>:                                                                 02 a8 40 f9 cd 0a              add    0xacdf940(%eax),%ch
   0x0011e8de <+29>:                                                                 01 60 08                       add    %esp,0x8(%eax)
   0x0011e8e1 <+32>:                                                                 a8 f9                          test   $0xf9,%al
   0x0011e8e3 <+34>:                                                                 21 51 f1                       and    %edx,-0xf(%ecx)
   0x0011e8e6 <+37>:                                                                 62                             (bad)  
   0x0011e8e7 <+38>:                                                                 ea 60 48 d4 e9 00 23           ljmp   $0x2300,$0xe9d44860

奇妙なことは、まだ列をタブで区切らず、タブのように見える空白で区切ることです。だからここでは使用できません| awk '{print $2}'

次の問題は、生のバイナリデータの長さが異なり、列2..8に必要な生のバイナリデータが含まれる可能性があることです。

私の考えは複雑すぎるかもしれません。組み込みの方法がありますが、gdb見つかりません。

したがって、私が望む出力は次のようになります(1行にすべてを含む)。

e9 f0 41 c8 b0 04 46 67 48 c0 ef 50 00 00 21 78 44 07 68 38 68 47 90 02 a8 40 f9 cd 0a 01 60 08 a8 f9 21 51 f1 62 ea 60 48 d4 e9 00 23

編集:gdb自己出力:

$ gdb -batch -ex "disassemble/r btif_set_adapter_property" libbluetooth_qti.so
Dump of assembler code for function _Z25btif_set_adapter_propertyPK13bt_property_t:
   0x0011e8c1 <+0>: e9 f0 41 c8 b0  jmp    0xb0da2ab6
   0x0011e8c6 <+5>: 04 46   add    $0x46,%al
   0x0011e8c8 <+7>: 67 48   addr16 dec %eax
   0x0011e8ca <+9>: c0 ef 50    shr    $0x50,%bh
   0x0011e8cd <+12>:    00 00   add    %al,(%eax)
   0x0011e8cf <+14>:    21 78 44    and    %edi,0x44(%eax)
   0x0011e8d2 <+17>:    07  pop    %es
   0x0011e8d3 <+18>:    68 38 68 47 90  push   $0x90476838
   0x0011e8d8 <+23>:    02 a8 40 f9 cd 0a   add    0xacdf940(%eax),%ch
   0x0011e8de <+29>:    01 60 08    add    %esp,0x8(%eax)
   0x0011e8e1 <+32>:    a8 f9   test   $0xf9,%al
   0x0011e8e3 <+34>:    21 51 f1    and    %edx,-0xf(%ecx)
   0x0011e8e6 <+37>:    62  (bad)  
   0x0011e8e7 <+38>:    ea 60 48 d4 e9 00 23    ljmp   $0x2300,$0xe9d44860

答え1

フィールドがコロンまたはスペースと余分なスペースで区切られているように見えるので、それに応じてFSを設定します。

$ awk -F'[: ] +' 'NR>1{o=(o=="" ? "" : o OFS) $3} END{print o}' file
e9 f0 41 c8 b0 04 46 67 48 c0 ef 50 00 00 21 78 44 07 68 38 68 47 90 02 a8 40 f9 cd 0a 01 60 08 a8 f9 21 51 f1 62 ea 60 48 d4 e9 00 23

答え2

GDB出力をパイピングできる幸運があるかもしれませんawk

awk '{for (i=1;i<=NF;i++) if ($i~/^[a-f0-9]{2}$/) printf("%s%s",$i,OFS)} END{print ""}' 

これは、GDB出力の着信行のすべての「単語」(スペースで区切られたテキストブロック)を調べ、それが2桁の16進数であることを確認します。その場合は印刷されます。そうでなければ何も起こらないでしょう。このように見つかった印刷された16進数は、OFS出力フィールド区切り文字で区切られます(デフォルトは空白)。入力の末尾に改行のみを印刷します(printステートメントは自動的に「出力レコード区切り記号」を追加し、デフォルトは改行なので、「なし」を印刷することは改行を出力するのと同じです)。したがって、すべての16進数は1つの数字で表されます。 space 別のストリーム。

これは、提供された例のGDB出力で動作しますが、他の場所に「長くない」2つの16進数がある場合は、出力にも表示されます。

答え3

PCRE正規表現をサポートするGNU grepを使用して情報を抽出し、他のLinuxユーティリティを使用して後処理できます。 file はファイルに保存された gdb コマンドの出力です。

< file \
grep -Po ':\s*((\s\S+)+)\s{2}' |
paste -s - | tr -s '\t :' ' '  |
sed -E 's/^ | $//g'

Perlはこれを抽出できます:

perl -ne '
  print(($"x!!$a++),$1) if /:\s+(\S.*?\S)\s{2}/;
  }{printf $/;
' file

出力:

e9 f0 41 c8 b0 04 46 67 48 c0 ef 50 00 00 21 78 44 07 68 38 68 47 90 02 a8 40 f9 cd 0a 01 60 08 a8 f9 21 51 f1 62 ea 60 48 d4 e9 00 23

python3 -c 'import sys
ifile = sys.argv[1]
L = []
with open(ifile) as fh:
  for l in fh:
    ln = l.rstrip()
    if ln.find(":") < 0: continue
    f1 = ln.split(":",1)[1].lstrip()
    L += f1[0:f1.find("  ")].split()
print(*L)
' file

GNU sedストリームエディタは拡張正規表現モードで開きます。

sed -En '
  s/:\s*((\s[[:xdigit:]]{2})+)\s{2}/\n\1\n/;T
  s/.*\n\s(.*)\n.*/\1/;H
  $!d;g;s/.//;s/\s+/ /gp
' file

関連情報