假设在IDA中肉眼怀疑有除法优化,不是所有神密常量都能放狗命中,想纯静态还原出除数,从而得到人类可读的最简除法表达式。此需求在逆向工程中时有碰到,以前写过两篇技术文章,当时IDA F5尚不能还原除数,最近发现IDA F5已能从除法优化中还原除数,伪代码或许有瑕疵,但除数还原正确。若发现IDA F5未能还原除数,可尝试手工还原之,本文从实用角度举例演示。
除法优化汇编模板1/2
/*
* 有符号除法
*/
mov ?,magic_0
imul
sar ?,magic_1
/*
* 此处随位数而变化,依次对应16/32/64位除法
*/
shr ?,15/31/63
add
/*
* 无符号除法
*/
mov ?,magic_0
mul
shr ?,magic_1
一般情况16位除数 pow(2,16+magic_1) // magic_0 + 1
32位除数 pow(2,32+magic_1) // magic_0 + 1
64位除数 pow(2,64+magic_1) // magic_0 + 1
除法优化汇编模板3
/*
* 无符号除法
*/
mov ?,magic_0
.if !carry
mul
.endif
shr ?,magic_1
一般情况16位除数 pow(2,16+magic_1) // magic_0
32位除数 pow(2,32+magic_1) // magic_0
64位除数 pow(2,64+magic_1) // magic_0
除数最后是否加1,不太固定,未进行严格数学推导,上面只是部分经验结论。
某次逆向工程看到:
mov r8, 8080808080808081h
mul r8
shr rdx, 7
与除法优化汇编模板2接近,疑似64位无符号除法优化,尝试还原64位无符号除数:
pow(2,64+magic_1) // magic_0 + 1
pow(2,64+7) // 0x8080808080808081 + 1 = 255
即,上述汇编代码实际执行:
X // 255