如何解释二进制文件的转储?
How to interpret a dump of binary file?
考虑二进制文件 (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 [=10=]x20,%rdi
25fd: 85 f6 test %esi,%esi
25ff: 74 3c je 263d <acm_port_dtr_rts+0x4d>
2601: b8 03 00 00 00 mov [=10=]x3,%eax
2606: b9 03 00 00 00 mov [=10=]x3,%ecx
260b: f6 83 60 08 00 00 40 testb [=10=]x40,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 [=10=]x22,%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 [=10=]x2,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 [=10=]x0,%rsi
264e: 5b pop %rbx
264f: 48 83 c7 30 add [=10=]x30,%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
如果使用调试信息进行编译,则 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
,并且有一个 test/je 在 %esi
时跳过几个 mov , %eax
/ mov , %ecx
指令] 为零,所以这是 if(raise)
分支。在 x86-64 System V 调用约定中,第二个整数函数 arg 在 RSI/ESI 中传递,所以它是 raise
除非它被较早的 call
或您用 [ 隐藏的其他东西破坏=23=].
这两个mov
指令可能是通过将val
分配给其他东西来解释的,但我还没有尝试完全遵循逻辑。
考虑二进制文件 (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 [=10=]x20,%rdi
25fd: 85 f6 test %esi,%esi
25ff: 74 3c je 263d <acm_port_dtr_rts+0x4d>
2601: b8 03 00 00 00 mov [=10=]x3,%eax
2606: b9 03 00 00 00 mov [=10=]x3,%ecx
260b: f6 83 60 08 00 00 40 testb [=10=]x40,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 [=10=]x22,%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 [=10=]x2,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 [=10=]x0,%rsi
264e: 5b pop %rbx
264f: 48 83 c7 30 add [=10=]x30,%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
如果使用调试信息进行编译,则 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
,并且有一个 test/je 在 %esi
时跳过几个 mov , %eax
/ mov , %ecx
指令] 为零,所以这是 if(raise)
分支。在 x86-64 System V 调用约定中,第二个整数函数 arg 在 RSI/ESI 中传递,所以它是 raise
除非它被较早的 call
或您用 [ 隐藏的其他东西破坏=23=].
这两个mov
指令可能是通过将val
分配给其他东西来解释的,但我还没有尝试完全遵循逻辑。