Пример #1
0
def debugme(debugger):
    utils.ILOG("start patch ptrace funtion to bypass anti debug")
    patch_ptrace(debugger)
    utils.SLOG("ptrace funtion patach done")

    utils.ILOG("start patch svc ins to bypass anti debug")
    images = utils.get_all_image_of_app()
    for image in images:
        utils.ILOG("search svc from:{}".format(image["name"]))
        text_addr_arr_str = get_text_segment(debugger, image["idx"])
        text_addr_arr = text_addr_arr_str.strip()[1:-1].split(",")
        if len(text_addr_arr) < 2:
            utils.ELOG("failed to get text segment of image:{}" + image["name"])
            continue
        text_start = text_addr_arr[0]
        text_end = text_addr_arr[1]
        utils.ILOG("text start:{} end:{}".format(text_start, text_end))
        svc_arr_str = lookup_svc_insn(debugger, text_start, text_end)
        if "<object returned empty description>" in svc_arr_str:
            utils.ILOG("not found svc ins, so don't need patch")
            continue
        
        svc_arr = svc_arr_str.strip()
        svc_arr = svc_arr.split()

        if len(svc_arr) < 1:
            utils.ELOG("not found svc ins, so don't need patch")
            continue
        for svc_addr in svc_arr:
            utils.ILOG("start hook svc at address:{}".format(svc_addr))
            ret = xia0Hook(debugger, svc_addr)
            if ret:
                utils.SLOG("hook svc at address:{} done".format(svc_addr))
    return
Пример #2
0
def debugme(debugger):
    utils.ILOG("start patch ptrace funtion to bypass antiDebug")
    patch_ptrace(debugger)
    utils.SLOG("success ptrace funtion to bypass antiDebug")

    utils.ILOG("start patch svc ins to bypass antiDebug")
    # get text segment start/end address

    ret = get_text_segment(debugger)
    # remove " \n"
    ret = ret.strip()
    ret = ret[1:-1]

    textAddrs = ret.split(',')

    if len(textAddrs) < 2:
        utils.ELOG("failed to get text segment:" + str(textAddrs))
        return

    textStart = ret.split(',')[0]
    textEnd = ret.split(',')[1]
    textStart = textStart.strip()
    textEnd = textEnd.strip()

    utils.SLOG("get text segment start address:{} and end address:{}".format(
        textStart, textEnd))

    # lookup svc ins go through all text code
    ret = lookup_svc_insn(debugger, textStart, textEnd)

    if "<object returned empty description>" in ret:
        utils.ILOG("not found svc ins, so don't need patch")
        return

    svcAddrs = ret.strip()
    svcAddrs = svcAddrs.split()

    if len(svcAddrs) < 1:
        utils.ELOG("not found svc ins, so don't need patch")
        return

    for svcAddr in svcAddrs:
        utils.SLOG("found svc address:{}".format(svcAddr))
        utils.ILOG("start hook svc at address:{}".format(svcAddr))
        ret = xia0Hook(debugger, svcAddr)
        if ret:
            utils.SLOG("success hook svc at address:{}".format(svcAddr))

    utils.ILOG("all patch done")

    return
Пример #3
0
def get_instance_method_address(class_name, method_name):
    frame = get_selected_frame()
    class_addr = frame.EvaluateExpression("(Class)NSClassFromString(@\"%s\")" % class_name).GetValueAsUnsigned()
    utils.SLOG('found class address:0x%x' % class_addr)
    if class_addr == 0:
        return 0

    sel_addr = frame.EvaluateExpression("(SEL)NSSelectorFromString(@\"%s\")" % method_name).GetValueAsUnsigned()
    utils.SLOG('found selector address:0x%x' % sel_addr)
    has_method = frame.EvaluateExpression("(BOOL)class_respondsToSelector(%d, %d)" % (class_addr, sel_addr)).GetValueAsUnsigned()
    if not has_method:
        return 0

    method_addr = frame.EvaluateExpression('(void *)class_getMethodImplementation(%d, %d)' % (class_addr, sel_addr))
    
    return method_addr.GetValueAsUnsigned()
Пример #4
0
def croc(debugger, command, exe_ctx, result, internal_dict):
    command_args = shlex.split(command, posix=False)

    _ = exe_ctx.target
    _ = exe_ctx.thread

    utils.ILOG("going to env that can run oc script")
    utils.exe_cmd(debugger, "b CFBundleGetMainBundle")
    utils.exe_cmd(debugger, "c")
    utils.exe_cmd(debugger, "br del -f")
    utils.SLOG("now you can exe oc")
    # result.AppendMessage(str('usage: croc [-m moduleName, -a address, -u UserDefaults]'))
    return
