class And_OllvmRule_1(PatternMatchingRule): PATTERN = AstNode(m_and, AstNode(m_or, AstLeaf('x_0'), AstLeaf('x_1')), AstNode(m_bnot, AstNode(m_xor, AstLeaf('x_0'), AstLeaf('x_1')))) REPLACEMENT_PATTERN = AstNode(m_and, AstLeaf('x_0'), AstLeaf('x_1'))
class And_HackersDelightRule_3(PatternMatchingRule): PATTERN = AstNode(m_sub, AstNode(m_add, AstLeaf("x_0"), AstLeaf("x_1")), AstNode(m_or, AstLeaf("x_0"), AstLeaf("x_1"))) REPLACEMENT_PATTERN = AstNode(m_and, AstLeaf("x_0"), AstLeaf("x_1"))
class Bnot_XorRule_1(PatternMatchingRule): PATTERN = AstNode(m_or, AstNode(m_and, AstLeaf("x_0"), AstLeaf("x_1")), AstNode(m_bnot, AstNode(m_or, AstLeaf("x_0"), AstLeaf("x_1")))) REPLACEMENT_PATTERN = AstNode(m_bnot, AstNode(m_xor, AstLeaf("x_0"), AstLeaf("x_1")))
class Or_OllvmRule_1(PatternMatchingRule): PATTERN = AstNode( m_or, AstNode(m_and, AstLeaf("x_0"), AstLeaf("x_1")), AstNode(m_bnot, AstNode(m_xor, AstLeaf("bnot_x_0"), AstLeaf("x_1")))) REPLACEMENT_PATTERN = AstNode(m_or, AstLeaf("x_0"), AstLeaf("x_1")) def check_candidate(self, candidate): if not equal_bnot_mop(candidate["x_0"].mop, candidate["bnot_x_0"].mop): return False return True
class Sub1Or_MbaRule_1(PatternMatchingRule): PATTERN = AstNode( m_add, AstNode(m_add, AstLeaf("x_0"), AstLeaf("x_1")), AstNode(m_bnot, AstNode(m_and, AstLeaf("x_0"), AstLeaf("x_1")))) REPLACEMENT_PATTERN = AstNode( m_sub, AstNode(m_or, AstLeaf("x_0"), AstLeaf("x_1")), AstConstant("val_1")) def check_candidate(self, candidate): candidate.add_constant_leaf("val_1", 1, candidate.size) return True
class Add_HackersDelightRule_4(PatternMatchingRule): PATTERN = AstNode(m_sub, AstNode(m_mul, AstConstant("2", 2), AstNode(m_or, AstLeaf("x_0"), AstLeaf("x_1"))), AstNode(m_xor, AstLeaf("x_0"), AstLeaf("x_1"))) REPLACEMENT_PATTERN = AstNode(m_add, AstLeaf("x_0"), AstLeaf("x_1"))
class Add_OllvmRule_4(PatternMatchingRule): PATTERN = AstNode(m_sub, AstNode(m_xor, AstLeaf('x_0'), AstLeaf('x_1')), AstNode(m_mul, AstConstant("val_fe"), AstNode(m_and, AstLeaf('x_0'), AstLeaf('x_1')))) REPLACEMENT_PATTERN = AstNode(m_add, AstLeaf('x_0'), AstLeaf('x_1'))
class JnzRule7(JumpOptimizationRule): ORIGINAL_JUMP_OPCODES = [m_jnz, m_jz] LEFT_PATTERN = AstNode(m_and, AstLeaf("x_0"), AstConstant("c_1")) RIGHT_PATTERN = AstConstant("c_2") REPLACEMENT_OPCODE = m_goto def check_candidate(self, opcode, left_candidate, right_candidate): tmp = left_candidate["c_1"].value & right_candidate["c_2"].value if tmp == right_candidate["c_2"].value: return False if opcode == m_jnz: self.jump_replacement_block_serial = self.jump_original_block_serial else: self.jump_replacement_block_serial = self.direct_block_serial return True
class XorAlmost_Rule_1(PatternMatchingRule): PATTERN = AstNode( m_sub, AstNode(m_add, AstLeaf("x_0"), AstLeaf("x_1")), AstNode( m_mul, AstConstant("2", 2), AstNode(m_or, AstLeaf("x_0"), AstNode(m_sub, AstLeaf("x_1"), AstConstant("1", 1))))) REPLACEMENT_PATTERN = AstNode( m_add, AstNode(m_xor, AstLeaf("x_0"), AstNode(m_neg, AstLeaf("x_1"))), AstLeaf("val_2")) def check_candidate(self, candidate): candidate.add_constant_leaf("val_2", 2, candidate.size) return True
class Xor_HackersDelightRule_4(PatternMatchingRule): PATTERN = AstNode( m_sub, AstNode( m_sub, AstNode(m_sub, AstLeaf('x_0'), AstLeaf('x_1')), AstNode( m_mul, AstConstant('2', 2), AstNode(m_or, AstLeaf('x_0'), AstNode(m_bnot, AstLeaf('x_1'))))), AstConstant('2', 2)) REPLACEMENT_PATTERN = AstNode(m_xor, AstLeaf("x_0"), AstLeaf("x_1"))
class Sub_HackersDelightRule_4(PatternMatchingRule): PATTERN = AstNode( m_sub, AstNode(m_mul, AstConstant("2", 2), AstNode(m_and, AstLeaf("x_0"), AstLeaf("bnot_x_1"))), AstNode(m_xor, AstLeaf("x_0"), AstLeaf("x_1"))) REPLACEMENT_PATTERN = AstNode(m_sub, AstLeaf("x_0"), AstLeaf("x_1")) def check_candidate(self, candidate): if not equal_bnot_mop(candidate["x_1"].mop, candidate["bnot_x_1"].mop): return False return True
class Xor_FactorRule_2(PatternMatchingRule): PATTERN = AstNode(m_xor, AstNode(m_and, AstLeaf('bnot_x_0'), AstLeaf('x_1')), AstNode(m_and, AstLeaf('x_0'), AstLeaf('bnot_x_1'))) REPLACEMENT_PATTERN = AstNode(m_xor, AstLeaf("x_0"), AstLeaf("x_1")) def check_candidate(self, candidate): if not equal_bnot_mop(candidate["x_0"].mop, candidate["bnot_x_0"].mop): return False if not equal_bnot_mop(candidate["x_1"].mop, candidate["bnot_x_1"].mop): return False return True
class Mul_FactorRule_2(PatternMatchingRule): PATTERN = AstNode( m_sub, AstNode(m_neg, AstNode(m_and, AstLeaf("x_0"), AstLeaf("x_1"))), AstNode(m_and, AstLeaf("x_0"), AstLeaf("x_1"))) REPLACEMENT_PATTERN = AstNode( m_mul, AstConstant("val_fe"), AstNode(m_and, AstLeaf("x_0"), AstLeaf("x_1"))) def check_candidate(self, candidate): candidate.add_constant_leaf("val_fe", SUB_TABLE[candidate.size] - 2, candidate.size) return True
class And_OllvmRule_2(PatternMatchingRule): PATTERN = AstNode(m_and, AstNode(m_or, AstLeaf('x_0'), AstLeaf('x_1')), AstNode(m_xor, AstLeaf('x_0'), AstLeaf('bnot_x_1'))) REPLACEMENT_PATTERN = AstNode(m_and, AstLeaf('x_0'), AstLeaf('x_1')) def check_candidate(self, candidate): return equal_bnot_mop(candidate["x_1"].mop, candidate["bnot_x_1"].mop)
class Xor_SpecialConstantRule_2(PatternMatchingRule): PATTERN = AstNode( m_add, AstLeaf('x_0'), AstNode( m_add, AstNode(m_mul, AstConstant('0xfe'), AstNode(m_and, AstLeaf('x_0'), AstLeaf('x_1'))), AstLeaf('x_1'))) REPLACEMENT_PATTERN = AstNode(m_xor, AstLeaf("x_0"), AstLeaf("x_1")) def check_candidate(self, candidate): return candidate["0xfe"].value == SUB_TABLE[candidate["0xfe"].size] - 2
class NegAdd_HackersDelightRule_1(PatternMatchingRule): PATTERN = AstNode( m_add, AstNode(m_mul, AstConstant('val_fe'), AstNode(m_or, AstLeaf('x_0'), AstLeaf('x_1'))), AstNode(m_xor, AstLeaf('x_0'), AstLeaf('x_1'))) REPLACEMENT_PATTERN = AstNode( m_neg, AstNode(m_add, AstLeaf("x_0"), AstLeaf("x_1"))) def check_candidate(self, candidate): if (candidate["val_fe"].value + 2) & AND_TABLE[candidate["val_fe"].size] != 0: return False return True
class SetGlobalVariablesToZeroIfDetectedReadOnly(EarlyRule): DESCRIPTION = "WARNING: Use it only if you know what you are doing as it may patch data not related to obfuscation" PATTERN = AstNode(m_mov, AstLeaf("ro_dword")) REPLACEMENT_PATTERN = AstNode(m_mov, AstConstant("val_res")) def is_read_only_inited_var(self, address): s: segment_t = getseg(address) if s is None: return False if s.perm != (SEGPERM_READ | SEGPERM_WRITE): return False if is_loaded(address): return False ref_finder = xrefblk_t() is_ok = ref_finder.first_to(address, XREF_DATA) while is_ok: if ref_finder.type == dr_W: return False is_ok = ref_finder.next_to() return True def check_candidate(self, candidate): mem_read_address = None if candidate["ro_dword"].mop.t == mop_v: mem_read_address = candidate["ro_dword"].mop.g elif candidate["ro_dword"].mop.t == mop_a: if candidate["ro_dword"].mop.a.t == mop_v: mem_read_address = candidate["ro_dword"].mop.a.g if mem_read_address is None: return False if not self.is_read_only_inited_var(mem_read_address): return False candidate.add_constant_leaf("val_res", 0, candidate["ro_dword"].mop.size) return True
class AddXor_Rule_2(PatternMatchingRule): PATTERN = AstNode(m_sub, AstNode(m_sub, AstLeaf("x_0"), AstLeaf("x_1")), AstNode(m_mul, AstConstant("2", 2), AstNode(m_bnot, AstNode(m_and, AstLeaf("bnot_x_0"), AstLeaf("x_1"))))) REPLACEMENT_PATTERN = AstNode(m_add, AstNode(m_xor, AstLeaf("x_0"), AstLeaf("x_1")), AstLeaf("val_2")) def check_candidate(self, candidate): if not equal_bnot_mop(candidate["x_0"].mop, candidate["bnot_x_0"].mop): return False candidate.add_constant_leaf("val_2", 2, candidate["x_0"].size) return True
class Add_OllvmRule_1(PatternMatchingRule): PATTERN = AstNode(m_add, AstNode(m_bnot, AstNode(m_xor, AstLeaf('x_0'), AstLeaf('x_1'))), AstNode(m_mul, AstConstant("2", 2), AstNode(m_or, AstLeaf('x_1'), AstLeaf('x_0')))) REPLACEMENT_PATTERN = AstNode(m_sub, AstNode(m_add, AstLeaf('x_0'), AstLeaf('x_1')), AstConstant("val_1")) def check_candidate(self, candidate): candidate.add_constant_leaf("val_1", 1, candidate.size) return True
class Add_OllvmRule_2(PatternMatchingRule): PATTERN = AstNode(m_sub, AstNode(m_bnot, AstNode(m_xor, AstLeaf('x_0'), AstLeaf('x_1'))), AstNode(m_mul, AstConstant("val_fe"), AstNode(m_or, AstLeaf('x_0'), AstLeaf('x_1')))) REPLACEMENT_PATTERN = AstNode(m_sub, AstNode(m_add, AstLeaf('x_0'), AstLeaf('x_1')), AstConstant("val_1")) def check_candidate(self, candidate): if (candidate["val_fe"].value + 2) & AND_TABLE[candidate["val_fe"].size] != 0: return False candidate.add_constant_leaf("val_1", 1, candidate.size) return True
class WeirdRule2(PatternMatchingRule): PATTERN = AstNode( m_sub, AstNode(m_mul, AstConstant("2", 2), AstLeaf("x_0")), AstNode(m_and, AstLeaf("x_0"), AstNode(m_bnot, AstLeaf("x_1")))) REPLACEMENT_PATTERN = AstNode( m_add, AstLeaf("x_0"), AstNode(m_and, AstLeaf("x_0"), AstLeaf("x_1")))
class Or_MbaRule_1(PatternMatchingRule): PATTERN = AstNode(m_add, AstNode(m_and, AstLeaf("x_0"), AstLeaf("x_1")), AstNode(m_xor, AstLeaf("x_0"), AstLeaf("x_1"))) REPLACEMENT_PATTERN = AstNode(m_or, AstLeaf("x_0"), AstLeaf("x_1"))
class Or_HackersDelightRule_2_variant_1(PatternMatchingRule): PATTERN = AstNode( m_sub, AstNode(m_sub, AstLeaf("x_0"), AstLeaf("x_1")), AstNode(m_and, AstLeaf("x_0"), AstNode(m_neg, AstLeaf("x_1")))) REPLACEMENT_PATTERN = AstNode(m_or, AstLeaf("x_0"), AstNode(m_neg, AstLeaf("x_1")))
class Or_Rule_2(PatternMatchingRule): PATTERN = AstNode(m_or, AstNode(m_xor, AstLeaf("x_0"), AstLeaf("x_1")), AstLeaf("x_1")) REPLACEMENT_PATTERN = AstNode(m_or, AstLeaf("x_0"), AstLeaf("x_1"))
class GetIdentRule3(PatternMatchingRule): PATTERN = AstNode(m_and, AstLeaf("x_0"), AstNode(m_or, AstLeaf("x_0"), AstLeaf("x_1"))) REPLACEMENT_PATTERN = AstNode(m_mov, AstLeaf("x_0"))
class Sub1_FactorRule_2(PatternMatchingRule): PATTERN = AstNode(m_add, AstNode(m_mul, AstConstant("2", 2), AstLeaf("x_0")), AstNode(m_bnot, AstLeaf("x_0"))) REPLACEMENT_PATTERN = AstNode(m_sub, AstLeaf("x_0"), AstConstant("1", 1))
class WeirdRule6(PatternMatchingRule): PATTERN = AstNode( m_add, AstNode(m_or, AstLeaf('x_0'), AstLeaf('x_1')), AstNode(m_and, AstLeaf('x_0'), AstNode(m_bnot, AstLeaf('x_1')))) REPLACEMENT_PATTERN = AstNode( m_add, AstNode(m_xor, AstLeaf("x_0"), AstLeaf("x_1")), AstLeaf('x_0'))
class Xor_NestedStuff(PatternMatchingRule): PATTERN = AstNode( m_sub, AstNode(m_add, AstNode(m_add, AstLeaf('x_9'), AstLeaf('x_10')), AstLeaf("x_11")), AstNode( m_add, AstLeaf("x_14"), AstNode( m_mul, AstConstant('2', 2), AstNode( m_and, AstLeaf('x_10'), AstNode(m_sub, AstNode(m_add, AstLeaf('x_9'), AstLeaf("x_11")), AstLeaf("x_14")))))) REPLACEMENT_PATTERN = AstNode( m_xor, AstLeaf("x_10"), AstNode(m_sub, AstNode(m_add, AstLeaf('x_9'), AstLeaf("x_11")), AstLeaf("x_14"))) FUZZ_PATTERN = False
class Neg_HackersDelightRule_1(PatternMatchingRule): PATTERN = AstNode(m_add, AstNode(m_bnot, AstLeaf("x_0")), AstConstant("1", 1)) REPLACEMENT_PATTERN = AstNode(m_neg, AstLeaf("x_0"))
class NegXor_HackersDelightRule_1(PatternMatchingRule): PATTERN = AstNode(m_sub, AstNode(m_and, AstLeaf('x_0'), AstLeaf('x_1')), AstNode(m_or, AstLeaf('x_0'), AstLeaf('x_1'))) REPLACEMENT_PATTERN = AstNode( m_neg, AstNode(m_xor, AstLeaf("x_0"), AstLeaf("x_1")))