C 解释程序集跳转表
我试图逐行解释这个汇编代码在做什么,但当我看到这个汇编中的跳转表时,我发现自己真的很困惑。这是从教科书练习题3.63中获取的,但没有对它进行解释-因此我在这里问它。目标是对提供的程序集列表进行反向工程,并编写能够生成它的C代码(feel switch语句体)。请帮助:( 教科书是:Randal E.Bryant,David R.O'Hallaron-计算机系统。程序员的观点[3版](2016,Pearson) 问题3.63C 解释程序集跳转表,c,assembly,x86,switch-statement,jump-table,C,Assembly,X86,Switch Statement,Jump Table,我试图逐行解释这个汇编代码在做什么,但当我看到这个汇编中的跳转表时,我发现自己真的很困惑。这是从教科书练习题3.63中获取的,但没有对它进行解释-因此我在这里问它。目标是对提供的程序集列表进行反向工程,并编写能够生成它的C代码(feel switch语句体)。请帮助:( 教科书是:Randal E.Bryant,David R.O'Hallaron-计算机系统。程序员的观点[3版](2016,Pearson) 问题3.63 long switch_prob(long x, long n) {
long switch_prob(long x, long n) {
long result = x;
switch(n) {
/* Fill in code here */
}
return result;
}
我不知道如何“解码”它或如何知道它指向哪里
0000000000400590 <switch_prob>:
400590: 48 83 ee 3c sub $0x3c,%rsi
400594: 48 83 fe 05 cmp $0x5,%rsi
400598: 77 29 ja 4005c3 <switch_prob+0x33>
40059a: ff 24 f5 f8 06 40 00 jmpq *0x4006f8(,%rsi,8)
4005a1: 48 8d 04 fd 00 00 00 lea 0x0(,%rdi,8),%rax
4005a8: 00
4005a9: c3 retq
4005aa: 48 89 f8 mov %rdi,%rax
4005ad: 48 c1 f8 03 sar $0x3,%rax
4005b1: c3 retq
4005b2: 48 89 f8 mov %rdi,%rax
4005b5: 48 c1 e0 04 shl $0x4,%rax
4005b9: 48 29 f8 sub %rdi,%rax
4005bc: 48 89 c7 mov %rax,%rdi
4005bf: 48 0f af ff imul %rdi,%rdi
4005c3: 48 8d 47 4b lea 0x4b(%rdi),%rax
4005c7: c3 retq
0000000000 400590:
400590:48 83 ee 3c子$0x3c,%rsi
400594:48 83 fe 05 cmp$0x5,%rsi
400598:77 29 ja 4005c3
40059a:ff 24 f5 f8 06 40 00 jmpq*0x4006f8(,%rsi,8)
4005a1:48 8d 04 fd 00 00 lea 0x0(,%rdi,8),%rax
4005a8:00
4005a9:c3 retq
4005aa:48 89 f8 mov%rdi,%rax
4005ad:48 c1 f8 03 sar$0x3,%rax
4005b1:c3 retq
4005b2:48 89 f8 mov%rdi,%rax
4005b5:48 c1 e0 04 shl$0x4,%rax
4005b9:48 29 f8子%rdi,%rax
4005bc:48 89 c7 mov%rax%rdi
4005bf:48 0f af ff imul%rdi,%rdi
4005c3:48 8d 47 4b lea 0x4b(%rdi),%rax
4005c7:c3 retq
跳转表位于不同的内存区域。从第5行的间接跳转可以看出,跳转表从地址0x4006f8开始。使用GDB调试器,我们可以使用命令x/6gx 0x4006f8检查组成跳转表的六个8字节内存字。GDB打印以下内容:
(gdb)x/6gx 0x4006f80x4006f8:0x00000000004005a1 0x00000000004005c3
0x400708:0x00000000004005a1 0x00000000004005aa
0x400718:0x00000000004005b2 0x00000000004005bf 我了解该行40059a:ff 24 f5 f8 06 40 00 jmpq*0x4006f8(,%rsi,8)
正在跳到桌子上,但我不确定如何
1) 解释跳转表[每个地址对应什么,6个值中的每个值对应什么
平均/保持]
2) 对其进行反向工程,以获得switch语句的不同情况 感谢您的帮助:)显然有(5或)6个
案例
s个连续值,以及无处不在的默认值
跳转表包含每个案例的一个地址,您将在列表中找到这些地址
例如,0x00000000004005a1是该部件的地址:
4005a1: 48 8d 04 fd 00 00 00 lea 0x0(,%rdi,8),%rax
4005a8: 00
4005a9: c3 retq
由于表中的第二项指向与默认值相同的地址(由cmp$0x5、%rsi
和ja 4005c3
检测),因此我们可以假设未明确列出此案例。这就是为什么它可能只有5个case
s
减去的值0x3c可能是字符,因为您有一个空开关,所以它应该不会生成任何跳转表。因此,请更新您的问题或提供您实际使用的代码。@th33lf关键是填写(逆向工程)空开关块。代码基本上是goto table[rsi-0x3c]
。这对你来说足够了吗?条目对应于处理特定案例的代码地址
请确保你没有使用本书的国际版-它的练习中充满了众所周知的严重错误和完全胡说八道的代码。谢谢你,我明白了!)现在我想知道如何得到开关盒的值?我说第三列的值就是这个案例结束的地址,对吗?如果是这样的话,你怎么知道如果开关箱没有破裂是5个;在它们之间(这就是为什么我猜表中只有3个地址?)第3列的值是什么意思?@MeganDarcy如果您考虑第一条和第二条指令,您可以推断出各种大小写值,从0x400590开始。@MeganDarcy-您可以从busybee提到的减去值0x3c和上限5中推断出开关箱的各种值,因此它们是60,(61,)62,63,64,65。(61是多余的,因为它“指向”默认情况。)@Armali好的,很好,我知道了,谢谢!!