如何解释二进制文件的转储?

时间:2018-05-18 03:07:44

标签: assembly x86-64 reverse-engineering objdump

考虑转储二进制文件(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 :(得分:3)

如果使用调试信息进行编译,则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_RTS0x3,当mov $3, %eax为零时,有一个测试/ je跳过一对mov $3, %ecx / %esi条指令,所以那是if(raise)分支。第二个整数函数arg在x86-64 System V调用约定中的RSI / ESI中传递,因此raise除非它被早先的call或其他你用{{1}隐藏的东西所破坏。 }}

这两条...说明可能是通过将mov分配给其他内容来解释的,但我没有尝试完全遵循逻辑。