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찾을 수 없습니다.

따라서 내가 원하는 출력은 다음과 같습니다(한 줄에 모두 포함).

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 출력의 들어오는 줄의 모든 "단어"(공백으로 구분된 텍스트 블록)를 검사하고 그것이 두 자리 16진수인지 검사합니다. 그렇다면 인쇄됩니다. 그렇지 않다면 아무 일도 일어나지 않을 것입니다. 이렇게 발견된 인쇄된 16진수는 OFS출력 필드 구분 기호로 구분됩니다(기본값은 공백). 입력 끝에 개행만 인쇄합니다( print문은 자동으로 "출력 레코드 구분 기호"를 추가하며 기본값은 개행이므로 "없음"을 인쇄하는 것은 개행을 출력하는 것과 동일합니다). 따라서 모든 16진수는 하나의 숫자로 표시됩니다. space 별도의 스트림.

이는 제공한 예제 GDB 출력에서 ​​작동하지만 다른 곳에 "길지 않은" 두 개의 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

관련 정보