[原创] 腾讯游戏安全技术竞赛2023 安卓客户端初赛writeup | 宜武汇-ag真人国际厅网站

from emu_utils import *

from unicorn import *

from unicorn.arm64_const import *

# from ida_bytes import *

 

 

def trace_back_insn_with_target(insn_queue, target_reg):

    for insn in insn_queue:

        if (target_reg in insn.op_str):

            if (insn.mnemonic == 'add'):

                print(insn.mnemonic '\t' insn.op_str)

        if (insn.mnemonic == 'ldr'):

            print(insn.mnemonic '\t' insn.op_str)

        if (insn.mnemonic == 'csel'):

            print(insn.mnemonic '\t' insn.op_str)

 

 

def log_hook(emu, addr, size, user_data):

    disasm = get_disasm(emu, addr, size)

 

    print(hex(addr) '\t' disasm.mnemonic '\t' disasm.op_str)

 

 

def step_over_hook(emu, addr, size, none):

    disasm = get_disasm(emu, addr, size)

 

    if (disasm.mnemonic == 'bl' or disasm.mnemonic == 'blr'):

        emu.reg_write(uc_arm64_reg_pc, addr size)

 

    if (disasm.mnemonic == 'ret'):

        print('function returned')

        emu.emu_stop()

 

    if (addr == 0x3ac68):

        emu.reg_write(uc_arm64_reg_w10, 0xeecf7326)

 

 

def normal_hook(emu, addr, size, insn_queue):

    global const_value, offset_value, cond, cond_value, uncond_value

    disasm = get_disasm(emu, addr, size)

    reg_maps = get_reg_maps()

 

    insn_queue.insert(0, disasm)

    if (len(insn_queue) > 8):

        insn_queue.pop()

 

    if (disasm.mnemonic == 'csel'):

        cond_value = emu.reg_read(reg_maps[disasm.op_str.split(', ')[1]])

        uncond_value = emu.reg_read(reg_maps[disasm.op_str.split(', ')[2]])

        cond = disasm.op_str.split(', ')[3]

 

    if (disasm.mnemonic == 'cset'):

        cond_value = 1

        uncond_value = 0

        cond = disasm.op_str.split(', ')[1]

 

    if (disasm.mnemonic == 'ldr'):

        if (len(disasm.op_str.split(', ')) == 3):

            offset_value = emu.reg_read(

                reg_maps[disasm.op_str.split(', ')[1].split('[')[1]])

        elif (len(disasm.op_str.split(', ')) == 4):

            offset_value = emu.reg_read(

                reg_maps[disasm.op_str.split(', ')[1].split('[')[1]])

            cond_value *= 8

 

    if (disasm.mnemonic == 'add' and '#' not in disasm.op_str and 'w' not in disasm.op_str):

        const_value = emu.reg_read(reg_maps[disasm.op_str.split(', ')[2]])

 

    if (disasm.mnemonic == 'br'):

        print('on br insn')

 

        target_reg = disasm.op_str

        trace_back_insn_with_target(insn_queue, target_reg)

 

        print(hex(const_value), hex(offset_value),

              cond, cond_value, uncond_value)

 

        cond_addr = emu.mem_read(offset_value cond_value, 4)

        cond_addr = (int.from_bytes(

            cond_addr, byteorder='little') const_value) & 0xffffffff

        uncond_addr = emu.mem_read(offset_value uncond_value, 4)

        uncond_addr = (int.from_bytes(

            uncond_addr, byteorder='little') const_value) & 0xffffffff

 

        patch_asm = b''

        patch_asm = get_asm('b' cond ' ' hex(cond_addr), addr - 4)

        patch_asm = get_asm('b ' hex(uncond_addr), addr)

        # patch_bytes(addr - 4, patch_asm)

 

        emu.reg_write(uc_arm64_reg_pc, addr size)

 

 

def emulate_execution(filename, start_addr, hook_func, user_data):

    emu = uc(uc_arch_arm64, uc_mode_little_endian)

 

    textsec = get_section(filename, '.text')

    datasec = get_section(filename, '.data')

 

    textsec_entry = textsec.header['sh_addr']

    textsec_size = textsec.header['sh_size']

    textsec_raw = textsec.header['sh_offset']

 

    text_base = textsec_entry >> 12 << 12

    text_size = (textsec_size 0x1000) >> 12 << 12

    text_rbase = textsec_raw >> 12 << 12

 

    datasec_entry = datasec.header['sh_addr']

    datasec_size = datasec.header['sh_size']

    datasec_raw = datasec.header['sh_offset']

 

    data_base = datasec_entry >> 12 << 12

    data_size = (datasec_size 0x1000) >> 12 << 12

    data_rbase = datasec_raw >> 12 << 12

 

    void_1_base = 0x00000000

    void_1_size = text_base

 

    void_2_base = text_base text_size

    void_2_size = data_base - void_2_base

 

    stack_base = data_base data_size

    stack_size = 0xffffffff - stack_base >> 12 << 12

 

    emu.mem_map(void_1_base, void_1_size)

    emu.mem_map(text_base, text_size)

    emu.mem_map(data_base, data_size)

    emu.mem_map(void_2_base, void_2_size)

    emu.mem_map(stack_base, stack_size)

 

    emu.mem_write(text_base, read(filename)[text_rbase:text_rbase text_size])

    emu.mem_write(data_base, read(filename)[data_rbase:data_rbase data_size])

    emu.reg_write(uc_arm64_reg_fp, stack_base 0x1000)

    emu.reg_write(uc_arm64_reg_sp, stack_base stack_size // 2)

 

    emu.hook_add(uc_hook_code, log_hook)

    emu.hook_add(uc_hook_code, step_over_hook, user_data)

    emu.hook_add(uc_hook_code, hook_func, user_data)

 

    emu.emu_start(start_addr, 0x0)

 

 

if __name__ == '__main__':

    filename = './libsec2023.so'

    start_addr = 0x3ac68

 

    insn_queue = []

    emulate_execution(filename, start_addr, normal_hook, insn_queue)

原文链接:https://bbs.kanxue.com/thread-276893.htm

网络摘文,本文作者:15h,如若转载,请注明出处:https://www.15cov.cn/2023/08/27/原创-腾讯游戏安全技术竞赛2023-安卓客户端初赛writeup/

发表评论

邮箱地址不会被公开。 必填项已用*标注

网站地图