控制流平坦化的去除

 不过没考虑走遍所有分支的情况

第一步的python代码,第一步主要是识别主分发器之类的东西

import idaapi
import idc
fun_start = 0x000000000001E3C
fun_end = 0x00000000002F04
#  存在 bug,fun.end_ea得到的不一定是函数的尾地址。已修复,使用了一种比较笨的方法
def get_block_of_fun(ea,ed):
    block_all = []
    fun = idaapi.get_func(ea)
    fc = idaapi.FlowChart(fun)
    for block in fc:
        block_all.append( (block.start_ea,block.end_ea))
    block_all_order = sorted(block_all, key=lambda item: item[0])

    # for i in block_all_order:
    #     print(hex(i[0]),hex(i[1]))
    return block_all_order



def Get_Asm(begin,end):
    Asm_data = []
    ea = begin
    while ea < end:
        ttt = str(hex(ea)) + ":    " + idc.generate_disasm_line(ea, 0) 
        Asm_data.append(ttt)
        ea = idc.next_head(ea)

    return Asm_data


# 对某函数的所有基本快进行染色
def dye_blocks(block_all):
    blocks_dye = [None] * len(block_all)     # 对所有的基本块进行染色,0代表序言,1代表主分发器,2代表预处理器,3代表子分发器,4代表真实块,5代表retn块
    blocks_asm = [None] * len(block_all)     # 存放所有基本块的汇编
    # 先遍历一遍,找出序言、主分发器、预处理器
    for i in range(len(block_all)):
        block_start = block_all[i][0]
        block_end = block_all[i][1]
        
        asm_codes  = Get_Asm(block_start,block_end)
        blocks_asm[i] = asm_codes[:]
    blocks_dye[0] = 0                       # 第一个基本块代表序言,第二个基本块代表主分发器。                   
    blocks_dye[1] = 1
    jmp_table = [None] * len(block_all)
    

    preprocessor_addr = -1
    for i in range(len(blocks_asm)):
        asm_codes=  blocks_asm[i]
        fin_code:str = asm_codes[len(asm_codes)-1]
        if "B " in fin_code:
            B_addr = int(fin_code.split("loc_")[1].strip(),16)
            block_start = block_all[i][0]
            if block_start not in jmp_table:
                jmp_table[i] = B_addr
            if B_addr == block_all[1][0] and i!=0:       # 如果目的地址是序言,且不是主分发器,那么一定就是预处理器了
                blocks_dye[i] = 2
                preprocessor_addr = block_all[i][0]
        elif "RET" in fin_code:                          # 找到ret块
            blocks_dye[i] = 5
            
    if preprocessor_addr == -1:
        print("can't find preprocessor")
        assert 0
    for i in range(len(jmp_table)):                                  # 目的地址是预处理器的,都是真实块
        block_jmp = jmp_table[i]
        if block_jmp == None:
            continue
        if block_jmp == preprocessor_addr and i != 0:
            blocks_dye[i] = 4
    
    
    # 剩下的就都是子分发器喽
    for i in range(len(blocks_dye)):
        if blocks_dye[i] == None:
            blocks_dye[i] = 3

    return blocks_dye

blocks_all = get_block_of_fun(fun_start,fun_end)
blocks_dye = dye_blocks(blocks_all)
for i in range(len(blocks_all)):
    print(f"{{{hex(blocks_all[i][0])},{hex(blocks_all[i][1])},{blocks_dye[i]}}}",end =",")

 

 

第二步的unidbg代码,第二步主要是模拟执行找真实块之间的关系

