def extract_apk(apkPath, outputDir="output", sign=None, key=None):
    luacFiles = []
    soFiles = []
    soluaFiles = ['libcocos2dcpp.so', 'libcocos2dlua.so', 'libhellolua.so']
    if os.path.exists(apkPath):
        fileName = os.path.splitext(os.path.basename(apkPath))[0]
        outputDir = os.path.join(outputDir, fileName)
        if not os.path.exists(outputDir):
            os.makedirs(outputDir)
        zipFile = zipfile.ZipFile(apkPath)
        for names in zipFile.namelist():
            zipFile.extract(names, outputDir)
            if os.path.splitext(names)[-1] == '.luac':
                if sign and key:
                    xxtea.decrypt_file(src_file=os.path.join(outputDir, names),
                                       key=key,
                                       target_file=os.path.join(
                                           outputDir, names),
                                       sign=sign)
                luacFiles.append(os.path.join(outputDir, names))
            for i in soluaFiles:
                if i in names:
                    soFiles.append(os.path.join(outputDir, names))
        zipFile.close()
    else:
        exit(u'apk file not found')
    return luacFiles, soFiles
def decrypt_dir(dir, sign, key):
    for root, dirs, files in os.walk(dir):
        for f in files:
            if os.path.splitext(f)[-1] == ".luac":
                xxtea.decrypt_file(src_file=os.path.join(root, f),
                                   key=key,
                                   target_file=os.path.join(root, f),
                                   sign=sign)
def main():
    parser = argparse.ArgumentParser(
        add_help=True,
        description="cocos2d luac decrypt & encrypt tool",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
example:
    {prog} -f 1.apk -o output                       # Y auto parse apk
    {prog} -f 1.apk -s aaaaaaa -k bbbbbbb           # Y
    {prog} -f 1.apk -o output -s aaaaaaa -k bbbbbbb # Y
    {prog} -d dir -s aaaaaaa -k bbbbbbb             # Y
    {prog} -d dir -s aaaaaaa -k bbbbbbb -e         # encrypt lua""".format(
            prog=sys.argv[0]))
    parser.add_argument('-f', dest="apkFile", help='apk file')
    parser.add_argument('-o',
                        dest="output",
                        default="output",
                        help="output dir")
    parser.add_argument('-d', dest="dir", help="luac dir")
    parser.add_argument('-s', dest="sign", default="", help="xxtea sign")
    parser.add_argument('-k', dest="key", default="", help="xxtea key")
    parser.add_argument('-e',
                        dest="encrypt",
                        action="store_true",
                        help="encrypt")
    args = parser.parse_args()
    import pprint

    if args.sign and args.key and args.apkFile:
        extract_apk(args.apkFile, args.output, sign=args.sign, key=args.key)
    elif args.sign and args.key and args.dir and args.encrypt:
        pprint.pprint(encrypt_dir(args.dir, args.sign, args.key))
    elif args.sign and args.key and args.dir:
        pprint.pprint(decrypt_dir(args.dir, args.sign, args.key))
    elif args.apkFile and (args.sign == ''):
        sign = ''
        key = ''
        luacFiles, soFiles = extract_apk(args.apkFile, args.output)
        if luacFiles.__len__() > 1:
            sign = guess_sign(luacFiles)
        else:
            exit('not found Luac file')
        if soFiles.__len__() > 0:
            for soFile in soFiles:
                # 一般情况是存在于 strings soFile|grep -i key -A 3 -B 3
                key = get_key_list(sign, soFile)
                for k in key:
                    if xxtea.decrypt_file(luacFiles[0], k, luacFiles[0], sign):
                        for luac in luacFiles[1:]:
                            xxtea.decrypt_file(luac, k, luac, sign)
                            # print '[-] decrypt success : {}'.format(luac)
                        print "[*] sign:{} ,key:{}".format(sign, k)
                        break
                    else:
                        print '[*] not found KEY,sorry'
        else:
            exit('not found so file')
Пример #4
0
def start_decrypt(so_file, src_path):
    sign = get_sign(src_path)
    if sign == "":
        print "error: src_path contains plain text files."
        return
    key_list = get_key_list(sign, so_file)
    if len(key_list) == 0:
        print "error: no valid key, check it manual."
        return
    global OUTPUT_PATH
    for key in key_list:
        print "try use key %s to decrypt" % (key)
        if os.path.exists(OUTPUT_PATH):
            shutil.rmtree(OUTPUT_PATH)
        os.mkdir(OUTPUT_PATH)

        is_right_key = False
        for parent, folders, files in os.walk(src_path):
            target_folder = parent.replace(src_path, OUTPUT_PATH)
            if not os.path.exists(target_folder):
                os.mkdir(target_folder)

            for file in files:
                full_path = os.path.join(parent, file)
                target_path = full_path.replace(src_path, OUTPUT_PATH)
                target_path = target_path.replace("luac", "lua")
                is_right_key = decrypt_file(full_path, key, target_path, sign)
                if not is_right_key:
                    print "invalid key %s on file %s" % (key, full_path)
                    break
            if not is_right_key:
                break
        if is_right_key:
            print "success"
            break