IDA switch 在跳表结构下的修复

Posted on May 22, 2021

今天协会打了一场内部 AWD,第一次参加这样的比赛,确实有不少手忙脚乱的地方,也有学到许多新知识。

PWN 总共有两题,其中一题虚拟机类题由于有较大的 switch 结构,而 gcc 在编译超过 5 个 case 的 switch 时就会用跳表来优化,F5 之后一般会变成下面这个样子

也就是 IDA 无法分析出这是一个 switch 结构,这就会导致大量的代码丢失。修复的方法是使用 Edit->Other 中的 Specify switch idiom 功能。

首先将光标置于获取跳表值的语句上

找这条语句的方法一般可以现在反编译(C 伪代码)界面中将光标置于 JUMPOUT 语句,然后按 tab 就可以转到 jmp rax 处,在此语句上方就可以找到明显的类似数组寻址的代码,这就是获取跳表值得语句了。

然后打开 Specify switch idiom

对其中得每项进行设置

  • Address of Jump table:设置成 jump table 的地址
  • Number of elements:设置为 jump table 中存在的元素总数
  • Size of table element:设置为 jump table 中元素的类型
  • Element shift amount:这个一般情况下都是零,和跳表计算时的方式有关,比如此题只是单纯的跳表地址加跳表中的元素,那么就不需要移位
  • Element base value:设置为计算跳转地址时给跳表元素加的值,比如此题的计算方法为 &jump_table + jump_table[i],那么这里就应该填跳表的地址
  • Start of the switch idiom:这个默认就行,就是获取跳表值的语句的地址
  • Input register of switch:设置为用于给跳表寻址的寄存器
  • First(lowest) input value:就是 switch 的最小值了
  • Default jump address:也就是 default 的跳转位置,其实有时候可以不填,但是最好还是填上,这个一般在上方不远处的 cmp 指令附近,特征就是判断了输入,然后跳转到某个地址上,跳转的这个地址就是要填的值了(上图中填的值是错误的,但是即使填错了似乎也没有影响最后的分析,所以可以放轻松啦~)。

然后需要看情况勾选 Signed jump table elements,比如此题

跳表中存储的是负数,那么就需要勾选这个选项。完成之后按下确定,F5 之后就可以获得 switch 结构了