package com.deobf;
import capstone.api.Instruction;
import com.Tencent_game.tracer_fin_2023;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Emulator;
import com.github.unidbg.Module;
import com.github.unidbg.arm.backend.Backend;
import com.github.unidbg.arm.backend.ReadHook;
import com.github.unidbg.arm.backend.UnHook;
import com.github.unidbg.debugger.BreakPointCallback;
import com.github.unidbg.debugger.DebuggerType;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.DalvikModule;
import com.github.unidbg.linux.android.dvm.DvmClass;
import com.github.unidbg.linux.android.dvm.VM;
import com.github.unidbg.listener.TraceCodeListener;
import com.github.unidbg.memory.Memory;
import com.github.unidbg.virtualmodule.android.AndroidModule;
import java.util.HashMap;
import capstone.Capstone;
import capstone.Capstone.OpInfo;
import capstone.api.Instruction;
import keystone.Keystone;
import keystone.KeystoneArchitecture;
import keystone.KeystoneMode;
import keystone.KeystoneEncoded;
import com.github.unidbg.arm.context.RegisterContext;
import unicorn.Arm64Const;
import com.github.unidbg.arm.backend.CodeHook;
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.HashSet;
import java.util.Set;
import java.util.Arrays;
import com.github.unidbg.pointer.UnidbgPointer;
import java.io.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
public class deollvm {
    public final AndroidEmulator emulator;
    public final VM vm;
    public final Memory memory;
    public final Module module;

    public deollvm(){
        emulator = AndroidEmulatorBuilder.for64Bit().build();
        memory =  emulator.getMemory();
        memory.setLibraryResolver(new AndroidResolver(23));
        emulator.getSyscallHandler().setEnableThreadDispatcher(true);
        vm = emulator.createDalvikVM();
        new AndroidModule(emulator,vm).register(memory);

        DalvikModule dalvikModule = vm.loadLibrary(new File("C:\\Users\\27236\\Desktop\\Anti_ollvm\\tea_fla_split"), true);
        module = dalvikModule.getModule();
        vm.callJNI_OnLoad(emulator,module);
    }


    public  static  void main(String[] args)   {
        deollvm mainActivity = new deollvm();
        mainActivity.deollvm();
    }

