修复switch
相关链接:
Igor’s tip of the week #53: Manual switch idioms – Hex Rays (hex-rays.com)
IDA switch 在跳表结构下的修复 - blog of chuj (cjovi.icu)
举例:
__int64 __fastcall PayloadProfiler::qt_static_metacall(__int64 a1, int a2, unsigned int a3)
{
__int64 result; // rax
__endbr64();
if ( !a2 && a3 <= 5 )
// switch
return ((__int64 (*)(void))((char *)dword_91C980 + dword_91C980[a3]))();
return result;
}
修复:
将光标放在间接分支上并调用 Edit > Other > 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 指令附近,特征就是判断了输入,然后跳转到某个地址上,跳转的这个地址就是要填的值了(上图中填的值是错误的,但是即使填错了似乎也没有影响最后的分析,所以可以放轻松啦~)。
修复后