Loading... 今天协会打了一场内部 AWD,第一次参加这样的比赛,确实有不少手忙脚乱的地方,也有学到许多新知识。 PWN 总共有两题,其中一题虚拟机类题由于有较大的 switch 结构,而 gcc 在编译超过 5 个 case 的 switch 时就会用跳表来优化,F5 之后一般会变成下面这个样子 <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/05/3400925312.png "></div> 也就是 IDA 无法分析出这是一个 switch 结构,这就会导致大量的代码丢失。修复的方法是使用 Edit->Other 中的 Specify switch idiom 功能。 首先将光标置于获取跳表值的语句上 <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/05/1829874143.png "></div> 找这条语句的方法一般可以现在反编译(C 伪代码)界面中将光标置于 `JUMPOUT` 语句,然后按 tab 就可以转到 `jmp rax` 处,在此语句上方就可以找到明显的类似数组寻址的代码,这就是获取跳表值得语句了。 然后打开 `Specify switch idiom` <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/05/558521461.png "></div> 对其中得每项进行设置 * 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,比如此题 <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/05/2454325625.png "></div> 跳表中存储的是负数,那么就需要勾选这个选项。完成之后按下确定,F5 之后就可以获得 switch 结构了 <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/05/3017369985.png "></div> 最后修改:2021 年 11 月 20 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 1 如果觉得我的文章对你有用,那听听上面我喜欢的歌吧