    Instruction[][] blocks_asm;
    long [][]blocks_dye_mess = {
            {0x1e3c,0x1e64,0},{0x1e64,0x1e7c,1},{0x1e7c,0x1e80,3},{0x1e80,0x1e94,3},{0x1e94,0x1e98,3},{0x1e98,0x1eac,3},{0x1eac,0x1eb0,3},{0x1eb0,0x1ec4,3},{0x1ec4,0x1ec8,3},{0x1ec8,0x1edc,3},{0x1edc,0x1ee0,3},{0x1ee0,0x1ef4,3},{0x1ef4,0x1ef8,3},{0x1ef8,0x1f0c,3},{0x1f0c,0x1f10,3},{0x1f10,0x1f24,3},{0x1f24,0x1f28,3},{0x1f28,0x1f3c,3},{0x1f3c,0x1f40,3},{0x1f40,0x1f54,3},{0x1f54,0x1f58,3},{0x1f58,0x1f6c,3},{0x1f6c,0x1f70,3},{0x1f70,0x1f84,3},{0x1f84,0x1f88,3},{0x1f88,0x1f9c,3},{0x1f9c,0x1fa0,3},{0x1fa0,0x1fb4,3},{0x1fb4,0x1fb8,3},{0x1fb8,0x1fcc,3},{0x1fcc,0x1fd0,3},{0x1fd0,0x1fe4,3},{0x1fe4,0x1fe8,3},{0x1fe8,0x1ffc,3},{0x1ffc,0x2000,3},{0x2000,0x2014,3},{0x2014,0x2018,3},{0x2018,0x202c,3},{0x202c,0x2030,3},{0x2030,0x2044,3},{0x2044,0x2048,3},{0x2048,0x205c,3},{0x205c,0x2060,3},{0x2060,0x2074,3},{0x2074,0x2078,3},{0x2078,0x208c,3},{0x208c,0x2090,3},{0x2090,0x20a4,3},{0x20a4,0x20a8,3},{0x20a8,0x20bc,3},{0x20bc,0x20c0,3},{0x20c0,0x20d4,3},{0x20d4,0x20d8,3},{0x20d8,0x20ec,3},{0x20ec,0x20f0,3},{0x20f0,0x2104,3},{0x2104,0x2108,3},{0x2108,0x211c,3},{0x211c,0x2120,3},{0x2120,0x2134,3},{0x2134,0x2138,3},{0x2138,0x214c,3},{0x214c,0x2150,3},{0x2150,0x2164,3},{0x2164,0x2168,3},{0x2168,0x217c,3},{0x217c,0x2180,3},{0x2180,0x2194,3},{0x2194,0x2198,3},{0x2198,0x21ac,3},{0x21ac,0x21b0,3},{0x21b0,0x21c4,3},{0x21c4,0x21c8,3},{0x21c8,0x21dc,3},{0x21dc,0x21e0,3},{0x21e0,0x21f4,3},{0x21f4,0x21f8,3},{0x21f8,0x220c,3},{0x220c,0x2210,3},{0x2210,0x2224,3},{0x2224,0x2228,3},{0x2228,0x223c,3},{0x223c,0x2240,3},{0x2240,0x2254,3},{0x2254,0x2258,3},{0x2258,0x226c,3},{0x226c,0x2270,3},{0x2270,0x2284,3},{0x2284,0x2288,3},{0x2288,0x229c,3},{0x229c,0x22a0,3},{0x22a0,0x22b4,3},{0x22b4,0x22b8,3},{0x22b8,0x22cc,3},{0x22cc,0x22d0,3},{0x22d0,0x22e4,3},{0x22e4,0x22e8,3},{0x22e8,0x22fc,3},{0x22fc,0x2300,3},{0x2300,0x2314,3},{0x2314,0x2318,3},{0x2318,0x232c,3},{0x232c,0x2330,3},{0x2330,0x2344,3},{0x2344,0x2348,3},{0x2348,0x235c,3},{0x235c,0x2360,3},{0x2360,0x2374,3},{0x2374,0x2378,3},{0x2378,0x238c,3},{0x238c,0x2390,3},{0x2390,0x23a4,3},{0x23a4,0x23a8,3},{0x23a8,0x23bc,3},{0x23bc,0x23c0,3},{0x23c0,0x23d4,3},{0x23d4,0x23d8,3},{0x23d8,0x23ec,3},{0x23ec,0x23f0,3},{0x23f0,0x2404,3},{0x2404,0x2408,3},{0x2408,0x241c,3},{0x241c,0x2420,3},{0x2420,0x2434,3},{0x2434,0x2438,3},{0x2438,0x244c,3},{0x244c,0x2450,3},{0x2450,0x2464,3},{0x2464,0x2468,3},{0x2468,0x247c,3},{0x247c,0x2480,3},{0x2480,0x2484,3},{0x2484,0x24a4,4},{0x24a4,0x24b4,4},{0x24b4,0x24d8,4},{0x24d8,0x24f0,4},{0x24f0,0x2528,4},{0x2528,0x254c,4},{0x254c,0x2578,4},{0x2578,0x259c,4},{0x259c,0x25b4,4},{0x25b4,0x25cc,4},{0x25cc,0x25f4,4},{0x25f4,0x260c,4},{0x260c,0x2628,4},{0x2628,0x2654,4},{0x2654,0x2678,4},{0x2678,0x2690,4},{0x2690,0x26a8,4},{0x26a8,0x274c,4},{0x274c,0x27b4,4},{0x27b4,0x27cc,4},{0x27cc,0x27e8,4},{0x27e8,0x2800,4},{0x2800,0x2810,4},{0x2810,0x2844,4},{0x2844,0x28f4,4},{0x28f4,0x290c,4},{0x290c,0x291c,4},{0x291c,0x2934,4},{0x2934,0x2954,4},{0x2954,0x2984,4},{0x2984,0x29a8,4},{0x29a8,0x29b8,4},{0x29b8,0x29d0,4},{0x29d0,0x29fc,4},{0x29fc,0x2a20,4},{0x2a20,0x2a40,4},{0x2a40,0x2a60,4},{0x2a60,0x2aa4,4},{0x2aa4,0x2ab4,4},{0x2ab4,0x2ad8,4},{0x2ad8,0x2af0,4},{0x2af0,0x2b0c,4},{0x2b0c,0x2b24,4},{0x2b24,0x2b3c,4},{0x2b3c,0x2b64,4},{0x2b64,0x2b88,4},{0x2b88,0x2bf8,4},{0x2bf8,0x2c34,4},{0x2c34,0x2cb0,4},{0x2cb0,0x2cd8,4},{0x2cd8,0x2cf0,4},{0x2cf0,0x2d10,4},{0x2d10,0x2d28,4},{0x2d28,0x2d38,4},{0x2d38,0x2d70,4},{0x2d70,0x2dd0,4},{0x2dd0,0x2e3c,4},{0x2e3c,0x2e60,4},{0x2e60,0x2e78,4},{0x2e78,0x2e98,4},{0x2e98,0x2eb0,4},{0x2eb0,0x2ed4,4},{0x2ed4,0x2ee4,4},{0x2ee4,0x2ef4,4},{0x2ef4,0x2f00,5},{0x2f00,0x2f04,2},
    };
    public void get_blocks_asm(int block_idx,long begin,long end){
        Capstone capstone = new Capstone(Capstone.CS_ARCH_ARM64,Capstone.CS_MODE_LITTLE_ENDIAN);
        byte[] bytes = emulator.getBackend().mem_read(begin + module.base, end - begin);
        blocks_asm[block_idx] = capstone.disasm(bytes, begin);
    }
    public void init_blocks_asm(){
        blocks_asm = new Instruction[blocks_dye_mess.length][];
        for(int i=0;i<blocks_dye_mess.length;i++){
            long begin = blocks_dye_mess[i][0];
            long end = blocks_dye_mess[i][1];
            get_blocks_asm(i,begin,end);
        }
    }

