Как интерпретировать дамп двоичного файла? - PullRequest
0 голосов
/ 18 мая 2018

Рассмотрим следующую часть вывода из дампа двоичного файла (amd64):

$ objdump -D /lib/modules/4.16.0-1-amd64/kernel/drivers/usb/class/cdc-acm.ko
...
25f0:       e8 00 00 00 00          callq  25f5 <acm_port_dtr_rts+0x5>
25f5:       53                      push   %rbx
25f6:       48 89 fb                mov    %rdi,%rbx
25f9:       48 83 ef 20             sub    $0x20,%rdi
25fd:       85 f6                   test   %esi,%esi
25ff:       74 3c                   je     263d <acm_port_dtr_rts+0x4d>
2601:       b8 03 00 00 00          mov    $0x3,%eax
2606:       b9 03 00 00 00          mov    $0x3,%ecx
260b:       f6 83 60 08 00 00 40    testb  $0x40,0x860(%rbx)
2612:       89 83 94 07 00 00       mov    %eax,0x794(%rbx)
2618:       75 18                   jne    2632 <acm_port_dtr_rts+0x42>
261a:       48 8d 73 e8             lea    -0x18(%rbx),%rsi
261e:       45 31 c9                xor    %r9d,%r9d
2621:       45 31 c0                xor    %r8d,%r8d
2624:       ba 22 00 00 00          mov    $0x22,%edx
2629:       e8 32 eb ff ff          callq  1160 <acm_ctrl_msg.isra.10>
262e:       85 c0                   test   %eax,%eax
2630:       74 09                   je     263b <acm_port_dtr_rts+0x4b>
2632:       f6 83 1c 08 00 00 02    testb  $0x2,0x81c(%rbx)
2639:       75 08                   jne    2643 <acm_port_dtr_rts+0x53>
263b:       5b                      pop    %rbx
263c:       c3                      retq
263d:       89 f1                   mov    %esi,%ecx
263f:       31 c0                   xor    %eax,%eax
2641:       eb c8                   jmp    260b <acm_port_dtr_rts+0x1b>
2643:       48 8b 7b e8             mov    -0x18(%rbx),%rdi
2647:       48 c7 c6 00 00 00 00    mov    $0x0,%rsi
264e:       5b                      pop    %rbx
264f:       48 83 c7 30             add    $0x30,%rdi
2653:       e9 00 00 00 00          jmpq   2658 <acm_port_dtr_rts+0x68>
2658:       0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
265f:       00
...

Следующая часть из cdc-acm.c соответствует приведенному выше дампу:

static void acm_port_dtr_rts(struct tty_port *port, int raise)
{
  struct acm *acm = container_of(port, struct acm, port);
  int val;
  int res;

  if (raise)
        val = ACM_CTRL_DTR | ACM_CTRL_RTS;
  else
        val = 0;

  acm->ctrlout = val;

  res = acm_set_control(acm, val);
  if (res && (acm->ctrl_caps & USB_CDC_CAP_LINE))
        dev_err(&acm->control->dev, "failed to set dtr/rts\n");
}

Также здесь используются следующие константы:

#define ACM_CTRL_DTR            0x01
#define ACM_CTRL_RTS            0x02

Как узнать, какая строка в дампе соответствует следующей строке из исходного кода?

val = ACM_CTRL_DTR | ACM_CTRL_RTS;

РЕДАКТИРОВАТЬ

Следующая процедура была использована для изменения двоичного файла:

hexdump -v -e "1/1 \" %02x\n\"" cdc-acm.ko.orig >text_file
<edit text_file>
xxd -r -p text_file cdc-acm.ko

1 Ответ

0 голосов
/ 18 мая 2018

Если вы скомпилировали с отладочной информацией, тогда objdump -d -S для чередования строк исходного текста с asm.gdb может использовать внешние символы отладки (например, из linux-image-4.16.0-1-amd64-dbg), но я не думаю, что это полезно для разборки модулей ядра.

Я не уверен, как сказать objdump искать / использоватьих.См. https://www.technovelty.org/code/separate-debug-info.html для получения дополнительной информации о отдельной отладочной информации, но ничего не говорится о objdump -S, использующем их, только GDB.


В противном случае ACM_CTRL_DTR | ACM_CTRL_RTS равно 0x3, и есть тест / je, который пропускает пару mov $3, %eax / mov $3, %ecx инструкций, когда что-то %esi равно нулю, так что это if(raise) ветвь.2-я целочисленная функция arg передается в RSI / ESI в соглашении о вызовах System V x86-64, так что это raise, если только оно не было забито более ранним call или чем-то другим, что вы спрятали с помощью ....

Две mov инструкции, вероятно, объясняются присвоением val чему-то еще, но я не пытался полностью следовать логике.

...