Add a rule to simplify constant earlier in decompilation

This commit is contained in:
Boris Batteux
2021-02-18 15:33:05 +01:00
parent fd923d1d42
commit 388f7fa241
2 changed files with 37 additions and 0 deletions

View File

@@ -12,6 +12,7 @@ from d810.optimizers.instructions.pattern_matching.rewrite_or import *
from d810.optimizers.instructions.pattern_matching.rewrite_sub import *
from d810.optimizers.instructions.pattern_matching.rewrite_xor import *
from d810.optimizers.instructions.pattern_matching.weird import *
from d810.optimizers.instructions.pattern_matching.experimental import *
PATTERN_MATCHING_RULES = [x() for x in get_all_subclasses(PatternMatchingRule)]

View File

@@ -0,0 +1,36 @@
from ida_hexrays import *
from d810.optimizers.instructions.pattern_matching.handler import PatternMatchingRule
from d810.ast import AstLeaf, AstConstant, AstNode
from d810.hexrays_formatters import format_mop_t
class ReplaceMovHigh(PatternMatchingRule):
PATTERN = AstNode(m_mov,
AstConstant('c_0'))
REPLACEMENT_PATTERN = AstNode(m_or, AstConstant("new_c_0"), AstNode(m_and, AstLeaf("new_reg"), AstConstant("mask")))
def check_candidate(self, candidate):
# IDA does not do constant propagation for pattern such as:
# mov #0x65A4.2, r6.2
# mov #0x210F.2, r6^2.2
# jz r0.4, r6.4
# Thus, we try to detect mov to r6^2 and replace by (or #0x210F0000.4, r6.4 & 0x0000ffff.4, r6.4
# By doing that, IDA constant propagation will work again.
if candidate.dst_mop.t != mop_r:
return False
dst_reg_name = format_mop_t(candidate.dst_mop)
if dst_reg_name is None:
return False
if "^2" in dst_reg_name:
if candidate["c_0"].mop.size != 2:
return False
candidate.add_constant_leaf("new_c_0", candidate["c_0"].value << 16, 4)
candidate.add_constant_leaf("mask", 0xffff, 4)
new_dst_reg = mop_t()
new_dst_reg.make_reg(candidate.dst_mop.r - 2, 4)
candidate.add_leaf("new_reg", new_dst_reg)
candidate.dst_mop = new_dst_reg
return True
else:
return False