    public long last_true_block = -1;
    public long last_condition_true_block = -1;
    public long last_condition_false_block = -1;
    public String con_op;
    class select_ins{
        long ins_addr;
        long taraddr;
        long other_taraddr=-1;
        long block_idx;
        String condition;
        String true_or_false;


    }
    public ArrayList<select_ins>  global_select_list= new ArrayList<>();

    public void set_ins_hook(long begin_addr,long end_addr){
        emulator.getBackend().hook_add_new(new CodeHook() {

            private UnHook unHook;

            @Override
            public void hook(Backend backend, long address, int size, Object user) {

                try{
                    long offset = address-module.base;
                    int idx = (int)addr2block_idx[(int)offset];
                    Instruction block_asm[] = blocks_asm[idx];
                    long begin_offset = blocks_dye_mess[idx][0];


                    int block_off = (int)(offset-begin_offset)/4;
                    if( block_off > 0 && block_asm[ block_off -1].getMnemonic().contains("csel")){
                        String[] ops = block_asm[block_off-1].getOpStr().split(",");
                        String tarreg = ops[0].replace("w","x").trim();
                        String op1_reg = ops[1].replace("w","x").trim();
                        String op2_reg = ops[2].replace("w","x").trim();
                        String conditon = ops[3].trim();

                        long tarreg_val = read_reg_by_str(backend,tarreg);
                        long op1_reg_val = read_reg_by_str(backend,op1_reg);
                        long op2_reg_val = read_reg_by_str(backend,op2_reg);

                        if(tarreg_val == op1_reg_val){
                            last_condition_true_block = offset-4;
                        }else{
                            last_condition_false_block = offset-4;
                        }
                        con_op = new String(conditon);

                    }

                    if(block_end_addr_table.containsKey(offset)){
                        // 1、判断是不是真实块
                        int block_idx = end_to_block_idx.get(offset);
                        long dye = blocks_dye_mess[block_idx][2];


                        if(dye == 4){


                            // CSET、CSEL代表出现了条件分支,这里我们以csel作为条件分支,因为ollvm主要以csel作为分割
                            if(last_condition_true_block != -1){
                                if(addr2block_idx[(int)offset] != addr2block_idx[(int)last_condition_true_block]){

                                    select_ins ins = new select_ins();
                                    ins.ins_addr = last_condition_true_block;
                                    ins.condition = new String(con_op);
                                    ins.taraddr = blocks_dye_mess[block_idx][0];
                                    ins.block_idx = block_idx;
                                    ins.true_or_false = "true";
                                    global_select_list.add(ins);
                                    last_condition_true_block = -1;
                                }
                            }else if(last_condition_false_block != -1){
                                if(addr2block_idx[(int)offset] != addr2block_idx[(int)last_condition_false_block]){

                                    select_ins ins = new select_ins();
                                    ins.ins_addr = last_condition_false_block;
                                    ins.condition = new String(con_op);
                                    ins.taraddr = blocks_dye_mess[block_idx][0];
                                    ins.block_idx = block_idx;
                                    ins.true_or_false = "false";
                                    global_select_list.add(ins);
                                    last_condition_false_block = -1;
                                }
                            }



                            if (last_true_block != -1){
                                true_block_jmp_table.put(last_true_block,blocks_dye_mess[block_idx][0]);
                                last_true_block = offset;
                            }else{
                                last_true_block = offset;
                            }
                        }

                        // 2、判断是不是ret块
                        if(dye == 5){
                            true_block_jmp_table.put(last_true_block,blocks_dye_mess[block_idx][0]);

                            last_true_block = -1;
                            unHook.unhook();            // detach hook
                        }

                        // 3、判断是不是主分发器
                        if(dye == 0){
                            last_true_block = offset;
                        }

                    }


                }catch (Exception e){
                    System.out.println(e);
                }


            }

            @Override
            public void onAttach(UnHook unHook) {
                this.unHook = unHook;
            }

            @Override
            public void detach() {
            }
        },begin_addr+module.base,end_addr+module.base,null);
    }