Пример #5
0
def dumpdecrypted(debugger, modulePath=None, moduleIdx=None):
    # must delete all breakpoints.
    utils.ILOG("delete all breakpoints")
    utils.exe_cmd(debugger, "br de -f")
    main_image = utils.get_app_exe_path()
    images = utils.get_all_image_of_app()
    utils.ILOG("start to dump...\n")
    if modulePath and moduleIdx:
        print(dump_macho_to_file(debugger, moduleIdx, modulePath))
    else:
        for image in images:
            if main_image == image["name"]:
                entryAddrStr = get_macho_entry_offset(debugger)
                entryAddr_int = int(entryAddrStr.strip()[1:-1], 16)
                utils.SLOG("fix main addr:" + hex(entryAddr_int))
                print(
                    dump_macho_to_file(debugger, image["idx"], image["name"],
                                       entryAddr_int))
                continue
            print(dump_macho_to_file(debugger, image["idx"], image["name"]))
    return '[*] Developed By xia0@2019'
Пример #6
0
def patcher(debugger, ins, addr, size):
    if is_raw_data(ins):
        utils.ILOG("detect you manual set ins data:{}".format(ins))
        utils.ILOG(
            "start patch text at address:{} size:{} to ins data:{}".format(
                hex(addr), size, ins))
        patch_code(debugger, hex(addr), ins, size)
        return "[x] power by xia0@2019"

    supportInsList = {
        'nop': '0x1f, 0x20, 0x03, 0xd5 ',
        'ret': '0xc0, 0x03, 0x5f, 0xd6',
        'mov0': '0x00, 0x00, 0x80, 0xd2',
        'mov1': '0x20, 0x00, 0x80, 0xd2'
    }
    if ins not in supportInsList.keys():
        utils.ELOG("patcher not support this ins type:{}".format(ins))
        return "[x] power by xia0@2019"

    utils.ILOG(
        "start patch text at address:{} size:{} to ins:\"{}\" and data:{}".
        format(hex(addr), size, ins, supportInsList[ins]))

    # for i in range(size):
    #     patch_code(debugger, hex(curPatchAddr), supportInsList[ins])
    #     utils.SLOG("current patch address:{} patch done".format(hex(curPatchAddr)))
    #     curPatchAddr += 4
    ins_data = ""
    for i in range(size):
        ins_data += supportInsList[ins]
        if i != size - 1:
            ins_data += ","

    build_ins_data = "{" + ins_data + "}"

    utils.ILOG("make ins data:\n{}".format(build_ins_data))

    patch_code(debugger, hex(addr), build_ins_data, size)
    utils.SLOG("patch done")
    return "[x] power by xia0@2019"
Пример #7
0
def dumpdecrypted(debugger, modulePath=None, moduleIdx=None):
    # must delete all breakpoints.
    utils.ILOG("delete all breakpoints")
    utils.exe_cmd(debugger, "br de -f")
    #dump_macho_to_file(debugger,)
    if modulePath and moduleIdx:
        print(dump_macho_to_file(debugger, moduleIdx, modulePath))
    else:
        mainImagePath = get_main_image_path(debugger)
        appDir = os.path.dirname(mainImagePath)

        appImagesStr = get_all_image_of_app(debugger, appDir)

        appImagesArr = appImagesStr.split("#")
        for imageInfo in appImagesArr:
            if not imageInfo or not "," in imageInfo:
                utils.ELOG("image info is null, skip image # " + imageInfo)
                continue

            utils.ILOG("now is image: " + imageInfo)
            info = imageInfo.split(",")

            if len(info) == 2:
                utils.ILOG("start dump [" + info[0] + "] image:" + info[1])
                # print "idx:" + info[0]
                # print "path:" + info[1]
                if info[1] == mainImagePath:
                    entryAddrStr = get_macho_entry_offset(debugger)
                    entryAddr_int = int(entryAddrStr.strip()[1:-1], 16)
                    utils.SLOG("fix main addr:" + hex(entryAddr_int))
                    print(
                        dump_macho_to_file(debugger, info[0], info[1],
                                           entryAddr_int))
                    continue
                print(dump_macho_to_file(debugger, info[0], info[1]))
    return '\n\n[*] Developed By xia0@2019'
