Как просто напечатать двоичный код функции в объектном файле? - PullRequest
0 голосов
/ 19 февраля 2019

Я могу разобрать объектный файл, как показано ниже.Но я хотел бы просто сбросить необработанное число, например 55, 48, ... инструкций в двоичном формате для конкретной функции, например, add4, в файл.

Я мог бы написать программу дляразбирать вывод otool.Но есть ли более простой способ сделать это?

Моя ОС - Mac OS X.

$ cat add.c
long x;
long add2(long num) {
  return num + 2;
}
long add4(long num) {
  return num + 4;
}
$ clang -c -o add.o add.c
$ otool -tvjV add.o 
add.o:
(__TEXT,__text) section
_add4:
0000000000000000    55  pushq   %rbp
0000000000000001    48 89 e5    movq    %rsp, %rbp
0000000000000004    48 89 7d f8     movq    %rdi, -0x8(%rbp)
0000000000000008    48 8b 7d f8     movq    -0x8(%rbp), %rdi
000000000000000c    48 83 c7 04     addq    $0x4, %rdi
0000000000000010    48 89 f8    movq    %rdi, %rax
0000000000000013    5d  popq    %rbp
0000000000000014    c3  retq
0000000000000015    66 2e 0f 1f 84 00 00 00 00 00   nopw    %cs:_add4(%rax,%rax)
000000000000001f    90  nop
_add2:
0000000000000020    55  pushq   %rbp
0000000000000021    48 89 e5    movq    %rsp, %rbp
0000000000000024    48 89 7d f8     movq    %rdi, -0x8(%rbp)
0000000000000028    48 8b 7d f8     movq    -0x8(%rbp), %rdi
000000000000002c    48 83 c7 02     addq    $0x2, %rdi
0000000000000030    48 89 f8    movq    %rdi, %rax
0000000000000033    5d  popq    %rbp
0000000000000034    c3  retq

Ответы [ 2 ]

0 голосов
/ 14 марта 2019

Вы можете использовать objdump, а затем извлечь часть кода операции.Это можно сделать следующим образом.

$ objdump -d add.o | grep add4 -A10 | cut -f 2 | grep -v ':'

Флаг -v для grep указывает на печать всех строк без двоеточия.

Вывод:

    55                   
    48 89 e5             
    48 89 7d f8          
    48 8b 45 f8          
    48 83 c0 04          
    5d                
    c3

-A10 предписывает grep печатать 10 строк после совпадения.

Теперь, чтобы вывести это в файл, мы сначала отформатируем коды операций в шестнадцатеричном виде, как '\ x45'.Приведенный выше вывод может иметь несколько пробелов и пробел в конце каждой строки, поэтому мы сначала удаляем их, так как они могут испортить наш sed.

$ objdump -d add.o | grep add4 -A10 | cut -f 2 | grep -v ':' | sed 's/ */ /g' | sed 's/ $//g'

Добавьте '\ x'часть, сначала для пробелов между ними, а затем для первого гекса в каждой строке.

$ objdump -d add.o | grep add4 -A10 | cut -f 2 | grep -v ':' | sed 's/ */ /g' | sed 's/ $//g' | sed 's/ /\\x/g' | sed 's/^/\\x/g'

\x55
\x48\x89\xe5
\x48\x89\x7d\xf8
\x48\x8b\x45\xf8
\x48\x83\xc0\x04
\x5d
\xc3

Сверните все это в одну строку и добавьте кавычки.

$ objdump -d add.o | grep add4 -A10 | cut -f 2 | grep -v ':' | sed 's/ */ /g' | sed 's/ $//g' | sed 's/ /\\x/g' | sed 's/^/\\x/g' | tr -d '\n' | sed 's/^/\"/g' | sed 's/$/\"/g'

"\x55\x48\x89\xe5\x48\x89\x7d\xf8\x48\x8b\x45\xf8\x48\x83\xc0\x04\x5d\xc3"

Теперь мы получили строку в стиле C и просто передаем ее в printf, а затем перенаправляем вывод в файл.

$ printf $(objdump -d add.o | grep add4 -A10 | cut -f 2 | grep -v ':' | sed 's/ */ /g' | sed 's/ $//g' | sed 's/ /\\x/g' | sed 's/^/\\x/g' | tr -d '\n' | sed 's/^/\"/g' | sed 's/$/\"/g') | sed 's/^\"//g' | sed 's/\"$//g' > add4.bin

Последние два seds после printf должны удалить кавычки, которые по какой-то причине остаются в выводе printf.

Зашифровывая файл, который мы получаем:

$ hexdump -C add4.bin

00000000  55 48 89 e5 48 89 7d f8  48 8b 45 f8 48 83 c0 04  |UH..H.}.H.E.H...|
00000010  5d c3                                             |].|
00000012
0 голосов
/ 19 февраля 2019

Вы можете использовать nm -nU add.o для получения адресов символов.Вы можете найти интересующий символ и получить его адрес и последующий адрес.Это дает вам начало и (примерно) длину символа.Затем вы можете использовать любой инструмент для шестнадцатеричного дампа из файла, чтобы прочитать только эту часть.

Например:

exec 3< <(nm -nU add.o | grep -A1 -w _add4 | cut -d ' ' -f 1)
read start <&3
read end <&3
3<&-
offset=$(otool -lV add.o | grep -A3 -w "segname __TEXT" | grep -m1 offset | cut -c 12-)
if [ -n "$end" ] ; then length_arg="-n $(( "0x$end" - "0x$start" ))" ; fi
hexdump -C -s $((0x$start + $offset)) $length_arg add.o
...