    public HashMap<Long,Boolean> block_end_addr_table = new HashMap<>();
    public HashMap<Long,Integer> end_to_block_idx = new HashMap<>();
    public HashMap<Long,Long> true_block_jmp_table = new HashMap<>();  // 这个表是为了记录真实块之间的跳转的
    public int ins_long = 4;
    public long[] addr2block_idx;

    public void init_block_end_jmp_table(){
        for(int i=0;i<blocks_dye_mess.length;i++){
            long end =blocks_dye_mess[i][1];
            block_end_addr_table.put(end-ins_long,true);
        }
    }
    public void init_end_to_block_idx(){
        for(int i=0;i<blocks_dye_mess.length;i++){
            long end =blocks_dye_mess[i][1];
            end_to_block_idx.put(end-ins_long,i);
        }
    }
    public void init_addr2block_idx(long begin,long end){
        addr2block_idx = new long[(int)end + 0x10];
        for(int i=0;i<blocks_dye_mess.length;i++){
            long be = blocks_dye_mess[i][0];
            long ed = blocks_dye_mess[i][1];
            for(int j=(int)be;j<ed;j++){
                addr2block_idx[j] = i;
            }

        }
    }

    public void patcher(long begin,long end){
        System.out.printf("patch = [");
        for (Map.Entry<Long, Long> entry : true_block_jmp_table.entrySet()) {
            Long src_address = entry.getKey();
            Long tar_address = entry.getValue();
            System.out.printf("(0x%x,0x%x),",src_address,tar_address);
        }
        System.out.printf("]\n");


        HashMap<Long,select_ins>  part_select_list= new HashMap<>();
        long []set_ins = new long[(int)end + 0x10];
        for(select_ins ins: global_select_list){
            long ins_addr = ins.ins_addr;
            if(set_ins[(int)ins_addr]!=0){
                if (set_ins[(int)ins_addr] != ins.taraddr){
                    part_select_list.get(ins_addr).other_taraddr = ins.taraddr;
                }
            }else{
                set_ins[(int)ins_addr] = ins.taraddr;
                part_select_list.put(ins_addr,ins);
            }
        }

        System.out.printf("patch_sel = [");
        for (Map.Entry<Long, select_ins> entry : part_select_list.entrySet()) {
            long ins_addr = entry.getKey();
            select_ins ins_mess = entry.getValue();
            System.out.printf("(0x%x , '%s' , 0x%x , 0x%x, '%s') ,",ins_addr,ins_mess.true_or_false,ins_mess.taraddr,ins_mess.other_taraddr,ins_mess.condition);
        }

        System.out.printf("]\n");
    }
    public HashMap<String, Integer> reg2val = new HashMap<>();
    public  void padding_reg2val() {
        reg2val.put("x0",Arm64Const.UC_ARM64_REG_X0);
        reg2val.put("x1",Arm64Const.UC_ARM64_REG_X1);
        reg2val.put("x2",Arm64Const.UC_ARM64_REG_X2);
        reg2val.put("x3",Arm64Const.UC_ARM64_REG_X3);
        reg2val.put("x4",Arm64Const.UC_ARM64_REG_X4);
        reg2val.put("x5",Arm64Const.UC_ARM64_REG_X5);
        reg2val.put("x6",Arm64Const.UC_ARM64_REG_X6);
        reg2val.put("x7",Arm64Const.UC_ARM64_REG_X7);
        reg2val.put("x8",Arm64Const.UC_ARM64_REG_X8);
        reg2val.put("x9",Arm64Const.UC_ARM64_REG_X9);
        reg2val.put("x10",Arm64Const.UC_ARM64_REG_X10);
        reg2val.put("x11",Arm64Const.UC_ARM64_REG_X11);
        reg2val.put("x12",Arm64Const.UC_ARM64_REG_X12);
        reg2val.put("x13",Arm64Const.UC_ARM64_REG_X13);
        reg2val.put("x14",Arm64Const.UC_ARM64_REG_X14);
        reg2val.put("x15",Arm64Const.UC_ARM64_REG_X15);
        reg2val.put("x16",Arm64Const.UC_ARM64_REG_X16);
        reg2val.put("x17",Arm64Const.UC_ARM64_REG_X17);
        reg2val.put("x18",Arm64Const.UC_ARM64_REG_X18);
        reg2val.put("x19",Arm64Const.UC_ARM64_REG_X19);
        reg2val.put("x20",Arm64Const.UC_ARM64_REG_X20);
        reg2val.put("x21",Arm64Const.UC_ARM64_REG_X21);
        reg2val.put("x22",Arm64Const.UC_ARM64_REG_X22);
        reg2val.put("x23",Arm64Const.UC_ARM64_REG_X23);
        reg2val.put("x24",Arm64Const.UC_ARM64_REG_X24);
        reg2val.put("x25",Arm64Const.UC_ARM64_REG_X25);
        reg2val.put("x26",Arm64Const.UC_ARM64_REG_X26);
        reg2val.put("x27",Arm64Const.UC_ARM64_REG_X27);
        reg2val.put("x28",Arm64Const.UC_ARM64_REG_X28);

        reg2val.put("x29",Arm64Const.UC_ARM64_REG_FP);
        reg2val.put("x30",Arm64Const.UC_ARM64_REG_LR);

        reg2val.put("sp",Arm64Const.UC_ARM64_REG_SP);
        reg2val.put("pc",Arm64Const.UC_ARM64_REG_PC);
    }
    public long read_reg_by_str(Backend backend,String reg){
        long true_reg_val = -1;
        if(reg2val.containsKey(reg)){
            true_reg_val = backend.reg_read(reg2val.get(reg)).longValue();
        }else if(reg.equals("xzr")){
            true_reg_val = 0;
        }else{
            assert false;
        }
        return true_reg_val;
    }