Пример #8
0
def xbr(debugger, command, result, dict):
    raw_args = create_command_arguments(command)

    command_args = shlex.split(command, posix=False)
    parser = generate_option_parser()
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        result.SetError(parser.usage)
        return

    # check is options?
    if options.address:
        targetAddr = options.address

        if targetAddr.startswith("0x"):
            targetAddr_int = int(targetAddr, 16)
        else:
            targetAddr_int = int(targetAddr, 10)
          
        utils.ILOG("breakpoint at address:{}".format(hex(targetAddr_int)))
        lldb.debugger.HandleCommand ('breakpoint set --address %d' % targetAddr_int)
        return

    if options.entryAddress:
        if options.entryAddress == "main":
            entryAddrStr = get_macho_entry_offset(debugger)
            entryAddr_int = int(entryAddrStr.strip()[1:-1], 16)
            utils.ILOG("breakpoint at main function:{}".format(hex(entryAddr_int)))
            lldb.debugger.HandleCommand ('breakpoint set --address %d' % entryAddr_int)
        elif options.entryAddress == "init":
            initFunAddrStr = get_macho_mod_init_first_func(debugger)
            initFunAddr_int = int(initFunAddrStr.strip()[1:-1], 16)
            utils.ILOG("breakpoint at mod int first function:{}".format(hex(initFunAddr_int)))
            lldb.debugger.HandleCommand ('breakpoint set --address %d' % initFunAddr_int)
        elif options.entryAddress == "load":
            
            ret = get_all_class_plus_load_methods(debugger)
            if "<object returned empty description>" in ret:
                utils.ILOG("not found +[* load] method")
                return
            all_load_addrs_str_arr = ret.strip().split(",")
            all_load_addrs = []
            for addr in all_load_addrs_str_arr:
                if addr != "":
                    all_load_addrs.append(int(addr, 10))
            utils.ILOG("will set breakpoint at all +[* load] methold, count:{}".format(len(all_load_addrs)))
            for addr in all_load_addrs:
                lldb.debugger.HandleCommand ('breakpoint set --address %d' % addr)
                utils.SLOG("set br at:{}".format(hex(addr)))
            # utils.ILOG("load:\n{}\n".format([hex(addr) for addr in all_load_addrs]))
        else:
            utils.ELOG("you should special the -E options:[main/init/load]")

        return
        

    # check is arg is address ? mean auto add slide
    if is_just_address_cmd(args):

        if options.modulePath:
            modulePath = options.modulePath
            utils.ILOG("you special the module:" + modulePath)
        else:
            utils.ILOG("you not special the module, default is main module")
            modulePath = None

        targetAddr = args[0]

        if targetAddr.startswith("0x"):
            targetAddr_int = int(targetAddr, 16)
        else:
            targetAddr_int = int(targetAddr, 10)

        moduleSlide = get_process_module_slide(debugger, modulePath)
        if "error" in moduleSlide:
            utils.ELOG("error in oc script # " + moduleSlide.strip())
            if modulePath:
                targetImagePath = modulePath
            else:               
                mainImagePath = get_main_image_path(debugger)
                if "no value available" in  mainImagePath or "error" in mainImagePath:
                    ret = utils.exe_cmd(debugger, "target list")
                    # pylint: disable=anomalous-backslash-in-string
                    pattern = '/.*\('
                    match = re.search(pattern, ret) # TODO: more strict
                    if match:
                        found = match.group(0)
                        found = found.split("(")[0]
                        found = found.strip()
                    else:
                        utils.ELOG("failed to auto get main module, use -m option")
                        return
 
                    mainImagePath = found
                    print("[+] use \"target list\" to get main module:" + mainImagePath)
                else:
                    mainImagePath = mainImagePath.strip()[1:-1]

                targetImagePath = mainImagePath

            ret = utils.exe_cmd(debugger, "image list -o -f")
            pattern = '0x.*?' + targetImagePath.replace("\"", "")
            match = re.search(pattern, ret) # TODO: more strict
            if match:
                found = match.group(0)
            else:
                utils.ELOG("not found image:"+targetImagePath)
                return
            moduleSlide = found.split()[0]
            utils.ILOG("use \"image list -o -f\" cmd to get image slide:"+moduleSlide)
            moduleSlide = int(moduleSlide, 16)

        else:
            moduleSlide = int(moduleSlide, 10)
            
        brAddr = moduleSlide + targetAddr_int

        utils.ILOG("ida's address:{} module slide:{} target breakpoint address:{}".format(hex(targetAddr_int), hex(moduleSlide), hex(brAddr)))
        
        lldb.debugger.HandleCommand ('breakpoint set --address %d' % brAddr)
        return

    # check is breakpoint at all methods address(IMP) for given classname
    if is_br_all_cmd_x(args):
        classname = args[0]
        begin = classname.find('$')
        end = classname.rfind('$')
        classname = classname[begin+1 : end]
        utils.ILOG("classname:{}".format(classname))

        ret = get_all_method_address_of_class(debugger, classname)

        addrArr = ret.split('-')[:-1]

        for addr in addrArr:
            address = int(addr)
            if address:
                lldb.debugger.HandleCommand ('breakpoint set --address %x' % address)
        
        result.AppendMessage("Set %ld breakpoints of %s" % (len(addrArr),classname))
        return

    if is_br_all_cmd(args):
        classname = args[0]
        ret = get_all_method_address_of_class(debugger, classname)

        addrArr = ret.split('-')[:-1]

        for addr in addrArr:
            address = int(addr)
            if address:
                lldb.debugger.HandleCommand ('breakpoint set --address %x' % address)
        
        result.AppendMessage("Set %ld breakpoints of %s" % (len(addrArr),classname))
        return
    


    if not is_command_valid(raw_args):
        print('please specify the param, for example: "-[UIView initWithFrame:]"')
        return

    arg_ = raw_args[0]
    class_name = get_class_name(arg_)
    method_name = get_method_name(arg_)
#    xlog = 'className:'+ str(class_name) + '\tmethodName:' + str(method_name)
    utils.ILOG("className:{} methodName:{}".format(class_name, method_name))
    # print class_name, method_name
    address = 0
    if is_class_method(arg_):
        address = get_class_method_address(class_name, method_name)
    else:
        address = get_instance_method_address(class_name, method_name)

    utils.SLOG('found method address:0x%x' % address)
    if address:
        lldb.debugger.HandleCommand ('breakpoint set --address %x' % address)
    else:
        utils.ELOG("fail, please check the arguments")