【发布时间】:2017-03-29 20:09:47
【问题描述】:
我正在尝试对一些程序集进行逆向工程,我已经做到了这一点:
40073f: 89 45 fc mov %eax,-0x4(%rbp)
400742: 83 7d fc 05 cmpl $0x5,-0x4(%rbp)
400746: 77 37 ja 40077f <f51+0x85>
400748: 8b 45 fc mov -0x4(%rbp),%eax
40074b: 48 8b 04 c5 28 09 40 mov 0x400928(,%rax,8),%rax
400752: 00
400753: ff e0 jmpq *%rax
400755: b8 11 00 00 00 mov $0x11,%eax
40075a: eb 28 jmp 400784 <f51+0x8a>
40075c: b8 12 00 00 00 mov $0x12,%eax
400761: eb 21 jmp 400784 <f51+0x8a>
400763: b8 13 00 00 00 mov $0x13,%eax
400768: eb 1a jmp 400784 <f51+0x8a>
40076a: b8 14 00 00 00 mov $0x14,%eax
40076f: eb 13 jmp 400784 <f51+0x8a>
400771: b8 15 00 00 00 mov $0x15,%eax
400776: eb 0c jmp 400784 <f51+0x8a>
400778: b8 16 00 00 00 mov $0x16,%eax
40077d: eb 05 jmp 400784 <f51+0x8a>
40077f: b8 0a 00 00 00 mov $0xa,%eax
400784: 5d pop %rbp
400785: c3 retq
我可以看到我在这里看到的是一个 switch 语句,其中默认情况是 -0x4(%rbp) > 5,但我对一些指令感到困惑:
40074b 是否只是转到跳转表上的某个位置并将该指令推入 rax,以便我们可以在之后跳转到 switch case 中的正确位置(即第 400753 行)?
在这种情况下,我不知道如何解释我们的不同案例。如果我的理解是正确的,跳转表从地址 400928 开始,我看到:
400928: 55 push %rbp
400929: 07 (bad)
40092a: 40 00 00 add %al,(%rax)
40092d: 00 00 add %al,(%rax)
40092f: 00 5c 07 40 add %bl,0x40(%rdi,%rax,1)
400933: 00 00 add %al,(%rax)
400935: 00 00 add %al,(%rax)
400937: 00 63 07 add %ah,0x7(%rbx)
40093a: 40 00 00 add %al,(%rax)
40093d: 00 00 add %al,(%rax)
40093f: 00 6a 07 add %ch,0x7(%rdx)
400942: 40 00 00 add %al,(%rax)
400945: 00 00 add %al,(%rax)
400947: 00 71 07 add %dh,0x7(%rcx)
40094a: 40 00 00 add %al,(%rax)
40094d: 00 00 add %al,(%rax)
40094f: 00 78 07 add %bh,0x7(%rax)
400952: 40 00 00 add %al,(%rax)
400955: 00 00 add %al,(%rax)
在这一点上,我几乎不知道我在看什么。大概使用第 400753 行,我们会跳转到该表中的某个位置,但是然后呢?还是我的理解完全不对?
【问题讨论】:
-
.rodata 中有 0x400928 吗?如果它只是在 .text 部分中,与代码混合,那很奇怪。通常,出于性能原因,您会将数据和代码单独分组,因为 CPU 具有拆分缓存(以及单独的 dTLB / iTLB)。
-
它在 .rodata 中
-
好的,所以你必须使用
-D或其他东西来反汇编那个非代码。现在您知道为什么您的工具不想为您拆卸它:P -
使用 -D 是我在第二个代码块中找到指令的方式。
-
就像 Wumpus 的回答所说,它们不是说明。这就是为什么
-d不会分解它们的原因。
标签: assembly x86 switch-statement gnu-assembler jump-table