    public  void deollvm() {
        long begin_addr = 0x000000000001E3C;
        long end_addr = 0x00000000002F04;
        // 1、获取各基本块的汇编信息
        init_blocks_asm();
        // 2、指令级hook
        set_ins_hook(begin_addr,end_addr);
        // 3、初始化 block_end_jmp_table ,这个表是为了set_ins_hook做准备,每次只处理尾地址,优化unidbg执行效率
        init_block_end_jmp_table();
        // 4、初始化 end_to_block_idx , 这个是为了方便末尾地址对bloc序列的转化
        init_end_to_block_idx();
        // 5、初始化 addr2block_idx 。这个是为了方便任意地址找block序列
        init_addr2block_idx(begin_addr,end_addr);
        // 6、padding_reg2val
        padding_reg2val();
        // 7、模拟执行
        module.callFunction(emulator,0x00000000000325C);
        // 8、patcher
        patcher(begin_addr,end_addr);
    }

}

 

第三步的patch脚本

import idc
from keystone import *
def patcher(patch):
    Kstone = Ks(KS_ARCH_ARM64,KS_MODE_LITTLE_ENDIAN)
    for i in range(len(patch)):
        block_patch  = patch[i]
        asm_code = f"b {hex(block_patch[1])}"
        asm_addr = block_patch[0]
        encode,count =Kstone.asm(asm_code,asm_addr)
        for j in range(4):
            idc.patch_byte(asm_addr+j,encode[j])            

