def makePatchDexData(baseApk,modifyApk): try: cmd ='java -jar %s -f %s -t %s -o %s -k %s -p testres -a testres -e testres '%(apkpatch_jar,baseApk,modifyApk,constrant.PATCH_APK_DEX,constrant.KEY_STORE_PATH) os.system(cmd) except Exception as e: log.log_print("makePatchDexData exception",log.ERROR) log.log_print(e,log.ERROR)
def rebuildApk(smalipath,outpath): try: cmd ="java -jar %s b %s -o %s"%(apktool_jar,smalipath,outpath) os.system(cmd) except Exception as e: log.log_print("when rebuild apk was occured error",log.ERROR) log.log_print(e,log.ERROR)
def decodeApk(apk,smaliPath): try: cmd = 'java -jar %s d %s -o %s'%(apktool_jar,apk,smaliPath) # log.log_print("disassemble cmd:%s"%cmd) os.system(cmd) except Exception as e: log.log_print("when disassemble apk was occured error",log.ERROR) log.log_print(e,log.ERROR)
def copyApk(self): log.log_print("copy Apk") if self.Apk: self.copyBaseApk = fileutils.copyFile( self.Apk, constrant.TMP_ROOT_DIR + os.sep + constrant.TMP_COPY_APK) else: self.copyBaseApk = fileutils.copyFile( self.filelist[0], constrant.TMP_ROOT_DIR + os.sep + constrant.TMP_COPY_APK)
def copyFile(srcfile, dstfile): if not os.path.isfile(srcfile): log.log_print("%s is not file" % srcfile, log.ERROR) return createDirs(constrant.TMP_ROOT_DIR) #预先创建 copyFile = dstfile deleteFile(copyFile) shutil.copyfile(srcfile, copyFile) log.log_print("copy %s is ok" % copyFile, log.DEBUG) return copyFile
def copyDirs(src, dst): log.log_print(os.path.isdir(src)) log.log_print(os.path.isdir(dst)) if not checkDirs(src): log.log_print("copy dirs error,%s not directory" % (src), log.ERROR) sys.exit(1) try: shutil.copytree(src=src, dst=dst, symlinks=True) #注意,dst目录要不在,如果已经存在,则需要删除才能复制 except Exception as e: log.log_print("copy dirs occurred exception", log.ERROR) log.log_print(e, log.ERROR) sys.exit(1)
def release(self): try: time_stamp = self.get_time_hash( time.strftime('%Y%m%d%H%M%S', time.localtime())) fileutils.copyDirs(constrant.SRC_ANDFIX_PATH, constrant.DST_ANDFIX_PATH) #复制添加的文件目录 mlist = fileutils.scanFile(constrant.PATCH_APK_DEX, suffix=constrant.PATCH_DEX_SUFFIX) if not os.path.isdir(constrant.APP_ASSETS_DIR): os.makedirs(constrant.APP_ASSETS_DIR) out_patch_file = constrant.APP_ASSETS_DIR + os.sep + 'out.apatch' shutil.copyfile(mlist[0], out_patch_file) for file in fileutils.scanFile(self.disaCodePath, suffix=constrant.SMALI_SUFFIX): modifyer.add_fix_function_code(file) log.log_print('build release apk ... ') builder.rebuildApk( constrant.SMALI_OUT_PATH, constrant.RELEASE_APK_NAME + time_stamp + '.apk') log.log_print('release apk path:%s' % (constrant.RELEASE_APK_NAME + time_stamp + '.apk')) except Exception as e: log.log_print("when build release apk was occured an error ", log.ERROR) log.log_print(e, log.ERROR)
def add_fix_function_code(file): tmp = os.path.split(file) filename = tmp[1] if __isRFile(filename): return try: fd = open(file, 'r') lines = fd.readlines() out_fd = open(file, "w+") tmpDict = found(static_method_reg_str, lines) if tmpDict.get('isinterface') == True: # 接口类 out_fd.writelines(lines) return tmpIndex = tmpDict.get('method_index') clazz = tmpDict.get('clazz') objlines = ' const-class v0, ' + clazz + '\n' invoke = ' invoke-static {v0}, Lcom/alipay/euler/andfix/AndFixManager;->fixfunc(Ljava/lang/Class;)V\n' if tmpIndex == 0: log.log_print('tmpindex== 0') # 说明,没有找到<clinit>方法 mDict = found(constrant.METHOD_START, lines) #需要添加完整的方法体 tmpIndex = mDict.get('method_index') tmpfd = open(constrant.ADD_FIX_FUNCTION_CODE_PATH, 'r') tmplines = tmpfd.readlines() tmplines.insert(3, objlines) log.log_print(tmplines) tmpfd.close() for item in tmplines: lines.insert(tmpIndex, item) tmpIndex += 1 lines.insert(tmpIndex, '\n') #多添加一个换行符 out_fd.writelines(lines) elif tmpIndex > 0: # 说明,找到了<clinit>方法 #只需要添加部分代码 log.log_print('tmpIndex > 0') tmpIndex += 5 lines.insert(tmpIndex, objlines) tmpIndex += 1 lines.insert(tmpIndex, invoke) out_fd.writelines(lines) out_fd.close() fd.close() except IOError as e: log.log_print('when add fix function code was occured an error', log.ERROR) log.log_print(e, log.ERROR)
def modifySmaliFileMethod(file, isAddFixFuntion=False): try: #读取内容,同时写文件 tmp = os.path.split(file) filename = tmp[1] if __isRFile(filename): return log.log_print("file:%s" % file) fd = open(file, 'r') lines = fd.readlines() tmpFile = tmp[0] + os.sep + "_tmp_" + tmp[1] outfd = open(tmpFile, 'w') isInterFaceClass = False isAddMethod = True for line in lines: if is_match_reg(interface_class_reg_str, line): isInterFaceClass = True break # if is_match_reg(current_java_class_name,line): # java_class_filename = line.split(' ')[1].replace('"','') # log.log_print('current java class name :%s'%(java_class_filename)) matchobj = re.match(constrant.METHOD_START, line.strip()) if matchobj: if is_match_reg(static_method_reg_str, line): #这里添加 fixfunc的函数体 log.log_print('isStaticMethod') isAddMethod = True elif is_match_reg( abstract_method_reg_str, line) or is_match_reg( native_method_reg_str, line) or is_match_reg( constructor_reg_str, line): isAddMethod = True else: isAddMethod = False tmpMethod = line.split(" ") tmpMethod.insert(2, 'native') line = ' '.join(tmpMethod) outfd.writelines(line) if re.match(constrant.METHOD_END, line.strip()): outfd.writelines(line) outfd.writelines('\n') isAddMethod = False if isAddMethod: outfd.writelines(line) # if isInterFaceClass: outfd.writelines(lines) outfd.close() fd.close() os.remove(file) os.rename(tmpFile, os.path.split(tmpFile)[0] + os.sep + filename) except (IOError, OSError) as e: log.log_print("when createMethodStruct was occured exception ", log.ERROR) log.log_print(e, log.ERROR)
def getApkPackageName(): log.log_print("getPackageNaem") manifestfile =constrant.SMALI_OUT_PATH+os.sep+"AndroidManifest.xml" #manifestfile ="D:\\Android\\worRecord\\Androidprotected\\extractDexFile\\smali\\AndroidManifest.xml" if not fileutils.checkFile(manifestfile): log.log_print("AndroidMainfest.xml is not file",log.ERROR) sys.exit(1) pacakgeName="" try: xmlTree = ET.ElementTree(file=manifestfile) if xmlTree == None: log.log_print("parse AndroidManifest.xml failed", log.ERROR) sys.exit(1) for items in xmlTree.iter(): if items.tag == "manifest": pacakgeName = items.attrib.get('package') except Exception as e: log.log_print("Exception parse AndroidManifest.xml failed",log.ERROR) log.log_print(e,log.ERROR) return pacakgeName
def makePatchDex(self): log.log_print("makePatchDex .. ") packageName = mainfest.getApkPackageName() log.log_print("packageName:%s" % packageName) self.disaCodePath = constrant.SMALI_OUT_PATH + os.sep + 'smali' + os.sep + packageName.replace( '.', os.sep) mlist = fileutils.scanFile(self.disaCodePath, suffix=constrant.SMALI_SUFFIX) log.log_print("modifySmaliFileMetho begin") print "mlist", mlist for item in mlist: modifyer.modifySmaliFileMethod(item) log.log_print("modifySmaliFileMetho end") self.buildApk()
def doPatch(self): builder.makePatchDexData( self.copyBaseApk, constrant.TMP_APK_PATH + os.sep + constrant.BASE_METHOD_MODIFY_APK) log.log_print('dopatch ok ')
def buildApk(self): log.log_print("build apk") builder.rebuildApk( constrant.SMALI_OUT_PATH, constrant.TMP_APK_PATH + os.sep + constrant.BASE_METHOD_MODIFY_APK)
def decodeApk(self): log.log_print("disassemble Apk") builder.decodeApk(self.copyBaseApk, constrant.SMALI_OUT_PATH)
def renameFile(src, dst): try: os.rename(src, dst) except Exception as e: log.log_print("when rename file was occured error", log.ERROR) log.log_print(e, log.ERROR)