def patcher_sel(patch):
    Kstone = Ks(KS_ARCH_ARM64,KS_MODE_LITTLE_ENDIAN)
    for i in range(len(patch)):
        block_patch = patch[i]
        condition = block_patch[4]
        true_or_false = block_patch[1]
        taraddr = block_patch[2]
        other_addr = block_patch[3]
        ins_addr = block_patch[0]
        if other_addr == 0xffffffffffffffff:
            other_addr = taraddr
        if "true" in true_or_false:
            asm_code = f"b{condition} {hex(taraddr)}\n" + f"b {hex(other_addr)}"
        else:
            asm_code = f"b{condition} {hex(other_addr)}\n" + f"b {hex(taraddr)}"
        
        encode,count =Kstone.asm(asm_code,ins_addr)
        for j in range(len(encode)):
            idc.patch_byte(ins_addr+j,encode[j])      

def upc(begin,end):
    for i in range(begin,end):
        idc.del_items(i)
    for i in range(begin,end):
        idc.create_insn(i)
    idaapi.add_func(begin,end)
    print("Finish!!!")

patch = [(0x2840,0x2844),(0x2980,0x2984),(0x2548,0x254c),(0x25c8,0x25cc),(0x2608,0x260c),(0x2748,0x274c),(0x27c8,0x27cc),(0x2908,0x290c),(0x268c,0x2690),(0x280c,0x25f4),(0x2650,0x2654),(0x2950,0x2954),(0x24d4,0x24d8),(0x2598,0x259c),(0x2918,0x291c),(0x1e60,0x2484),(0x24a0,0x24a4),(0x2524,0x2528),(0x2624,0x2628),(0x26a4,0x26a8),(0x27e4,0x27e8),(0x29a4,0x29a8),(0x24ec,0x24f0),(0x24b0,0x24b4),(0x25b0,0x25b4),(0x25f0,0x25f4),(0x27b0,0x27b4),(0x28f0,0x28f4),(0x2930,0x2934),(0x2574,0x2578),(0x2674,0x2810),(0x29b4,0x2ef4),(0x27fc,0x2800),]
patch_sel = [(0x24cc , 'true' , 0x24d8 , 0xffffffffffffffff, 'gt') ,(0x266c , 'true' , 0x2678 , 0x2810, 'ne') ,(0x299c , 'true' , 0x2578 , 0x29a8, 'ne') ,]

patcher(patch)
patcher_sel(patch_sel)

fun_start = 0x000000000001E3C
fun_end = 0x00000000002F04
upc(fun_start,fun_end)

 

posted @ 2025-03-01 20:22  TLSN  阅读(80)  评论(0)    收藏  举报